blob: d506c83d204a6283e90bfbb5119f393b01d92389 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Driver for the PLX NET2280 USB device controller.
3 * Specs and errata are available from <http://www.plxtech.com>.
4 *
David Brownell901b3d72006-09-02 03:13:45 -07005 * PLX Technology Inc. (formerly NetChip Technology) supported the
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * development of this driver.
7 *
8 *
9 * CODE STATUS HIGHLIGHTS
10 *
11 * This driver should work well with most "gadget" drivers, including
Michal Nazarewiczfa069202012-11-06 22:52:36 +010012 * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * as well as Gadget Zero and Gadgetfs.
14 *
15 * DMA is enabled by default. Drivers using transfer queues might use
16 * DMA chaining to remove IRQ latencies between transfers. (Except when
17 * short OUT transfers happen.) Drivers can use the req->no_interrupt
18 * hint to completely eliminate some IRQs, if a later IRQ is guaranteed
19 * and DMA chaining is enabled.
20 *
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020021 * MSI is enabled by default. The legacy IRQ is used if MSI couldn't
22 * be enabled.
23 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070024 * Note that almost all the errata workarounds here are only needed for
25 * rev1 chips. Rev1a silicon (0110) fixes almost all of them.
26 */
27
28/*
29 * Copyright (C) 2003 David Brownell
30 * Copyright (C) 2003-2005 PLX Technology, Inc.
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020031 * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 *
David Brownell901b3d72006-09-02 03:13:45 -070033 * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility
34 * with 2282 chip
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +010035 *
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020036 * Modified Ricardo Ribalda Qtechnology AS to provide compatibility
37 * with usb 338x chip. Based on PLX driver
38 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 * This program is free software; you can redistribute it and/or modify
40 * it under the terms of the GNU General Public License as published by
41 * the Free Software Foundation; either version 2 of the License, or
42 * (at your option) any later version.
Linus Torvalds1da177e2005-04-16 15:20:36 -070043 */
44
45#undef DEBUG /* messages on error and most fault paths */
46#undef VERBOSE /* extra debug messages (success too) */
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <linux/module.h>
49#include <linux/pci.h>
David Brownell682d4c82006-01-18 23:55:08 -080050#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070051#include <linux/kernel.h>
52#include <linux/delay.h>
53#include <linux/ioport.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070054#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070055#include <linux/errno.h>
56#include <linux/init.h>
57#include <linux/timer.h>
58#include <linux/list.h>
59#include <linux/interrupt.h>
60#include <linux/moduleparam.h>
61#include <linux/device.h>
David Brownell5f848132006-12-16 15:34:53 -080062#include <linux/usb/ch9.h>
David Brownell9454a572007-10-04 18:05:17 -070063#include <linux/usb/gadget.h>
Bryan Wub38b03b2011-06-02 12:51:29 +080064#include <linux/prefetch.h>
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020065#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67#include <asm/byteorder.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070068#include <asm/irq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <asm/unaligned.h>
70
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020071#define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller"
72#define DRIVER_VERSION "2005 Sept 27/v3.0"
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
Linus Torvalds1da177e2005-04-16 15:20:36 -070074#define EP_DONTUSE 13 /* nonzero */
75
76#define USE_RDK_LEDS /* GPIO pins control three LEDs */
77
78
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020079static const char driver_name[] = "net2280";
80static const char driver_desc[] = DRIVER_DESC;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020082static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 };
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020083static const char ep0name[] = "ep0";
84static const char *const ep_name[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 ep0name,
86 "ep-a", "ep-b", "ep-c", "ep-d",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020087 "ep-e", "ep-f", "ep-g", "ep-h",
Linus Torvalds1da177e2005-04-16 15:20:36 -070088};
89
90/* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO)
91 * use_dma_chaining -- dma descriptor queueing gives even more irq reduction
92 *
93 * The net2280 DMA engines are not tightly integrated with their FIFOs;
94 * not all cases are (yet) handled well in this driver or the silicon.
95 * Some gadget drivers work better with the dma support here than others.
96 * These two parameters let you use PIO or more aggressive DMA.
97 */
Ricardo Ribalda Delgado00d4db02014-05-20 18:30:06 +020098static bool use_dma = true;
99static bool use_dma_chaining;
100static bool use_msi = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
102/* "modprobe net2280 use_dma=n" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200103module_param(use_dma, bool, 0444);
104module_param(use_dma_chaining, bool, 0444);
105module_param(use_msi, bool, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107/* mode 0 == ep-{a,b,c,d} 1K fifo each
108 * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
109 * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable
110 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200111static ushort fifo_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
113/* "modprobe net2280 fifo_mode=1" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200114module_param(fifo_mode, ushort, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116/* enable_suspend -- When enabled, the driver will respond to
117 * USB suspend requests by powering down the NET2280. Otherwise,
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300118 * USB suspend requests will be ignored. This is acceptable for
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100119 * self-powered devices
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 */
Ricardo Ribalda Delgado00d4db02014-05-20 18:30:06 +0200121static bool enable_suspend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
123/* "modprobe net2280 enable_suspend=1" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200124module_param(enable_suspend, bool, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Alan Stern2f076072013-01-30 16:40:14 -0500126/* force full-speed operation */
127static bool full_speed;
128module_param(full_speed, bool, 0444);
129MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
131#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
132
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200133static char *type_string(u8 bmAttributes)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134{
135 switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
136 case USB_ENDPOINT_XFER_BULK: return "bulk";
137 case USB_ENDPOINT_XFER_ISOC: return "iso";
138 case USB_ENDPOINT_XFER_INT: return "intr";
Joe Perches2b84f922013-10-08 16:01:37 -0700139 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 return "control";
141}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
143#include "net2280.h"
144
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200145#define valid_bit cpu_to_le32(BIT(VALID_BIT))
146#define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148/*-------------------------------------------------------------------------*/
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200149static inline void enable_pciirqenb(struct net2280_ep *ep)
150{
151 u32 tmp = readl(&ep->dev->regs->pciirqenb0);
152
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200153 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200154 tmp |= BIT(ep->num);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200155 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200156 tmp |= BIT(ep_bit[ep->num]);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200157 writel(tmp, &ep->dev->regs->pciirqenb0);
158
159 return;
160}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162static int
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200163net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164{
165 struct net2280 *dev;
166 struct net2280_ep *ep;
167 u32 max, tmp;
168 unsigned long flags;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200169 static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200171 ep = container_of(_ep, struct net2280_ep, ep);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200172 if (!_ep || !desc || ep->desc || _ep->name == ep0name ||
173 desc->bDescriptorType != USB_DT_ENDPOINT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return -EINVAL;
175 dev = ep->dev;
176 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
177 return -ESHUTDOWN;
178
179 /* erratum 0119 workaround ties up an endpoint number */
180 if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE)
181 return -EDOM;
182
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200183 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200184 if ((desc->bEndpointAddress & 0x0f) >= 0x0c)
185 return -EDOM;
186 ep->is_in = !!usb_endpoint_dir_in(desc);
187 if (dev->enhanced_mode && ep->is_in && ep_key[ep->num])
188 return -EINVAL;
189 }
190
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 /* sanity check ep-e/ep-f since their fifos are small */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200192 max = usb_endpoint_maxp(desc) & 0x1fff;
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200193 if (ep->num > 4 && max > 64 &&
194 (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 return -ERANGE;
196
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200197 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 _ep->maxpacket = max & 0x7ff;
199 ep->desc = desc;
200
201 /* ep_reset() has already been called */
202 ep->stopped = 0;
Alan Stern80661342008-08-14 15:49:11 -0400203 ep->wedged = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 ep->out_overflow = 0;
205
206 /* set speed-dependent max packet; may kick in high bandwidth */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200207 set_max_speed(ep, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
209 /* FIFO lines can't go to different packets. PIO is ok, so
210 * use it instead of troublesome (non-bulk) multi-packet DMA.
211 */
212 if (ep->dma && (max % 4) != 0 && use_dma_chaining) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200213 DEBUG(ep->dev, "%s, no dma for maxpacket %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 ep->ep.name, ep->ep.maxpacket);
215 ep->dma = NULL;
216 }
217
218 /* set type, direction, address; reset fifo counters */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200219 writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
221 if (tmp == USB_ENDPOINT_XFER_INT) {
222 /* erratum 0105 workaround prevents hs NYET */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200223 if (dev->chiprev == 0100 &&
224 dev->gadget.speed == USB_SPEED_HIGH &&
225 !(desc->bEndpointAddress & USB_DIR_IN))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200226 writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 &ep->regs->ep_rsp);
228 } else if (tmp == USB_ENDPOINT_XFER_BULK) {
229 /* catch some particularly blatant driver bugs */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200230 if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) ||
231 (dev->gadget.speed == USB_SPEED_HIGH && max != 512) ||
232 (dev->gadget.speed == USB_SPEED_FULL && max > 64)) {
233 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 return -ERANGE;
235 }
236 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200237 ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200238 /* Enable this endpoint */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200239 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200240 tmp <<= ENDPOINT_TYPE;
241 tmp |= desc->bEndpointAddress;
242 /* default full fifo lines */
243 tmp |= (4 << ENDPOINT_BYTE_COUNT);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200244 tmp |= BIT(ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200245 ep->is_in = (tmp & USB_DIR_IN) != 0;
246 } else {
247 /* In Legacy mode, only OUT endpoints are used */
248 if (dev->enhanced_mode && ep->is_in) {
249 tmp <<= IN_ENDPOINT_TYPE;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200250 tmp |= BIT(IN_ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200251 /* Not applicable to Legacy */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200252 tmp |= BIT(ENDPOINT_DIRECTION);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200253 } else {
254 tmp <<= OUT_ENDPOINT_TYPE;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200255 tmp |= BIT(OUT_ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200256 tmp |= (ep->is_in << ENDPOINT_DIRECTION);
257 }
258
259 tmp |= usb_endpoint_num(desc);
260 tmp |= (ep->ep.maxburst << MAX_BURST_SIZE);
261 }
262
263 /* Make sure all the registers are written before ep_rsp*/
264 wmb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265
266 /* for OUT transfers, block the rx fifo until a read is posted */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 if (!ep->is_in)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200268 writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100269 else if (dev->pdev->device != 0x2280) {
David Brownell901b3d72006-09-02 03:13:45 -0700270 /* Added for 2282, Don't use nak packets on an in endpoint,
271 * this was ignored on 2280
272 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200273 writel(BIT(CLEAR_NAK_OUT_PACKETS) |
274 BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100275 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200277 writel(tmp, &ep->cfg->ep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
279 /* enable irqs */
280 if (!ep->dma) { /* pio, per-packet */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200281 enable_pciirqenb(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200283 tmp = BIT(DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) |
284 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100285 if (dev->pdev->device == 0x2280)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200286 tmp |= readl(&ep->regs->ep_irqenb);
287 writel(tmp, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 } else { /* dma, per-request */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200289 tmp = BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200290 tmp |= readl(&dev->regs->pciirqenb1);
291 writel(tmp, &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
293 /* for short OUT transfers, dma completions can't
294 * advance the queue; do it pio-style, by hand.
295 * NOTE erratum 0112 workaround #2
296 */
297 if ((desc->bEndpointAddress & USB_DIR_IN) == 0) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200298 tmp = BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200299 writel(tmp, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200301 enable_pciirqenb(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
303 }
304
305 tmp = desc->bEndpointAddress;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200306 DEBUG(dev, "enabled %s (ep%d%s-%s) %s max %04x\n",
307 _ep->name, tmp & 0x0f, DIR_STRING(tmp),
308 type_string(desc->bmAttributes),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 ep->dma ? "dma" : "pio", max);
310
311 /* pci writes may still be posted */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200312 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 return 0;
314}
315
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200316static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317{
318 u32 result;
319
320 do {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200321 result = readl(ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 if (result == ~(u32)0) /* "device unplugged" */
323 return -ENODEV;
324 result &= mask;
325 if (result == done)
326 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200327 udelay(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 usec--;
329 } while (usec > 0);
330 return -ETIMEDOUT;
331}
332
David Brownell901b3d72006-09-02 03:13:45 -0700333static const struct usb_ep_ops net2280_ep_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200335static void ep_reset_228x(struct net2280_regs __iomem *regs,
336 struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337{
338 u32 tmp;
339
340 ep->desc = NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200341 INIT_LIST_HEAD(&ep->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
Robert Baldygae117e742013-12-13 12:23:38 +0100343 usb_ep_set_maxpacket_limit(&ep->ep, ~0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 ep->ep.ops = &net2280_ep_ops;
345
346 /* disable the dma, irqs, endpoint... */
347 if (ep->dma) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200348 writel(0, &ep->dma->dmactl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200349 writel(BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
350 BIT(DMA_TRANSACTION_DONE_INTERRUPT) |
351 BIT(DMA_ABORT),
352 &ep->dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200354 tmp = readl(&regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200355 tmp &= ~BIT(ep->num);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200356 writel(tmp, &regs->pciirqenb0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200358 tmp = readl(&regs->pciirqenb1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200359 tmp &= ~BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200360 writel(tmp, &regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200362 writel(0, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
364 /* init to our chosen defaults, notably so that we NAK OUT
365 * packets until the driver queues a read (+note erratum 0112)
366 */
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100367 if (!ep->is_in || ep->dev->pdev->device == 0x2280) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200368 tmp = BIT(SET_NAK_OUT_PACKETS_MODE) |
369 BIT(SET_NAK_OUT_PACKETS) |
370 BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
371 BIT(CLEAR_INTERRUPT_MODE);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100372 } else {
373 /* added for 2282 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200374 tmp = BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
375 BIT(CLEAR_NAK_OUT_PACKETS) |
376 BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
377 BIT(CLEAR_INTERRUPT_MODE);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100378 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
380 if (ep->num != 0) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200381 tmp |= BIT(CLEAR_ENDPOINT_TOGGLE) |
382 BIT(CLEAR_ENDPOINT_HALT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200384 writel(tmp, &ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
386 /* scrub most status bits, and flush any fifo state */
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100387 if (ep->dev->pdev->device == 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200388 tmp = BIT(FIFO_OVERFLOW) |
389 BIT(FIFO_UNDERFLOW);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100390 else
391 tmp = 0;
392
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200393 writel(tmp | BIT(TIMEOUT) |
394 BIT(USB_STALL_SENT) |
395 BIT(USB_IN_NAK_SENT) |
396 BIT(USB_IN_ACK_RCVD) |
397 BIT(USB_OUT_PING_NAK_SENT) |
398 BIT(USB_OUT_ACK_SENT) |
399 BIT(FIFO_FLUSH) |
400 BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
401 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
402 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
403 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
404 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200405 BIT(DATA_IN_TOKEN_INTERRUPT),
406 &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
408 /* fifo size is handled separately */
409}
410
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200411static void ep_reset_338x(struct net2280_regs __iomem *regs,
412 struct net2280_ep *ep)
413{
414 u32 tmp, dmastat;
415
416 ep->desc = NULL;
417 INIT_LIST_HEAD(&ep->queue);
418
419 usb_ep_set_maxpacket_limit(&ep->ep, ~0);
420 ep->ep.ops = &net2280_ep_ops;
421
422 /* disable the dma, irqs, endpoint... */
423 if (ep->dma) {
424 writel(0, &ep->dma->dmactl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200425 writel(BIT(DMA_ABORT_DONE_INTERRUPT) |
426 BIT(DMA_PAUSE_DONE_INTERRUPT) |
427 BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200428 BIT(DMA_TRANSACTION_DONE_INTERRUPT),
429 /* | BIT(DMA_ABORT), */
430 &ep->dma->dmastat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200431
432 dmastat = readl(&ep->dma->dmastat);
433 if (dmastat == 0x5002) {
434 WARNING(ep->dev, "The dmastat return = %x!!\n",
435 dmastat);
436 writel(0x5a, &ep->dma->dmastat);
437 }
438
439 tmp = readl(&regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200440 tmp &= ~BIT(ep_bit[ep->num]);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200441 writel(tmp, &regs->pciirqenb0);
442 } else {
443 if (ep->num < 5) {
444 tmp = readl(&regs->pciirqenb1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200445 tmp &= ~BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200446 writel(tmp, &regs->pciirqenb1);
447 }
448 }
449 writel(0, &ep->regs->ep_irqenb);
450
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200451 writel(BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
452 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
453 BIT(FIFO_OVERFLOW) |
454 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
455 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
456 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
457 BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200458}
459
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200460static void nuke(struct net2280_ep *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200462static int net2280_disable(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463{
464 struct net2280_ep *ep;
465 unsigned long flags;
466
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200467 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (!_ep || !ep->desc || _ep->name == ep0name)
469 return -EINVAL;
470
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200471 spin_lock_irqsave(&ep->dev->lock, flags);
472 nuke(ep);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200473
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200474 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200475 ep_reset_338x(ep->dev->regs, ep);
476 else
477 ep_reset_228x(ep->dev->regs, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200479 VDEBUG(ep->dev, "disabled %s %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 ep->dma ? "dma" : "pio", _ep->name);
481
482 /* synch memory views with the device */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200483 (void)readl(&ep->cfg->ep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
485 if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200486 ep->dma = &ep->dev->dma[ep->num - 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200488 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 return 0;
490}
491
492/*-------------------------------------------------------------------------*/
493
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200494static struct usb_request
495*net2280_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496{
497 struct net2280_ep *ep;
498 struct net2280_request *req;
499
500 if (!_ep)
501 return NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200502 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
Eric Sesterhenn7039f422006-02-27 13:34:10 -0800504 req = kzalloc(sizeof(*req), gfp_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 if (!req)
506 return NULL;
507
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200508 INIT_LIST_HEAD(&req->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509
510 /* this dma descriptor may be swapped with the previous dummy */
511 if (ep->dma) {
512 struct net2280_dma *td;
513
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200514 td = pci_pool_alloc(ep->dev->requests, gfp_flags,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 &req->td_dma);
516 if (!td) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200517 kfree(req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 return NULL;
519 }
520 td->dmacount = 0; /* not VALID */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 td->dmadesc = td->dmaaddr;
522 req->td = td;
523 }
524 return &req->req;
525}
526
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200527static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528{
529 struct net2280_ep *ep;
530 struct net2280_request *req;
531
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200532 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 if (!_ep || !_req)
534 return;
535
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200536 req = container_of(_req, struct net2280_request, req);
537 WARN_ON(!list_empty(&req->queue));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 if (req->td)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200539 pci_pool_free(ep->dev->requests, req->td, req->td_dma);
540 kfree(req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541}
542
543/*-------------------------------------------------------------------------*/
544
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545/* load a packet into the fifo we use for usb IN transfers.
546 * works for all endpoints.
547 *
548 * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo
549 * at a time, but this code is simpler because it knows it only writes
550 * one packet. ep-a..ep-d should use dma instead.
551 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200552static void write_fifo(struct net2280_ep *ep, struct usb_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553{
554 struct net2280_ep_regs __iomem *regs = ep->regs;
555 u8 *buf;
556 u32 tmp;
557 unsigned count, total;
558
559 /* INVARIANT: fifo is currently empty. (testable) */
560
561 if (req) {
562 buf = req->buf + req->actual;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200563 prefetch(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 total = req->length - req->actual;
565 } else {
566 total = 0;
567 buf = NULL;
568 }
569
570 /* write just one packet at a time */
571 count = ep->ep.maxpacket;
572 if (count > total) /* min() cannot be used on a bitfield */
573 count = total;
574
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200575 VDEBUG(ep->dev, "write %s fifo (IN) %d bytes%s req %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 ep->ep.name, count,
577 (count != ep->ep.maxpacket) ? " (short)" : "",
578 req);
579 while (count >= 4) {
580 /* NOTE be careful if you try to align these. fifo lines
581 * should normally be full (4 bytes) and successive partial
582 * lines are ok only in certain cases.
583 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200584 tmp = get_unaligned((u32 *)buf);
585 cpu_to_le32s(&tmp);
586 writel(tmp, &regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 buf += 4;
588 count -= 4;
589 }
590
591 /* last fifo entry is "short" unless we wrote a full packet.
592 * also explicitly validate last word in (periodic) transfers
593 * when maxpacket is not a multiple of 4 bytes.
594 */
595 if (count || total < ep->ep.maxpacket) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200596 tmp = count ? get_unaligned((u32 *)buf) : count;
597 cpu_to_le32s(&tmp);
598 set_fifo_bytecount(ep, count & 0x03);
599 writel(tmp, &regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 }
601
602 /* pci writes may still be posted */
603}
604
605/* work around erratum 0106: PCI and USB race over the OUT fifo.
606 * caller guarantees chiprev 0100, out endpoint is NAKing, and
607 * there's no real data in the fifo.
608 *
609 * NOTE: also used in cases where that erratum doesn't apply:
610 * where the host wrote "too much" data to us.
611 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200612static void out_flush(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613{
614 u32 __iomem *statp;
615 u32 tmp;
616
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200617 ASSERT_OUT_NAKING(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
619 statp = &ep->regs->ep_stat;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200620 writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200621 BIT(DATA_PACKET_RECEIVED_INTERRUPT),
622 statp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200623 writel(BIT(FIFO_FLUSH), statp);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200624 /* Make sure that stap is written */
625 mb();
626 tmp = readl(statp);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200627 if (tmp & BIT(DATA_OUT_PING_TOKEN_INTERRUPT) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 /* high speed did bulk NYET; fifo isn't filling */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200629 ep->dev->gadget.speed == USB_SPEED_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 unsigned usec;
631
632 usec = 50; /* 64 byte bulk/interrupt */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200633 handshake(statp, BIT(USB_OUT_PING_NAK_SENT),
634 BIT(USB_OUT_PING_NAK_SENT), usec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */
636 }
637}
638
639/* unload packet(s) from the fifo we use for usb OUT transfers.
640 * returns true iff the request completed, because of short packet
641 * or the request buffer having filled with full packets.
642 *
643 * for ep-a..ep-d this will read multiple packets out when they
644 * have been accepted.
645 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200646static int read_fifo(struct net2280_ep *ep, struct net2280_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647{
648 struct net2280_ep_regs __iomem *regs = ep->regs;
649 u8 *buf = req->req.buf + req->req.actual;
650 unsigned count, tmp, is_short;
651 unsigned cleanup = 0, prevent = 0;
652
653 /* erratum 0106 ... packets coming in during fifo reads might
654 * be incompletely rejected. not all cases have workarounds.
655 */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200656 if (ep->dev->chiprev == 0x0100 &&
657 ep->dev->gadget.speed == USB_SPEED_FULL) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200658 udelay(1);
659 tmp = readl(&ep->regs->ep_stat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200660 if ((tmp & BIT(NAK_OUT_PACKETS)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 cleanup = 1;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200662 else if ((tmp & BIT(FIFO_FULL))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200663 start_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 prevent = 1;
665 }
666 /* else: hope we don't see the problem */
667 }
668
669 /* never overflow the rx buffer. the fifo reads packets until
670 * it sees a short one; we might not be ready for them all.
671 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200672 prefetchw(buf);
673 count = readl(&regs->ep_avail);
674 if (unlikely(count == 0)) {
675 udelay(1);
676 tmp = readl(&ep->regs->ep_stat);
677 count = readl(&regs->ep_avail);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 /* handled that data already? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200679 if (count == 0 && (tmp & BIT(NAK_OUT_PACKETS)) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 return 0;
681 }
682
683 tmp = req->req.length - req->req.actual;
684 if (count > tmp) {
685 /* as with DMA, data overflow gets flushed */
686 if ((tmp % ep->ep.maxpacket) != 0) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200687 ERROR(ep->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 "%s out fifo %d bytes, expected %d\n",
689 ep->ep.name, count, tmp);
690 req->req.status = -EOVERFLOW;
691 cleanup = 1;
692 /* NAK_OUT_PACKETS will be set, so flushing is safe;
693 * the next read will start with the next packet
694 */
695 } /* else it's a ZLP, no worries */
696 count = tmp;
697 }
698 req->req.actual += count;
699
700 is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0);
701
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200702 VDEBUG(ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 ep->ep.name, count, is_short ? " (short)" : "",
704 cleanup ? " flush" : "", prevent ? " nak" : "",
705 req, req->req.actual, req->req.length);
706
707 while (count >= 4) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200708 tmp = readl(&regs->ep_data);
709 cpu_to_le32s(&tmp);
710 put_unaligned(tmp, (u32 *)buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 buf += 4;
712 count -= 4;
713 }
714 if (count) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200715 tmp = readl(&regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 /* LE conversion is implicit here: */
717 do {
718 *buf++ = (u8) tmp;
719 tmp >>= 8;
720 } while (--count);
721 }
722 if (cleanup)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200723 out_flush(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 if (prevent) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200725 writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200726 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 }
728
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200729 return is_short || ((req->req.actual == req->req.length) &&
730 !req->req.zero);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731}
732
733/* fill out dma descriptor to match a given request */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200734static void fill_dma_desc(struct net2280_ep *ep,
735 struct net2280_request *req, int valid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700736{
737 struct net2280_dma *td = req->td;
738 u32 dmacount = req->req.length;
739
740 /* don't let DMA continue after a short OUT packet,
741 * so overruns can't affect the next transfer.
742 * in case of overruns on max-size packets, we can't
743 * stop the fifo from filling but we can flush it.
744 */
745 if (ep->is_in)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200746 dmacount |= BIT(DMA_DIRECTION);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200747 if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) ||
748 ep->dev->pdev->device != 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200749 dmacount |= BIT(END_OF_CHAIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751 req->valid = valid;
752 if (valid)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200753 dmacount |= BIT(VALID_BIT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 if (likely(!req->req.no_interrupt || !use_dma_chaining))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200755 dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756
757 /* td->dmadesc = previously set by caller */
758 td->dmaaddr = cpu_to_le32 (req->req.dma);
759
760 /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200761 wmb();
Harvey Harrisonda2bbdc2008-10-29 14:25:51 -0700762 td->dmacount = cpu_to_le32(dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763}
764
765static const u32 dmactl_default =
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200766 BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
767 BIT(DMA_CLEAR_COUNT_ENABLE) |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 /* erratum 0116 workaround part 1 (use POLLING) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200769 (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) |
770 BIT(DMA_VALID_BIT_POLLING_ENABLE) |
771 BIT(DMA_VALID_BIT_ENABLE) |
772 BIT(DMA_SCATTER_GATHER_ENABLE) |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 /* erratum 0116 workaround part 2 (no AUTOSTART) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200774 BIT(DMA_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200776static inline void spin_stop_dma(struct net2280_dma_regs __iomem *dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200778 handshake(&dma->dmactl, BIT(DMA_ENABLE), 0, 50);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779}
780
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200781static inline void stop_dma(struct net2280_dma_regs __iomem *dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200783 writel(readl(&dma->dmactl) & ~BIT(DMA_ENABLE), &dma->dmactl);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200784 spin_stop_dma(dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785}
786
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200787static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788{
789 struct net2280_dma_regs __iomem *dma = ep->dma;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200790 unsigned int tmp = BIT(VALID_BIT) | (ep->is_in << DMA_DIRECTION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100792 if (ep->dev->pdev->device != 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200793 tmp |= BIT(END_OF_CHAIN);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100794
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200795 writel(tmp, &dma->dmacount);
796 writel(readl(&dma->dmastat), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200798 writel(td_dma, &dma->dmadesc);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200799 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200800 dmactl |= BIT(DMA_REQUEST_OUTSTANDING);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200801 writel(dmactl, &dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
803 /* erratum 0116 workaround part 3: pci arbiter away from net2280 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200804 (void) readl(&ep->dev->pci->pcimstctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200806 writel(BIT(DMA_START), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807
808 if (!ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200809 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810}
811
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200812static void start_dma(struct net2280_ep *ep, struct net2280_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813{
814 u32 tmp;
815 struct net2280_dma_regs __iomem *dma = ep->dma;
816
817 /* FIXME can't use DMA for ZLPs */
818
819 /* on this path we "know" there's no dma active (yet) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200820 WARN_ON(readl(&dma->dmactl) & BIT(DMA_ENABLE));
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200821 writel(0, &ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822
823 /* previous OUT packet might have been short */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200824 if (!ep->is_in && (readl(&ep->regs->ep_stat) &
825 BIT(NAK_OUT_PACKETS))) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200826 writel(BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 &ep->regs->ep_stat);
828
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200829 tmp = readl(&ep->regs->ep_avail);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 if (tmp) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200831 writel(readl(&dma->dmastat), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
833 /* transfer all/some fifo data */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200834 writel(req->req.dma, &dma->dmaaddr);
835 tmp = min(tmp, req->req.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836
837 /* dma irq, faking scatterlist status */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200838 req->td->dmacount = cpu_to_le32(req->req.length - tmp);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200839 writel(BIT(DMA_DONE_INTERRUPT_ENABLE) | tmp,
840 &dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 req->td->dmadesc = 0;
842 req->valid = 1;
843
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200844 writel(BIT(DMA_ENABLE), &dma->dmactl);
845 writel(BIT(DMA_START), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 return;
847 }
848 }
849
850 tmp = dmactl_default;
851
852 /* force packet boundaries between dma requests, but prevent the
853 * controller from automagically writing a last "short" packet
854 * (zero length) unless the driver explicitly said to do that.
855 */
856 if (ep->is_in) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200857 if (likely((req->req.length % ep->ep.maxpacket) ||
858 req->req.zero)){
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200859 tmp |= BIT(DMA_FIFO_VALIDATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 ep->in_fifo_validate = 1;
861 } else
862 ep->in_fifo_validate = 0;
863 }
864
865 /* init req->td, pointing to the current dummy */
866 req->td->dmadesc = cpu_to_le32 (ep->td_dma);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200867 fill_dma_desc(ep, req, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868
869 if (!use_dma_chaining)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200870 req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200872 start_queue(ep, tmp, req->td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873}
874
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200875static inline void resume_dma(struct net2280_ep *ep)
876{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200877 writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200878
879 ep->dma_started = true;
880}
881
882static inline void ep_stop_dma(struct net2280_ep *ep)
883{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200884 writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200885 spin_stop_dma(ep->dma);
886
887 ep->dma_started = false;
888}
889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890static inline void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200891queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892{
893 struct net2280_dma *end;
894 dma_addr_t tmp;
895
896 /* swap new dummy for old, link; fill and maybe activate */
897 end = ep->dummy;
898 ep->dummy = req->td;
899 req->td = end;
900
901 tmp = ep->td_dma;
902 ep->td_dma = req->td_dma;
903 req->td_dma = tmp;
904
905 end->dmadesc = cpu_to_le32 (ep->td_dma);
906
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200907 fill_dma_desc(ep, req, valid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908}
909
910static void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200911done(struct net2280_ep *ep, struct net2280_request *req, int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912{
913 struct net2280 *dev;
914 unsigned stopped = ep->stopped;
915
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200916 list_del_init(&req->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917
918 if (req->req.status == -EINPROGRESS)
919 req->req.status = status;
920 else
921 status = req->req.status;
922
923 dev = ep->dev;
Felipe Balbiae4d7932011-12-19 12:09:56 +0200924 if (ep->dma)
925 usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
927 if (status && status != -ESHUTDOWN)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200928 VDEBUG(dev, "complete %s req %p stat %d len %u/%u\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 ep->ep.name, &req->req, status,
930 req->req.actual, req->req.length);
931
932 /* don't modify queue heads during completion callback */
933 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200934 spin_unlock(&dev->lock);
935 req->req.complete(&ep->ep, &req->req);
936 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 ep->stopped = stopped;
938}
939
940/*-------------------------------------------------------------------------*/
941
942static int
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200943net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944{
945 struct net2280_request *req;
946 struct net2280_ep *ep;
947 struct net2280 *dev;
948 unsigned long flags;
949
950 /* we always require a cpu-view buffer, so that we can
951 * always use pio (as fallback or whatever).
952 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200953 req = container_of(_req, struct net2280_request, req);
954 if (!_req || !_req->complete || !_req->buf ||
955 !list_empty(&req->queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 return -EINVAL;
957 if (_req->length > (~0 & DMA_BYTE_COUNT_MASK))
958 return -EDOM;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200959 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 if (!_ep || (!ep->desc && ep->num != 0))
961 return -EINVAL;
962 dev = ep->dev;
963 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
964 return -ESHUTDOWN;
965
966 /* FIXME implement PIO fallback for ZLPs with DMA */
967 if (ep->dma && _req->length == 0)
968 return -EOPNOTSUPP;
969
970 /* set up dma mapping in case the caller didn't */
Felipe Balbiae4d7932011-12-19 12:09:56 +0200971 if (ep->dma) {
972 int ret;
973
974 ret = usb_gadget_map_request(&dev->gadget, _req,
975 ep->is_in);
976 if (ret)
977 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 }
979
980#if 0
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200981 VDEBUG(dev, "%s queue req %p, len %d buf %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 _ep->name, _req, _req->length, _req->buf);
983#endif
984
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200985 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986
987 _req->status = -EINPROGRESS;
988 _req->actual = 0;
989
990 /* kickstart this i/o queue? */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200991 if (list_empty(&ep->queue) && !ep->stopped) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200992 /* DMA request while EP halted */
993 if (ep->dma &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200994 (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) &&
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +0200995 (dev->pdev->vendor == PCI_VENDOR_ID_PLX)) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200996 int valid = 1;
997 if (ep->is_in) {
998 int expect;
999 expect = likely(req->req.zero ||
1000 ((req->req.length %
1001 ep->ep.maxpacket) != 0));
1002 if (expect != ep->in_fifo_validate)
1003 valid = 0;
1004 }
1005 queue_dma(ep, req, valid);
1006 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 /* use DMA if the endpoint supports it, else pio */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001008 else if (ep->dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001009 start_dma(ep, req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 else {
1011 /* maybe there's no control data, just status ack */
1012 if (ep->num == 0 && _req->length == 0) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001013 allow_status(ep);
1014 done(ep, req, 0);
1015 VDEBUG(dev, "%s status ack\n", ep->ep.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 goto done;
1017 }
1018
1019 /* PIO ... stuff the fifo, or unblock it. */
1020 if (ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001021 write_fifo(ep, _req);
1022 else if (list_empty(&ep->queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 u32 s;
1024
1025 /* OUT FIFO might have packet(s) buffered */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001026 s = readl(&ep->regs->ep_stat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001027 if ((s & BIT(FIFO_EMPTY)) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 /* note: _req->short_not_ok is
1029 * ignored here since PIO _always_
1030 * stops queue advance here, and
1031 * _req->status doesn't change for
1032 * short reads (only _req->actual)
1033 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001034 if (read_fifo(ep, req) &&
1035 ep->num == 0) {
1036 done(ep, req, 0);
1037 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 /* don't queue it */
1039 req = NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001040 } else if (read_fifo(ep, req) &&
1041 ep->num != 0) {
1042 done(ep, req, 0);
1043 req = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 } else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001045 s = readl(&ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 }
1047
1048 /* don't NAK, let the fifo fill */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001049 if (req && (s & BIT(NAK_OUT_PACKETS)))
1050 writel(BIT(CLEAR_NAK_OUT_PACKETS),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 &ep->regs->ep_rsp);
1052 }
1053 }
1054
1055 } else if (ep->dma) {
1056 int valid = 1;
1057
1058 if (ep->is_in) {
1059 int expect;
1060
1061 /* preventing magic zlps is per-engine state, not
1062 * per-transfer; irq logic must recover hiccups.
1063 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001064 expect = likely(req->req.zero ||
1065 (req->req.length % ep->ep.maxpacket));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 if (expect != ep->in_fifo_validate)
1067 valid = 0;
1068 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001069 queue_dma(ep, req, valid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
1071 } /* else the irq handler advances the queue. */
1072
Alan Stern1f26e282006-11-16 10:16:00 -05001073 ep->responded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001075 list_add_tail(&req->queue, &ep->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076done:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001077 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079 /* pci writes may still be posted */
1080 return 0;
1081}
1082
1083static inline void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001084dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount,
1085 int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086{
1087 req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001088 done(ep, req, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089}
1090
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001091static void restart_dma(struct net2280_ep *ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001093static void scan_dma_completions(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094{
1095 /* only look at descriptors that were "naturally" retired,
1096 * so fifo and list head state won't matter
1097 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001098 while (!list_empty(&ep->queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 struct net2280_request *req;
1100 u32 tmp;
1101
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001102 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 struct net2280_request, queue);
1104 if (!req->valid)
1105 break;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001106 rmb();
1107 tmp = le32_to_cpup(&req->td->dmacount);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001108 if ((tmp & BIT(VALID_BIT)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 break;
1110
1111 /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
1112 * cases where DMA must be aborted; this code handles
1113 * all non-abort DMA completions.
1114 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001115 if (unlikely(req->td->dmadesc == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 /* paranoia */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001117 tmp = readl(&ep->dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 if (tmp & DMA_BYTE_COUNT_MASK)
1119 break;
1120 /* single transfer mode */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001121 dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 break;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02001123 } else if (!ep->is_in &&
1124 (req->req.length % ep->ep.maxpacket) != 0) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001125 tmp = readl(&ep->regs->ep_stat);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02001126 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001127 return dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
1129 /* AVOID TROUBLE HERE by not issuing short reads from
1130 * your gadget driver. That helps avoids errata 0121,
1131 * 0122, and 0124; not all cases trigger the warning.
1132 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001133 if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001134 WARNING(ep->dev, "%s lost packet sync!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 ep->ep.name);
1136 req->req.status = -EOVERFLOW;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001137 } else {
1138 tmp = readl(&ep->regs->ep_avail);
1139 if (tmp) {
1140 /* fifo gets flushed later */
1141 ep->out_overflow = 1;
1142 DEBUG(ep->dev,
1143 "%s dma, discard %d len %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 ep->ep.name, tmp,
1145 req->req.length);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001146 req->req.status = -EOVERFLOW;
1147 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 }
1149 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001150 dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 }
1152}
1153
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001154static void restart_dma(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155{
1156 struct net2280_request *req;
1157 u32 dmactl = dmactl_default;
1158
1159 if (ep->stopped)
1160 return;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001161 req = list_entry(ep->queue.next, struct net2280_request, queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162
1163 if (!use_dma_chaining) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001164 start_dma(ep, req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 return;
1166 }
1167
1168 /* the 2280 will be processing the queue unless queue hiccups after
1169 * the previous transfer:
1170 * IN: wanted automagic zlp, head doesn't (or vice versa)
1171 * DMA_FIFO_VALIDATE doesn't init from dma descriptors.
1172 * OUT: was "usb-short", we must restart.
1173 */
1174 if (ep->is_in && !req->valid) {
1175 struct net2280_request *entry, *prev = NULL;
1176 int reqmode, done = 0;
1177
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001178 DEBUG(ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td);
1179 ep->in_fifo_validate = likely(req->req.zero ||
1180 (req->req.length % ep->ep.maxpacket) != 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 if (ep->in_fifo_validate)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001182 dmactl |= BIT(DMA_FIFO_VALIDATE);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001183 list_for_each_entry(entry, &ep->queue, queue) {
David Brownell320f3452005-05-07 13:05:18 -07001184 __le32 dmacount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
1186 if (entry == req)
1187 continue;
1188 dmacount = entry->td->dmacount;
1189 if (!done) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001190 reqmode = likely(entry->req.zero ||
1191 (entry->req.length % ep->ep.maxpacket));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 if (reqmode == ep->in_fifo_validate) {
1193 entry->valid = 1;
1194 dmacount |= valid_bit;
1195 entry->td->dmacount = dmacount;
1196 prev = entry;
1197 continue;
1198 } else {
1199 /* force a hiccup */
1200 prev->td->dmacount |= dma_done_ie;
1201 done = 1;
1202 }
1203 }
1204
1205 /* walk the rest of the queue so unlinks behave */
1206 entry->valid = 0;
1207 dmacount &= ~valid_bit;
1208 entry->td->dmacount = dmacount;
1209 prev = entry;
1210 }
1211 }
1212
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001213 writel(0, &ep->dma->dmactl);
1214 start_queue(ep, dmactl, req->td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215}
1216
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001217static void abort_dma_228x(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218{
1219 /* abort the current transfer */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001220 if (likely(!list_empty(&ep->queue))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 /* FIXME work around errata 0121, 0122, 0124 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001222 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001223 spin_stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 } else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001225 stop_dma(ep->dma);
1226 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227}
1228
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001229static void abort_dma_338x(struct net2280_ep *ep)
1230{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001231 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001232 spin_stop_dma(ep->dma);
1233}
1234
1235static void abort_dma(struct net2280_ep *ep)
1236{
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02001237 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001238 return abort_dma_228x(ep);
1239 return abort_dma_338x(ep);
1240}
1241
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242/* dequeue ALL requests */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001243static void nuke(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244{
1245 struct net2280_request *req;
1246
1247 /* called with spinlock held */
1248 ep->stopped = 1;
1249 if (ep->dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001250 abort_dma(ep);
1251 while (!list_empty(&ep->queue)) {
1252 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 struct net2280_request,
1254 queue);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001255 done(ep, req, -ESHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 }
1257}
1258
1259/* dequeue JUST ONE request */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001260static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261{
1262 struct net2280_ep *ep;
1263 struct net2280_request *req;
1264 unsigned long flags;
1265 u32 dmactl;
1266 int stopped;
1267
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001268 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 if (!_ep || (!ep->desc && ep->num != 0) || !_req)
1270 return -EINVAL;
1271
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001272 spin_lock_irqsave(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 stopped = ep->stopped;
1274
1275 /* quiesce dma while we patch the queue */
1276 dmactl = 0;
1277 ep->stopped = 1;
1278 if (ep->dma) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001279 dmactl = readl(&ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 /* WARNING erratum 0127 may kick in ... */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001281 stop_dma(ep->dma);
1282 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 }
1284
1285 /* make sure it's still queued on this endpoint */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001286 list_for_each_entry(req, &ep->queue, queue) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 if (&req->req == _req)
1288 break;
1289 }
1290 if (&req->req != _req) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001291 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 return -EINVAL;
1293 }
1294
1295 /* queue head may be partially complete. */
1296 if (ep->queue.next == &req->queue) {
1297 if (ep->dma) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001298 DEBUG(ep->dev, "unlink (%s) dma\n", _ep->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 _req->status = -ECONNRESET;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001300 abort_dma(ep);
1301 if (likely(ep->queue.next == &req->queue)) {
1302 /* NOTE: misreports single-transfer mode*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 req->td->dmacount = 0; /* invalidate */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001304 dma_done(ep, req,
1305 readl(&ep->dma->dmacount),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 -ECONNRESET);
1307 }
1308 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001309 DEBUG(ep->dev, "unlink (%s) pio\n", _ep->name);
1310 done(ep, req, -ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 }
1312 req = NULL;
1313
1314 /* patch up hardware chaining data */
1315 } else if (ep->dma && use_dma_chaining) {
1316 if (req->queue.prev == ep->queue.next) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001317 writel(le32_to_cpu(req->td->dmadesc),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 &ep->dma->dmadesc);
1319 if (req->td->dmacount & dma_done_ie)
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02001320 writel(readl(&ep->dma->dmacount) |
1321 le32_to_cpu(dma_done_ie),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 &ep->dma->dmacount);
1323 } else {
1324 struct net2280_request *prev;
1325
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001326 prev = list_entry(req->queue.prev,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 struct net2280_request, queue);
1328 prev->td->dmadesc = req->td->dmadesc;
1329 if (req->td->dmacount & dma_done_ie)
1330 prev->td->dmacount |= dma_done_ie;
1331 }
1332 }
1333
1334 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001335 done(ep, req, -ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 ep->stopped = stopped;
1337
1338 if (ep->dma) {
1339 /* turn off dma on inactive queues */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001340 if (list_empty(&ep->queue))
1341 stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 else if (!ep->stopped) {
1343 /* resume current request, or start new one */
1344 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001345 writel(dmactl, &ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001347 start_dma(ep, list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 struct net2280_request, queue));
1349 }
1350 }
1351
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001352 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 return 0;
1354}
1355
1356/*-------------------------------------------------------------------------*/
1357
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001358static int net2280_fifo_status(struct usb_ep *_ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
1360static int
Alan Stern80661342008-08-14 15:49:11 -04001361net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362{
1363 struct net2280_ep *ep;
1364 unsigned long flags;
1365 int retval = 0;
1366
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001367 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 if (!_ep || (!ep->desc && ep->num != 0))
1369 return -EINVAL;
1370 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1371 return -ESHUTDOWN;
1372 if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03)
1373 == USB_ENDPOINT_XFER_ISOC)
1374 return -EINVAL;
1375
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001376 spin_lock_irqsave(&ep->dev->lock, flags);
1377 if (!list_empty(&ep->queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 retval = -EAGAIN;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001379 else if (ep->is_in && value && net2280_fifo_status(_ep) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 retval = -EAGAIN;
1381 else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001382 VDEBUG(ep->dev, "%s %s %s\n", _ep->name,
Alan Stern80661342008-08-14 15:49:11 -04001383 value ? "set" : "clear",
1384 wedged ? "wedge" : "halt");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 /* set/clear, then synch memory views with the device */
1386 if (value) {
1387 if (ep->num == 0)
1388 ep->dev->protocol_stall = 1;
1389 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001390 set_halt(ep);
Alan Stern80661342008-08-14 15:49:11 -04001391 if (wedged)
1392 ep->wedged = 1;
1393 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001394 clear_halt(ep);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02001395 if (ep->dev->pdev->vendor == PCI_VENDOR_ID_PLX &&
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001396 !list_empty(&ep->queue) && ep->td_dma)
1397 restart_dma(ep);
Alan Stern80661342008-08-14 15:49:11 -04001398 ep->wedged = 0;
1399 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001400 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001402 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
1404 return retval;
1405}
1406
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001407static int net2280_set_halt(struct usb_ep *_ep, int value)
Alan Stern80661342008-08-14 15:49:11 -04001408{
1409 return net2280_set_halt_and_wedge(_ep, value, 0);
1410}
1411
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001412static int net2280_set_wedge(struct usb_ep *_ep)
Alan Stern80661342008-08-14 15:49:11 -04001413{
1414 if (!_ep || _ep->name == ep0name)
1415 return -EINVAL;
1416 return net2280_set_halt_and_wedge(_ep, 1, 1);
1417}
1418
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001419static int net2280_fifo_status(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420{
1421 struct net2280_ep *ep;
1422 u32 avail;
1423
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001424 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 if (!_ep || (!ep->desc && ep->num != 0))
1426 return -ENODEV;
1427 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1428 return -ESHUTDOWN;
1429
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001430 avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 if (avail > ep->fifo_size)
1432 return -EOVERFLOW;
1433 if (ep->is_in)
1434 avail = ep->fifo_size - avail;
1435 return avail;
1436}
1437
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001438static void net2280_fifo_flush(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439{
1440 struct net2280_ep *ep;
1441
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001442 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 if (!_ep || (!ep->desc && ep->num != 0))
1444 return;
1445 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1446 return;
1447
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001448 writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001449 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450}
1451
David Brownell901b3d72006-09-02 03:13:45 -07001452static const struct usb_ep_ops net2280_ep_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453 .enable = net2280_enable,
1454 .disable = net2280_disable,
1455
1456 .alloc_request = net2280_alloc_request,
1457 .free_request = net2280_free_request,
1458
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 .queue = net2280_queue,
1460 .dequeue = net2280_dequeue,
1461
1462 .set_halt = net2280_set_halt,
Alan Stern80661342008-08-14 15:49:11 -04001463 .set_wedge = net2280_set_wedge,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 .fifo_status = net2280_fifo_status,
1465 .fifo_flush = net2280_fifo_flush,
1466};
1467
1468/*-------------------------------------------------------------------------*/
1469
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001470static int net2280_get_frame(struct usb_gadget *_gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471{
1472 struct net2280 *dev;
1473 unsigned long flags;
1474 u16 retval;
1475
1476 if (!_gadget)
1477 return -ENODEV;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001478 dev = container_of(_gadget, struct net2280, gadget);
1479 spin_lock_irqsave(&dev->lock, flags);
1480 retval = get_idx_reg(dev->regs, REG_FRAME) & 0x03ff;
1481 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 return retval;
1483}
1484
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001485static int net2280_wakeup(struct usb_gadget *_gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486{
1487 struct net2280 *dev;
1488 u32 tmp;
1489 unsigned long flags;
1490
1491 if (!_gadget)
1492 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001493 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001495 spin_lock_irqsave(&dev->lock, flags);
1496 tmp = readl(&dev->usb->usbctl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001497 if (tmp & BIT(DEVICE_REMOTE_WAKEUP_ENABLE))
1498 writel(BIT(GENERATE_RESUME), &dev->usb->usbstat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001499 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
1501 /* pci writes may still be posted */
1502 return 0;
1503}
1504
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001505static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506{
1507 struct net2280 *dev;
1508 u32 tmp;
1509 unsigned long flags;
1510
1511 if (!_gadget)
1512 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001513 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001515 spin_lock_irqsave(&dev->lock, flags);
1516 tmp = readl(&dev->usb->usbctl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001517 if (value) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001518 tmp |= BIT(SELF_POWERED_STATUS);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001519 dev->selfpowered = 1;
1520 } else {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001521 tmp &= ~BIT(SELF_POWERED_STATUS);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001522 dev->selfpowered = 0;
1523 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001524 writel(tmp, &dev->usb->usbctl);
1525 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
1527 return 0;
1528}
1529
1530static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
1531{
1532 struct net2280 *dev;
1533 u32 tmp;
1534 unsigned long flags;
1535
1536 if (!_gadget)
1537 return -ENODEV;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001538 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001540 spin_lock_irqsave(&dev->lock, flags);
1541 tmp = readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 dev->softconnect = (is_on != 0);
1543 if (is_on)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001544 tmp |= BIT(USB_DETECT_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001546 tmp &= ~BIT(USB_DETECT_ENABLE);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001547 writel(tmp, &dev->usb->usbctl);
1548 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 return 0;
1551}
1552
Felipe Balbi4cf5e002011-10-10 10:37:17 +03001553static int net2280_start(struct usb_gadget *_gadget,
1554 struct usb_gadget_driver *driver);
1555static int net2280_stop(struct usb_gadget *_gadget,
1556 struct usb_gadget_driver *driver);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001557
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558static const struct usb_gadget_ops net2280_ops = {
1559 .get_frame = net2280_get_frame,
1560 .wakeup = net2280_wakeup,
1561 .set_selfpowered = net2280_set_selfpowered,
1562 .pullup = net2280_pullup,
Felipe Balbi4cf5e002011-10-10 10:37:17 +03001563 .udc_start = net2280_start,
1564 .udc_stop = net2280_stop,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565};
1566
1567/*-------------------------------------------------------------------------*/
1568
1569#ifdef CONFIG_USB_GADGET_DEBUG_FILES
1570
1571/* FIXME move these into procfs, and use seq_file.
1572 * Sysfs _still_ doesn't behave for arbitrarily sized files,
1573 * and also doesn't help products using this with 2.4 kernels.
1574 */
1575
1576/* "function" sysfs attribute */
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001577static ssize_t function_show(struct device *_dev, struct device_attribute *attr,
1578 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001580 struct net2280 *dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001582 if (!dev->driver || !dev->driver->function ||
1583 strlen(dev->driver->function) > PAGE_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001585 return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001587static DEVICE_ATTR_RO(function);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001589static ssize_t registers_show(struct device *_dev,
1590 struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591{
1592 struct net2280 *dev;
1593 char *next;
1594 unsigned size, t;
1595 unsigned long flags;
1596 int i;
1597 u32 t1, t2;
Andrew Morton30e69592005-06-26 17:18:46 -07001598 const char *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001600 dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 next = buf;
1602 size = PAGE_SIZE;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001603 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
1605 if (dev->driver)
1606 s = dev->driver->driver.name;
1607 else
1608 s = "(none)";
1609
1610 /* Main Control Registers */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001611 t = scnprintf(next, size, "%s version " DRIVER_VERSION
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 ", chiprev %04x, dma %s\n\n"
1613 "devinit %03x fifoctl %08x gadget '%s'\n"
1614 "pci irqenb0 %02x irqenb1 %08x "
1615 "irqstat0 %04x irqstat1 %08x\n",
1616 driver_name, dev->chiprev,
1617 use_dma
1618 ? (use_dma_chaining ? "chaining" : "enabled")
1619 : "disabled",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001620 readl(&dev->regs->devinit),
1621 readl(&dev->regs->fifoctl),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 s,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001623 readl(&dev->regs->pciirqenb0),
1624 readl(&dev->regs->pciirqenb1),
1625 readl(&dev->regs->irqstat0),
1626 readl(&dev->regs->irqstat1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 size -= t;
1628 next += t;
1629
1630 /* USB Control Registers */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001631 t1 = readl(&dev->usb->usbctl);
1632 t2 = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001633 if (t1 & BIT(VBUS_PIN)) {
1634 if (t2 & BIT(HIGH_SPEED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635 s = "high speed";
1636 else if (dev->gadget.speed == USB_SPEED_UNKNOWN)
1637 s = "powered";
1638 else
1639 s = "full speed";
1640 /* full speed bit (6) not working?? */
1641 } else
1642 s = "not attached";
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001643 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 "stdrsp %08x usbctl %08x usbstat %08x "
1645 "addr 0x%02x (%s)\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001646 readl(&dev->usb->stdrsp), t1, t2,
1647 readl(&dev->usb->ouraddr), s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 size -= t;
1649 next += t;
1650
1651 /* PCI Master Control Registers */
1652
1653 /* DMA Control Registers */
1654
1655 /* Configurable EP Control Registers */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001656 for (i = 0; i < dev->n_ep; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 struct net2280_ep *ep;
1658
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001659 ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 if (i && !ep->desc)
1661 continue;
1662
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001663 t1 = readl(&ep->cfg->ep_cfg);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001664 t2 = readl(&ep->regs->ep_rsp) & 0xff;
1665 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
1667 "irqenb %02x\n",
1668 ep->ep.name, t1, t2,
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001669 (t2 & BIT(CLEAR_NAK_OUT_PACKETS))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 ? "NAK " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001671 (t2 & BIT(CLEAR_EP_HIDE_STATUS_PHASE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 ? "hide " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001673 (t2 & BIT(CLEAR_EP_FORCE_CRC_ERROR))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 ? "CRC " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001675 (t2 & BIT(CLEAR_INTERRUPT_MODE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 ? "interrupt " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001677 (t2 & BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 ? "status " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001679 (t2 & BIT(CLEAR_NAK_OUT_PACKETS_MODE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 ? "NAKmode " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001681 (t2 & BIT(CLEAR_ENDPOINT_TOGGLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 ? "DATA1 " : "DATA0 ",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001683 (t2 & BIT(CLEAR_ENDPOINT_HALT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 ? "HALT " : "",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001685 readl(&ep->regs->ep_irqenb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 size -= t;
1687 next += t;
1688
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001689 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 "\tstat %08x avail %04x "
1691 "(ep%d%s-%s)%s\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001692 readl(&ep->regs->ep_stat),
1693 readl(&ep->regs->ep_avail),
1694 t1 & 0x0f, DIR_STRING(t1),
1695 type_string(t1 >> 8),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 ep->stopped ? "*" : "");
1697 size -= t;
1698 next += t;
1699
1700 if (!ep->dma)
1701 continue;
1702
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001703 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 " dma\tctl %08x stat %08x count %08x\n"
1705 "\taddr %08x desc %08x\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001706 readl(&ep->dma->dmactl),
1707 readl(&ep->dma->dmastat),
1708 readl(&ep->dma->dmacount),
1709 readl(&ep->dma->dmaaddr),
1710 readl(&ep->dma->dmadesc));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 size -= t;
1712 next += t;
1713
1714 }
1715
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001716 /* Indexed Registers (none yet) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718 /* Statistics */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001719 t = scnprintf(next, size, "\nirqs: ");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 size -= t;
1721 next += t;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001722 for (i = 0; i < dev->n_ep; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 struct net2280_ep *ep;
1724
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001725 ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 if (i && !ep->irqs)
1727 continue;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001728 t = scnprintf(next, size, " %s/%lu", ep->ep.name, ep->irqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 size -= t;
1730 next += t;
1731
1732 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001733 t = scnprintf(next, size, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 size -= t;
1735 next += t;
1736
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001737 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
1739 return PAGE_SIZE - size;
1740}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001741static DEVICE_ATTR_RO(registers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001743static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
1744 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745{
1746 struct net2280 *dev;
1747 char *next;
1748 unsigned size;
1749 unsigned long flags;
1750 int i;
1751
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001752 dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 next = buf;
1754 size = PAGE_SIZE;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001755 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001757 for (i = 0; i < dev->n_ep; i++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001758 struct net2280_ep *ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 struct net2280_request *req;
1760 int t;
1761
1762 if (i != 0) {
1763 const struct usb_endpoint_descriptor *d;
1764
1765 d = ep->desc;
1766 if (!d)
1767 continue;
1768 t = d->bEndpointAddress;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001769 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 "\n%s (ep%d%s-%s) max %04x %s fifo %d\n",
1771 ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
1772 (t & USB_DIR_IN) ? "in" : "out",
Ricardo Ribalda Delgadoa27f37a2014-05-20 18:30:08 +02001773 type_string(d->bmAttributes),
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001774 usb_endpoint_maxp(d) & 0x1fff,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 ep->dma ? "dma" : "pio", ep->fifo_size
1776 );
1777 } else /* ep0 should only have one transfer queued */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001778 t = scnprintf(next, size, "ep0 max 64 pio %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 ep->is_in ? "in" : "out");
1780 if (t <= 0 || t > size)
1781 goto done;
1782 size -= t;
1783 next += t;
1784
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001785 if (list_empty(&ep->queue)) {
1786 t = scnprintf(next, size, "\t(nothing queued)\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 if (t <= 0 || t > size)
1788 goto done;
1789 size -= t;
1790 next += t;
1791 continue;
1792 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001793 list_for_each_entry(req, &ep->queue, queue) {
1794 if (ep->dma && req->td_dma == readl(&ep->dma->dmadesc))
1795 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 "\treq %p len %d/%d "
1797 "buf %p (dmacount %08x)\n",
1798 &req->req, req->req.actual,
1799 req->req.length, req->req.buf,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001800 readl(&ep->dma->dmacount));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001802 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 "\treq %p len %d/%d buf %p\n",
1804 &req->req, req->req.actual,
1805 req->req.length, req->req.buf);
1806 if (t <= 0 || t > size)
1807 goto done;
1808 size -= t;
1809 next += t;
1810
1811 if (ep->dma) {
1812 struct net2280_dma *td;
1813
1814 td = req->td;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001815 t = scnprintf(next, size, "\t td %08x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 " count %08x buf %08x desc %08x\n",
1817 (u32) req->td_dma,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001818 le32_to_cpu(td->dmacount),
1819 le32_to_cpu(td->dmaaddr),
1820 le32_to_cpu(td->dmadesc));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 if (t <= 0 || t > size)
1822 goto done;
1823 size -= t;
1824 next += t;
1825 }
1826 }
1827 }
1828
1829done:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001830 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 return PAGE_SIZE - size;
1832}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001833static DEVICE_ATTR_RO(queues);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835
1836#else
1837
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001838#define device_create_file(a, b) (0)
1839#define device_remove_file(a, b) do { } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
1841#endif
1842
1843/*-------------------------------------------------------------------------*/
1844
1845/* another driver-specific mode might be a request type doing dma
1846 * to/from another device fifo instead of to/from memory.
1847 */
1848
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001849static void set_fifo_mode(struct net2280 *dev, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850{
1851 /* keeping high bits preserves BAR2 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001852 writel((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
1854 /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001855 INIT_LIST_HEAD(&dev->gadget.ep_list);
1856 list_add_tail(&dev->ep[1].ep.ep_list, &dev->gadget.ep_list);
1857 list_add_tail(&dev->ep[2].ep.ep_list, &dev->gadget.ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 switch (mode) {
1859 case 0:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001860 list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
1861 list_add_tail(&dev->ep[4].ep.ep_list, &dev->gadget.ep_list);
1862 dev->ep[1].fifo_size = dev->ep[2].fifo_size = 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 break;
1864 case 1:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001865 dev->ep[1].fifo_size = dev->ep[2].fifo_size = 2048;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 break;
1867 case 2:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001868 list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
1869 dev->ep[1].fifo_size = 2048;
1870 dev->ep[2].fifo_size = 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 break;
1872 }
1873 /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001874 list_add_tail(&dev->ep[5].ep.ep_list, &dev->gadget.ep_list);
1875 list_add_tail(&dev->ep[6].ep.ep_list, &dev->gadget.ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876}
1877
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001878static void defect7374_disable_data_eps(struct net2280 *dev)
1879{
1880 /*
1881 * For Defect 7374, disable data EPs (and more):
1882 * - This phase undoes the earlier phase of the Defect 7374 workaround,
1883 * returing ep regs back to normal.
1884 */
1885 struct net2280_ep *ep;
1886 int i;
1887 unsigned char ep_sel;
1888 u32 tmp_reg;
1889
1890 for (i = 1; i < 5; i++) {
1891 ep = &dev->ep[i];
1892 writel(0, &ep->cfg->ep_cfg);
1893 }
1894
1895 /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
1896 for (i = 0; i < 6; i++)
1897 writel(0, &dev->dep[i].dep_cfg);
1898
1899 for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
1900 /* Select an endpoint for subsequent operations: */
1901 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
1902 writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl);
1903
1904 if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) ||
1905 ep_sel == 18 || ep_sel == 20)
1906 continue;
1907
1908 /* Change settings on some selected endpoints */
1909 tmp_reg = readl(&dev->plregs->pl_ep_cfg_4);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001910 tmp_reg &= ~BIT(NON_CTRL_IN_TOLERATE_BAD_DIR);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001911 writel(tmp_reg, &dev->plregs->pl_ep_cfg_4);
1912 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001913 tmp_reg |= BIT(EP_INITIALIZED);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001914 writel(tmp_reg, &dev->plregs->pl_ep_ctrl);
1915 }
1916}
1917
1918static void defect7374_enable_data_eps_zero(struct net2280 *dev)
1919{
1920 u32 tmp = 0, tmp_reg;
1921 u32 fsmvalue, scratch;
1922 int i;
1923 unsigned char ep_sel;
1924
1925 scratch = get_idx_reg(dev->regs, SCRATCH);
1926 fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
1927 scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
1928
1929 /*See if firmware needs to set up for workaround*/
1930 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
1931 WARNING(dev, "Operate Defect 7374 workaround soft this time");
1932 WARNING(dev, "It will operate on cold-reboot and SS connect");
1933
1934 /*GPEPs:*/
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001935 tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001936 (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
1937 ((dev->enhanced_mode) ?
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001938 BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
1939 BIT(IN_ENDPOINT_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001940
1941 for (i = 1; i < 5; i++)
1942 writel(tmp, &dev->ep[i].cfg->ep_cfg);
1943
1944 /* CSRIN, PCIIN, STATIN, RCIN*/
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001945 tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001946 writel(tmp, &dev->dep[1].dep_cfg);
1947 writel(tmp, &dev->dep[3].dep_cfg);
1948 writel(tmp, &dev->dep[4].dep_cfg);
1949 writel(tmp, &dev->dep[5].dep_cfg);
1950
1951 /*Implemented for development and debug.
1952 * Can be refined/tuned later.*/
1953 for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
1954 /* Select an endpoint for subsequent operations: */
1955 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
1956 writel(((tmp_reg & ~0x1f) | ep_sel),
1957 &dev->plregs->pl_ep_ctrl);
1958
1959 if (ep_sel == 1) {
1960 tmp =
1961 (readl(&dev->plregs->pl_ep_ctrl) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001962 BIT(CLEAR_ACK_ERROR_CODE) | 0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001963 writel(tmp, &dev->plregs->pl_ep_ctrl);
1964 continue;
1965 }
1966
1967 if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
1968 ep_sel == 18 || ep_sel == 20)
1969 continue;
1970
1971 tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001972 BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001973 writel(tmp, &dev->plregs->pl_ep_cfg_4);
1974
1975 tmp = readl(&dev->plregs->pl_ep_ctrl) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001976 ~BIT(EP_INITIALIZED);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001977 writel(tmp, &dev->plregs->pl_ep_ctrl);
1978
1979 }
1980
1981 /* Set FSM to focus on the first Control Read:
1982 * - Tip: Connection speed is known upon the first
1983 * setup request.*/
1984 scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
1985 set_idx_reg(dev->regs, SCRATCH, scratch);
1986
1987 } else{
1988 WARNING(dev, "Defect 7374 workaround soft will NOT operate");
1989 WARNING(dev, "It will operate on cold-reboot and SS connect");
1990 }
1991}
1992
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993/* keeping it simple:
1994 * - one bus driver, initted first;
1995 * - one function driver, initted second
1996 *
1997 * most of the work to support multiple net2280 controllers would
1998 * be to associate this gadget driver (yes?) with all of them, or
1999 * perhaps to bind specific drivers to specific devices.
2000 */
2001
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002002static void usb_reset_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003{
2004 u32 tmp;
2005
2006 dev->gadget.speed = USB_SPEED_UNKNOWN;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002007 (void) readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002009 net2280_led_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 /* disable automatic responses, and irqs */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002012 writel(0, &dev->usb->stdrsp);
2013 writel(0, &dev->regs->pciirqenb0);
2014 writel(0, &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015
2016 /* clear old dma and irq state */
2017 for (tmp = 0; tmp < 4; tmp++) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002018 struct net2280_ep *ep = &dev->ep[tmp + 1];
Greg Kroah-Hartman357d596e2014-05-28 11:35:41 -07002019 if (ep->dma)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002020 abort_dma(ep);
Greg Kroah-Hartman357d596e2014-05-28 11:35:41 -07002021 }
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002022
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002023 writel(~0, &dev->regs->irqstat0),
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002024 writel(~(u32)BIT(SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025
2026 /* reset, and enable pci */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002027 tmp = readl(&dev->regs->devinit) |
2028 BIT(PCI_ENABLE) |
2029 BIT(FIFO_SOFT_RESET) |
2030 BIT(USB_SOFT_RESET) |
2031 BIT(M8051_RESET);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002032 writel(tmp, &dev->regs->devinit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033
2034 /* standard fifo and endpoint allocations */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002035 set_fifo_mode(dev, (fifo_mode <= 2) ? fifo_mode : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036}
2037
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002038static void usb_reset_338x(struct net2280 *dev)
2039{
2040 u32 tmp;
2041 u32 fsmvalue;
2042
2043 dev->gadget.speed = USB_SPEED_UNKNOWN;
2044 (void)readl(&dev->usb->usbctl);
2045
2046 net2280_led_init(dev);
2047
2048 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
2049 (0xf << DEFECT7374_FSM_FIELD);
2050
2051 /* See if firmware needs to set up for workaround: */
2052 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
2053 INFO(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__,
2054 fsmvalue);
2055 } else {
2056 /* disable automatic responses, and irqs */
2057 writel(0, &dev->usb->stdrsp);
2058 writel(0, &dev->regs->pciirqenb0);
2059 writel(0, &dev->regs->pciirqenb1);
2060 }
2061
2062 /* clear old dma and irq state */
2063 for (tmp = 0; tmp < 4; tmp++) {
2064 struct net2280_ep *ep = &dev->ep[tmp + 1];
2065
2066 if (ep->dma)
2067 abort_dma(ep);
2068 }
2069
2070 writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1);
2071
2072 if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
2073 /* reset, and enable pci */
2074 tmp = readl(&dev->regs->devinit) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002075 BIT(PCI_ENABLE) |
2076 BIT(FIFO_SOFT_RESET) |
2077 BIT(USB_SOFT_RESET) |
2078 BIT(M8051_RESET);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002079
2080 writel(tmp, &dev->regs->devinit);
2081 }
2082
2083 /* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */
2084 INIT_LIST_HEAD(&dev->gadget.ep_list);
2085
2086 for (tmp = 1; tmp < dev->n_ep; tmp++)
2087 list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list);
2088
2089}
2090
2091static void usb_reset(struct net2280 *dev)
2092{
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002093 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002094 return usb_reset_228x(dev);
2095 return usb_reset_338x(dev);
2096}
2097
2098static void usb_reinit_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099{
2100 u32 tmp;
2101 int init_dma;
2102
2103 /* use_dma changes are ignored till next device re-init */
2104 init_dma = use_dma;
2105
2106 /* basic endpoint init */
2107 for (tmp = 0; tmp < 7; tmp++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002108 struct net2280_ep *ep = &dev->ep[tmp];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002110 ep->ep.name = ep_name[tmp];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111 ep->dev = dev;
2112 ep->num = tmp;
2113
2114 if (tmp > 0 && tmp <= 4) {
2115 ep->fifo_size = 1024;
2116 if (init_dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002117 ep->dma = &dev->dma[tmp - 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 } else
2119 ep->fifo_size = 64;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002120 ep->regs = &dev->epregs[tmp];
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002121 ep->cfg = &dev->epregs[tmp];
2122 ep_reset_228x(dev->regs, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002124 usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 64);
2125 usb_ep_set_maxpacket_limit(&dev->ep[5].ep, 64);
2126 usb_ep_set_maxpacket_limit(&dev->ep[6].ep, 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002128 dev->gadget.ep0 = &dev->ep[0].ep;
2129 dev->ep[0].stopped = 0;
2130 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
2132 /* we want to prevent lowlevel/insecure access from the USB host,
2133 * but erratum 0119 means this enable bit is ignored
2134 */
2135 for (tmp = 0; tmp < 5; tmp++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002136 writel(EP_DONTUSE, &dev->dep[tmp].dep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137}
2138
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002139static void usb_reinit_338x(struct net2280 *dev)
2140{
2141 int init_dma;
2142 int i;
2143 u32 tmp, val;
2144 u32 fsmvalue;
2145 static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
2146 static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00,
2147 0x00, 0xC0, 0x00, 0xC0 };
2148
2149 /* use_dma changes are ignored till next device re-init */
2150 init_dma = use_dma;
2151
2152 /* basic endpoint init */
2153 for (i = 0; i < dev->n_ep; i++) {
2154 struct net2280_ep *ep = &dev->ep[i];
2155
2156 ep->ep.name = ep_name[i];
2157 ep->dev = dev;
2158 ep->num = i;
2159
2160 if (i > 0 && i <= 4 && init_dma)
2161 ep->dma = &dev->dma[i - 1];
2162
2163 if (dev->enhanced_mode) {
2164 ep->cfg = &dev->epregs[ne[i]];
2165 ep->regs = (struct net2280_ep_regs __iomem *)
2166 (((void *)&dev->epregs[ne[i]]) +
2167 ep_reg_addr[i]);
2168 ep->fiforegs = &dev->fiforegs[i];
2169 } else {
2170 ep->cfg = &dev->epregs[i];
2171 ep->regs = &dev->epregs[i];
2172 ep->fiforegs = &dev->fiforegs[i];
2173 }
2174
2175 ep->fifo_size = (i != 0) ? 2048 : 512;
2176
2177 ep_reset_338x(dev->regs, ep);
2178 }
2179 usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512);
2180
2181 dev->gadget.ep0 = &dev->ep[0].ep;
2182 dev->ep[0].stopped = 0;
2183
2184 /* Link layer set up */
2185 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
2186 (0xf << DEFECT7374_FSM_FIELD);
2187
2188 /* See if driver needs to set up for workaround: */
2189 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
2190 INFO(dev, "%s: Defect 7374 FsmValue %08x\n",
2191 __func__, fsmvalue);
2192 else {
2193 tmp = readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002194 ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002195 writel(tmp, &dev->usb_ext->usbctl2);
2196 }
2197
2198 /* Hardware Defect and Workaround */
2199 val = readl(&dev->ll_lfps_regs->ll_lfps_5);
2200 val &= ~(0xf << TIMER_LFPS_6US);
2201 val |= 0x5 << TIMER_LFPS_6US;
2202 writel(val, &dev->ll_lfps_regs->ll_lfps_5);
2203
2204 val = readl(&dev->ll_lfps_regs->ll_lfps_6);
2205 val &= ~(0xffff << TIMER_LFPS_80US);
2206 val |= 0x0100 << TIMER_LFPS_80US;
2207 writel(val, &dev->ll_lfps_regs->ll_lfps_6);
2208
2209 /*
2210 * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB
2211 * Hot Reset Exit Handshake may Fail in Specific Case using
2212 * Default Register Settings. Workaround for Enumeration test.
2213 */
2214 val = readl(&dev->ll_tsn_regs->ll_tsn_counters_2);
2215 val &= ~(0x1f << HOT_TX_NORESET_TS2);
2216 val |= 0x10 << HOT_TX_NORESET_TS2;
2217 writel(val, &dev->ll_tsn_regs->ll_tsn_counters_2);
2218
2219 val = readl(&dev->ll_tsn_regs->ll_tsn_counters_3);
2220 val &= ~(0x1f << HOT_RX_RESET_TS2);
2221 val |= 0x3 << HOT_RX_RESET_TS2;
2222 writel(val, &dev->ll_tsn_regs->ll_tsn_counters_3);
2223
2224 /*
2225 * Set Recovery Idle to Recover bit:
2226 * - On SS connections, setting Recovery Idle to Recover Fmw improves
2227 * link robustness with various hosts and hubs.
2228 * - It is safe to set for all connection speeds; all chip revisions.
2229 * - R-M-W to leave other bits undisturbed.
2230 * - Reference PLX TT-7372
2231 */
2232 val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002233 val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002234 writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit);
2235
2236 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
2237
2238 /* disable dedicated endpoints */
2239 writel(0x0D, &dev->dep[0].dep_cfg);
2240 writel(0x0D, &dev->dep[1].dep_cfg);
2241 writel(0x0E, &dev->dep[2].dep_cfg);
2242 writel(0x0E, &dev->dep[3].dep_cfg);
2243 writel(0x0F, &dev->dep[4].dep_cfg);
2244 writel(0x0C, &dev->dep[5].dep_cfg);
2245}
2246
2247static void usb_reinit(struct net2280 *dev)
2248{
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002249 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002250 return usb_reinit_228x(dev);
2251 return usb_reinit_338x(dev);
2252}
2253
2254static void ep0_start_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002256 writel(BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
2257 BIT(CLEAR_NAK_OUT_PACKETS) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002258 BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
2259 &dev->epregs[0].ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260
2261 /*
2262 * hardware optionally handles a bunch of standard requests
2263 * that the API hides from drivers anyway. have it do so.
2264 * endpoint status/features are handled in software, to
2265 * help pass tests for some dubious behavior.
2266 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002267 writel(BIT(SET_TEST_MODE) |
2268 BIT(SET_ADDRESS) |
2269 BIT(DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) |
2270 BIT(GET_DEVICE_STATUS) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002271 BIT(GET_INTERFACE_STATUS),
2272 &dev->usb->stdrsp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002273 writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
2274 BIT(SELF_POWERED_USB_DEVICE) |
2275 BIT(REMOTE_WAKEUP_SUPPORT) |
2276 (dev->softconnect << USB_DETECT_ENABLE) |
2277 BIT(SELF_POWERED_STATUS),
2278 &dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279
2280 /* enable irqs so we can see ep0 and general operation */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002281 writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
2282 BIT(ENDPOINT_0_INTERRUPT_ENABLE),
2283 &dev->regs->pciirqenb0);
2284 writel(BIT(PCI_INTERRUPT_ENABLE) |
2285 BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) |
2286 BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) |
2287 BIT(PCI_RETRY_ABORT_INTERRUPT_ENABLE) |
2288 BIT(VBUS_INTERRUPT_ENABLE) |
2289 BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
2290 BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE),
2291 &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293 /* don't leave any writes posted */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002294 (void) readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295}
2296
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002297static void ep0_start_338x(struct net2280 *dev)
2298{
2299 u32 fsmvalue;
2300
2301 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
2302 (0xf << DEFECT7374_FSM_FIELD);
2303
2304 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
2305 INFO(dev, "%s: Defect 7374 FsmValue %08x\n", __func__,
2306 fsmvalue);
2307 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002308 writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
2309 BIT(SET_EP_HIDE_STATUS_PHASE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002310 &dev->epregs[0].ep_rsp);
2311
2312 /*
2313 * hardware optionally handles a bunch of standard requests
2314 * that the API hides from drivers anyway. have it do so.
2315 * endpoint status/features are handled in software, to
2316 * help pass tests for some dubious behavior.
2317 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002318 writel(BIT(SET_ISOCHRONOUS_DELAY) |
2319 BIT(SET_SEL) |
2320 BIT(SET_TEST_MODE) |
2321 BIT(SET_ADDRESS) |
2322 BIT(GET_INTERFACE_STATUS) |
2323 BIT(GET_DEVICE_STATUS),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002324 &dev->usb->stdrsp);
2325 dev->wakeup_enable = 1;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002326 writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002327 (dev->softconnect << USB_DETECT_ENABLE) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002328 BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002329 &dev->usb->usbctl);
2330
2331 /* enable irqs so we can see ep0 and general operation */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002332 writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002333 BIT(ENDPOINT_0_INTERRUPT_ENABLE),
2334 &dev->regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002335 writel(BIT(PCI_INTERRUPT_ENABLE) |
2336 BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
2337 BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) |
2338 BIT(VBUS_INTERRUPT_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002339 &dev->regs->pciirqenb1);
2340
2341 /* don't leave any writes posted */
2342 (void)readl(&dev->usb->usbctl);
2343}
2344
2345static void ep0_start(struct net2280 *dev)
2346{
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002347 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002348 return ep0_start_228x(dev);
2349 return ep0_start_338x(dev);
2350}
2351
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352/* when a driver is successfully registered, it will receive
2353 * control requests including set_configuration(), which enables
2354 * non-control requests. then usb traffic follows until a
2355 * disconnect is reported. then a host may connect again, or
2356 * the driver might get unbound.
2357 */
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002358static int net2280_start(struct usb_gadget *_gadget,
2359 struct usb_gadget_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360{
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002361 struct net2280 *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 int retval;
2363 unsigned i;
2364
2365 /* insist on high speed support from the driver, since
2366 * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
2367 * "must not be used in normal operation"
2368 */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002369 if (!driver || driver->max_speed < USB_SPEED_HIGH ||
2370 !driver->setup)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371 return -EINVAL;
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002372
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002373 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002375 for (i = 0; i < dev->n_ep; i++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002376 dev->ep[i].irqs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377
2378 /* hook up the driver ... */
2379 dev->softconnect = 1;
2380 driver->driver.bus = NULL;
2381 dev->driver = driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002383 retval = device_create_file(&dev->pdev->dev, &dev_attr_function);
2384 if (retval)
2385 goto err_unbind;
2386 retval = device_create_file(&dev->pdev->dev, &dev_attr_queues);
2387 if (retval)
2388 goto err_func;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389
Alan Stern2f076072013-01-30 16:40:14 -05002390 /* Enable force-full-speed testing mode, if desired */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002391 if (full_speed && dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002392 writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag);
Alan Stern2f076072013-01-30 16:40:14 -05002393
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394 /* ... then enable host detection and ep0; and we're ready
2395 * for set_configuration as well as eventual disconnect.
2396 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002397 net2280_led_active(dev, 1);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002398
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002399 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002400 defect7374_enable_data_eps_zero(dev);
2401
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002402 ep0_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002404 DEBUG(dev, "%s ready, usbctl %08x stdrsp %08x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 driver->driver.name,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002406 readl(&dev->usb->usbctl),
2407 readl(&dev->usb->stdrsp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
2409 /* pci writes may still be posted */
2410 return 0;
Jeff Garzikb3899da2006-10-11 21:50:24 -04002411
2412err_func:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002413 device_remove_file(&dev->pdev->dev, &dev_attr_function);
Jeff Garzikb3899da2006-10-11 21:50:24 -04002414err_unbind:
Jeff Garzikb3899da2006-10-11 21:50:24 -04002415 dev->driver = NULL;
2416 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002419static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420{
2421 int i;
2422
2423 /* don't disconnect if it's not connected */
2424 if (dev->gadget.speed == USB_SPEED_UNKNOWN)
2425 driver = NULL;
2426
2427 /* stop hardware; prevent new request submissions;
2428 * and kill any outstanding requests.
2429 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002430 usb_reset(dev);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002431 for (i = 0; i < dev->n_ep; i++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002432 nuke(&dev->ep[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433
Felipe Balbi699412d2013-03-18 10:14:47 +02002434 /* report disconnect; the driver is already quiesced */
2435 if (driver) {
2436 spin_unlock(&dev->lock);
2437 driver->disconnect(&dev->gadget);
2438 spin_lock(&dev->lock);
2439 }
2440
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002441 usb_reinit(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442}
2443
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002444static int net2280_stop(struct usb_gadget *_gadget,
2445 struct usb_gadget_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446{
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002447 struct net2280 *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 unsigned long flags;
2449
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002450 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002452 spin_lock_irqsave(&dev->lock, flags);
2453 stop_activity(dev, driver);
2454 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 dev->driver = NULL;
2457
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002458 net2280_led_active(dev, 0);
Alan Stern2f076072013-01-30 16:40:14 -05002459
2460 /* Disable full-speed test mode */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02002461 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002462 writel(0, &dev->usb->xcvrdiag);
Alan Stern2f076072013-01-30 16:40:14 -05002463
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002464 device_remove_file(&dev->pdev->dev, &dev_attr_function);
2465 device_remove_file(&dev->pdev->dev, &dev_attr_queues);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466
Ricardo Ribalda Delgado84237bf2014-05-15 14:28:45 +02002467 DEBUG(dev, "unregistered driver '%s'\n",
2468 driver ? driver->driver.name : "");
2469
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470 return 0;
2471}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472
2473/*-------------------------------------------------------------------------*/
2474
2475/* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq.
2476 * also works for dma-capable endpoints, in pio mode or just
2477 * to manually advance the queue after short OUT transfers.
2478 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002479static void handle_ep_small(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480{
2481 struct net2280_request *req;
2482 u32 t;
2483 /* 0 error, 1 mid-data, 2 done */
2484 int mode = 1;
2485
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002486 if (!list_empty(&ep->queue))
2487 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 struct net2280_request, queue);
2489 else
2490 req = NULL;
2491
2492 /* ack all, and handle what we care about */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002493 t = readl(&ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 ep->irqs++;
2495#if 0
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002496 VDEBUG(ep->dev, "%s ack ep_stat %08x, req %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 ep->ep.name, t, req ? &req->req : 0);
2498#endif
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01002499 if (!ep->is_in || ep->dev->pdev->device == 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002500 writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01002501 else
2502 /* Added for 2282 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002503 writel(t, &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002504
2505 /* for ep0, monitor token irqs to catch data stage length errors
2506 * and to synchronize on status.
2507 *
2508 * also, to defer reporting of protocol stalls ... here's where
2509 * data or status first appears, handling stalls here should never
2510 * cause trouble on the host side..
2511 *
2512 * control requests could be slightly faster without token synch for
2513 * status, but status can jam up that way.
2514 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002515 if (unlikely(ep->num == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 if (ep->is_in) {
2517 /* status; stop NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002518 if (t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 if (ep->dev->protocol_stall) {
2520 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002521 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 }
2523 if (!req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002524 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 mode = 2;
2526 /* reply to extra IN data tokens with a zlp */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002527 } else if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528 if (ep->dev->protocol_stall) {
2529 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002530 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 mode = 2;
Alan Stern1f26e282006-11-16 10:16:00 -05002532 } else if (ep->responded &&
2533 !req && !ep->stopped)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002534 write_fifo(ep, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535 }
2536 } else {
2537 /* status; stop NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002538 if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 if (ep->dev->protocol_stall) {
2540 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002541 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542 }
2543 mode = 2;
2544 /* an extra OUT token is an error */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002545 } else if (((t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) &&
2546 req &&
2547 req->req.actual == req->req.length) ||
2548 (ep->responded && !req)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 ep->dev->protocol_stall = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002550 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 ep->stopped = 1;
2552 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002553 done(ep, req, -EOVERFLOW);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 req = NULL;
2555 }
2556 }
2557 }
2558
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002559 if (unlikely(!req))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560 return;
2561
2562 /* manual DMA queue advance after short OUT */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002563 if (likely(ep->dma)) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002564 if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565 u32 count;
2566 int stopped = ep->stopped;
2567
2568 /* TRANSFERRED works around OUT_DONE erratum 0112.
2569 * we expect (N <= maxpacket) bytes; host wrote M.
2570 * iff (M < N) we won't ever see a DMA interrupt.
2571 */
2572 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002573 for (count = 0; ; t = readl(&ep->regs->ep_stat)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574
2575 /* any preceding dma transfers must finish.
2576 * dma handles (M >= N), may empty the queue
2577 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002578 scan_dma_completions(ep);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002579 if (unlikely(list_empty(&ep->queue) ||
2580 ep->out_overflow)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 req = NULL;
2582 break;
2583 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002584 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 struct net2280_request, queue);
2586
2587 /* here either (M < N), a "real" short rx;
2588 * or (M == N) and the queue didn't empty
2589 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002590 if (likely(t & BIT(FIFO_EMPTY))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002591 count = readl(&ep->dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 count &= DMA_BYTE_COUNT_MASK;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002593 if (readl(&ep->dma->dmadesc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594 != req->td_dma)
2595 req = NULL;
2596 break;
2597 }
2598 udelay(1);
2599 }
2600
2601 /* stop DMA, leave ep NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002602 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002603 spin_stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002605 if (likely(req)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 req->td->dmacount = 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002607 t = readl(&ep->regs->ep_avail);
2608 dma_done(ep, req, count,
David Brownell901b3d72006-09-02 03:13:45 -07002609 (ep->out_overflow || t)
2610 ? -EOVERFLOW : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611 }
2612
2613 /* also flush to prevent erratum 0106 trouble */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002614 if (unlikely(ep->out_overflow ||
2615 (ep->dev->chiprev == 0x0100 &&
2616 ep->dev->gadget.speed
2617 == USB_SPEED_FULL))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002618 out_flush(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 ep->out_overflow = 0;
2620 }
2621
2622 /* (re)start dma if needed, stop NAKing */
2623 ep->stopped = stopped;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002624 if (!list_empty(&ep->queue))
2625 restart_dma(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 } else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002627 DEBUG(ep->dev, "%s dma ep_stat %08x ??\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 ep->ep.name, t);
2629 return;
2630
2631 /* data packet(s) received (in the fifo, OUT) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002632 } else if (t & BIT(DATA_PACKET_RECEIVED_INTERRUPT)) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002633 if (read_fifo(ep, req) && ep->num != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 mode = 2;
2635
2636 /* data packet(s) transmitted (IN) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002637 } else if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 unsigned len;
2639
2640 len = req->req.length - req->req.actual;
2641 if (len > ep->ep.maxpacket)
2642 len = ep->ep.maxpacket;
2643 req->req.actual += len;
2644
2645 /* if we wrote it all, we're usually done */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002646 /* send zlps until the status stage */
2647 if ((req->req.actual == req->req.length) &&
2648 (!req->req.zero || len != ep->ep.maxpacket) && ep->num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 mode = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650
2651 /* there was nothing to do ... */
2652 } else if (mode == 1)
2653 return;
2654
2655 /* done */
2656 if (mode == 2) {
2657 /* stream endpoints often resubmit/unlink in completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002658 done(ep, req, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659
2660 /* maybe advance queue to next request */
2661 if (ep->num == 0) {
2662 /* NOTE: net2280 could let gadget driver start the
2663 * status stage later. since not all controllers let
2664 * them control that, the api doesn't (yet) allow it.
2665 */
2666 if (!ep->stopped)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002667 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 req = NULL;
2669 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002670 if (!list_empty(&ep->queue) && !ep->stopped)
2671 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 struct net2280_request, queue);
2673 else
2674 req = NULL;
2675 if (req && !ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002676 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 }
2678 }
2679
2680 /* is there a buffer for the next packet?
2681 * for best streaming performance, make sure there is one.
2682 */
2683 if (req && !ep->stopped) {
2684
2685 /* load IN fifo with next packet (may be zlp) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002686 if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT))
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002687 write_fifo(ep, &req->req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 }
2689}
2690
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002691static struct net2280_ep *get_ep_by_addr(struct net2280 *dev, u16 wIndex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692{
2693 struct net2280_ep *ep;
2694
2695 if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002696 return &dev->ep[0];
2697 list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 u8 bEndpointAddress;
2699
2700 if (!ep->desc)
2701 continue;
2702 bEndpointAddress = ep->desc->bEndpointAddress;
2703 if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
2704 continue;
2705 if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f))
2706 return ep;
2707 }
2708 return NULL;
2709}
2710
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002711static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
2712{
2713 u32 scratch, fsmvalue;
2714 u32 ack_wait_timeout, state;
2715
2716 /* Workaround for Defect 7374 (U1/U2 erroneously rejected): */
2717 scratch = get_idx_reg(dev->regs, SCRATCH);
2718 fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
2719 scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
2720
2721 if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) &&
2722 (r.bRequestType & USB_DIR_IN)))
2723 return;
2724
2725 /* This is the first Control Read for this connection: */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002726 if (!(readl(&dev->usb->usbstat) & BIT(SUPER_SPEED_MODE))) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002727 /*
2728 * Connection is NOT SS:
2729 * - Connection must be FS or HS.
2730 * - This FSM state should allow workaround software to
2731 * run after the next USB connection.
2732 */
2733 scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ;
2734 goto restore_data_eps;
2735 }
2736
2737 /* Connection is SS: */
2738 for (ack_wait_timeout = 0;
2739 ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS;
2740 ack_wait_timeout++) {
2741
2742 state = readl(&dev->plregs->pl_ep_status_1)
2743 & (0xff << STATE);
2744 if ((state >= (ACK_GOOD_NORMAL << STATE)) &&
2745 (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) {
2746 scratch |= DEFECT7374_FSM_SS_CONTROL_READ;
2747 break;
2748 }
2749
2750 /*
2751 * We have not yet received host's Data Phase ACK
2752 * - Wait and try again.
2753 */
2754 udelay(DEFECT_7374_PROCESSOR_WAIT_TIME);
2755
2756 continue;
2757 }
2758
2759
2760 if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) {
2761 ERROR(dev, "FAIL: Defect 7374 workaround waited but failed "
2762 "to detect SS host's data phase ACK.");
2763 ERROR(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16"
2764 "got 0x%2.2x.\n", state >> STATE);
2765 } else {
2766 WARNING(dev, "INFO: Defect 7374 workaround waited about\n"
2767 "%duSec for Control Read Data Phase ACK\n",
2768 DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout);
2769 }
2770
2771restore_data_eps:
2772 /*
2773 * Restore data EPs to their pre-workaround settings (disabled,
2774 * initialized, and other details).
2775 */
2776 defect7374_disable_data_eps(dev);
2777
2778 set_idx_reg(dev->regs, SCRATCH, scratch);
2779
2780 return;
2781}
2782
2783static void ep_stall(struct net2280_ep *ep, int stall)
2784{
2785 struct net2280 *dev = ep->dev;
2786 u32 val;
2787 static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 };
2788
2789 if (stall) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002790 writel(BIT(SET_ENDPOINT_HALT) |
2791 /* BIT(SET_NAK_PACKETS) | */
2792 BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002793 &ep->regs->ep_rsp);
2794 ep->is_halt = 1;
2795 } else {
2796 if (dev->gadget.speed == USB_SPEED_SUPER) {
2797 /*
2798 * Workaround for SS SeqNum not cleared via
2799 * Endpoint Halt (Clear) bit. select endpoint
2800 */
2801 val = readl(&dev->plregs->pl_ep_ctrl);
2802 val = (val & ~0x1f) | ep_pl[ep->num];
2803 writel(val, &dev->plregs->pl_ep_ctrl);
2804
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002805 val |= BIT(SEQUENCE_NUMBER_RESET);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002806 writel(val, &dev->plregs->pl_ep_ctrl);
2807 }
2808 val = readl(&ep->regs->ep_rsp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002809 val |= BIT(CLEAR_ENDPOINT_HALT) |
2810 BIT(CLEAR_ENDPOINT_TOGGLE);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002811 writel(val,
2812 /* | BIT(CLEAR_NAK_PACKETS),*/
2813 &ep->regs->ep_rsp);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002814 ep->is_halt = 0;
2815 val = readl(&ep->regs->ep_rsp);
2816 }
2817}
2818
2819static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged)
2820{
2821 /* set/clear, then synch memory views with the device */
2822 if (value) {
2823 ep->stopped = 1;
2824 if (ep->num == 0)
2825 ep->dev->protocol_stall = 1;
2826 else {
2827 if (ep->dma)
2828 ep_stop_dma(ep);
2829 ep_stall(ep, true);
2830 }
2831
2832 if (wedged)
2833 ep->wedged = 1;
2834 } else {
2835 ep->stopped = 0;
2836 ep->wedged = 0;
2837
2838 ep_stall(ep, false);
2839
2840 /* Flush the queue */
2841 if (!list_empty(&ep->queue)) {
2842 struct net2280_request *req =
2843 list_entry(ep->queue.next, struct net2280_request,
2844 queue);
2845 if (ep->dma)
2846 resume_dma(ep);
2847 else {
2848 if (ep->is_in)
2849 write_fifo(ep, &req->req);
2850 else {
2851 if (read_fifo(ep, req))
2852 done(ep, req, 0);
2853 }
2854 }
2855 }
2856 }
2857}
2858
2859static void handle_stat0_irqs_superspeed(struct net2280 *dev,
2860 struct net2280_ep *ep, struct usb_ctrlrequest r)
2861{
2862 int tmp = 0;
2863
2864#define w_value le16_to_cpu(r.wValue)
2865#define w_index le16_to_cpu(r.wIndex)
2866#define w_length le16_to_cpu(r.wLength)
2867
2868 switch (r.bRequest) {
2869 struct net2280_ep *e;
2870 u16 status;
2871
2872 case USB_REQ_SET_CONFIGURATION:
2873 dev->addressed_state = !w_value;
2874 goto usb3_delegate;
2875
2876 case USB_REQ_GET_STATUS:
2877 switch (r.bRequestType) {
2878 case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2879 status = dev->wakeup_enable ? 0x02 : 0x00;
2880 if (dev->selfpowered)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002881 status |= BIT(0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002882 status |= (dev->u1_enable << 2 | dev->u2_enable << 3 |
2883 dev->ltm_enable << 4);
2884 writel(0, &dev->epregs[0].ep_irqenb);
2885 set_fifo_bytecount(ep, sizeof(status));
2886 writel((__force u32) status, &dev->epregs[0].ep_data);
2887 allow_status_338x(ep);
2888 break;
2889
2890 case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
2891 e = get_ep_by_addr(dev, w_index);
2892 if (!e)
2893 goto do_stall3;
2894 status = readl(&e->regs->ep_rsp) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002895 BIT(CLEAR_ENDPOINT_HALT);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002896 writel(0, &dev->epregs[0].ep_irqenb);
2897 set_fifo_bytecount(ep, sizeof(status));
2898 writel((__force u32) status, &dev->epregs[0].ep_data);
2899 allow_status_338x(ep);
2900 break;
2901
2902 default:
2903 goto usb3_delegate;
2904 }
2905 break;
2906
2907 case USB_REQ_CLEAR_FEATURE:
2908 switch (r.bRequestType) {
2909 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2910 if (!dev->addressed_state) {
2911 switch (w_value) {
2912 case USB_DEVICE_U1_ENABLE:
2913 dev->u1_enable = 0;
2914 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002915 ~BIT(U1_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002916 &dev->usb_ext->usbctl2);
2917 allow_status_338x(ep);
2918 goto next_endpoints3;
2919
2920 case USB_DEVICE_U2_ENABLE:
2921 dev->u2_enable = 0;
2922 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002923 ~BIT(U2_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002924 &dev->usb_ext->usbctl2);
2925 allow_status_338x(ep);
2926 goto next_endpoints3;
2927
2928 case USB_DEVICE_LTM_ENABLE:
2929 dev->ltm_enable = 0;
2930 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002931 ~BIT(LTM_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002932 &dev->usb_ext->usbctl2);
2933 allow_status_338x(ep);
2934 goto next_endpoints3;
2935
2936 default:
2937 break;
2938 }
2939 }
2940 if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
2941 dev->wakeup_enable = 0;
2942 writel(readl(&dev->usb->usbctl) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002943 ~BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002944 &dev->usb->usbctl);
2945 allow_status_338x(ep);
2946 break;
2947 }
2948 goto usb3_delegate;
2949
2950 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
2951 e = get_ep_by_addr(dev, w_index);
2952 if (!e)
2953 goto do_stall3;
2954 if (w_value != USB_ENDPOINT_HALT)
2955 goto do_stall3;
2956 VDEBUG(dev, "%s clear halt\n", e->ep.name);
2957 ep_stall(e, false);
2958 if (!list_empty(&e->queue) && e->td_dma)
2959 restart_dma(e);
2960 allow_status(ep);
2961 ep->stopped = 1;
2962 break;
2963
2964 default:
2965 goto usb3_delegate;
2966 }
2967 break;
2968 case USB_REQ_SET_FEATURE:
2969 switch (r.bRequestType) {
2970 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2971 if (!dev->addressed_state) {
2972 switch (w_value) {
2973 case USB_DEVICE_U1_ENABLE:
2974 dev->u1_enable = 1;
2975 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002976 BIT(U1_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002977 &dev->usb_ext->usbctl2);
2978 allow_status_338x(ep);
2979 goto next_endpoints3;
2980
2981 case USB_DEVICE_U2_ENABLE:
2982 dev->u2_enable = 1;
2983 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002984 BIT(U2_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002985 &dev->usb_ext->usbctl2);
2986 allow_status_338x(ep);
2987 goto next_endpoints3;
2988
2989 case USB_DEVICE_LTM_ENABLE:
2990 dev->ltm_enable = 1;
2991 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002992 BIT(LTM_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002993 &dev->usb_ext->usbctl2);
2994 allow_status_338x(ep);
2995 goto next_endpoints3;
2996 default:
2997 break;
2998 }
2999 }
3000
3001 if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
3002 dev->wakeup_enable = 1;
3003 writel(readl(&dev->usb->usbctl) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003004 BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003005 &dev->usb->usbctl);
3006 allow_status_338x(ep);
3007 break;
3008 }
3009 goto usb3_delegate;
3010
3011 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
3012 e = get_ep_by_addr(dev, w_index);
3013 if (!e || (w_value != USB_ENDPOINT_HALT))
3014 goto do_stall3;
3015 ep_stdrsp(e, true, false);
3016 allow_status_338x(ep);
3017 break;
3018
3019 default:
3020 goto usb3_delegate;
3021 }
3022
3023 break;
3024 default:
3025
3026usb3_delegate:
3027 VDEBUG(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n",
3028 r.bRequestType, r.bRequest,
3029 w_value, w_index, w_length,
3030 readl(&ep->cfg->ep_cfg));
3031
3032 ep->responded = 0;
3033 spin_unlock(&dev->lock);
3034 tmp = dev->driver->setup(&dev->gadget, &r);
3035 spin_lock(&dev->lock);
3036 }
3037do_stall3:
3038 if (tmp < 0) {
3039 VDEBUG(dev, "req %02x.%02x protocol STALL; stat %d\n",
3040 r.bRequestType, r.bRequest, tmp);
3041 dev->protocol_stall = 1;
3042 /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */
3043 ep_stall(ep, true);
3044 }
3045
3046next_endpoints3:
3047
3048#undef w_value
3049#undef w_index
3050#undef w_length
3051
3052 return;
3053}
3054
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003055static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056{
3057 struct net2280_ep *ep;
3058 u32 num, scratch;
3059
3060 /* most of these don't need individual acks */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003061 stat &= ~BIT(INTA_ASSERTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 if (!stat)
3063 return;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003064 /* DEBUG(dev, "irqstat0 %04x\n", stat); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003065
3066 /* starting a control request? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003067 if (unlikely(stat & BIT(SETUP_PACKET_INTERRUPT))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 union {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003069 u32 raw[2];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070 struct usb_ctrlrequest r;
3071 } u;
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003072 int tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073 struct net2280_request *req;
3074
3075 if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003076 u32 val = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003077 if (val & BIT(SUPER_SPEED)) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003078 dev->gadget.speed = USB_SPEED_SUPER;
3079 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
3080 EP0_SS_MAX_PACKET_SIZE);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003081 } else if (val & BIT(HIGH_SPEED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 dev->gadget.speed = USB_SPEED_HIGH;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003083 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
3084 EP0_HS_MAX_PACKET_SIZE);
3085 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 dev->gadget.speed = USB_SPEED_FULL;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003087 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
3088 EP0_HS_MAX_PACKET_SIZE);
3089 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003090 net2280_led_speed(dev, dev->gadget.speed);
3091 DEBUG(dev, "%s\n",
3092 usb_speed_string(dev->gadget.speed));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003093 }
3094
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003095 ep = &dev->ep[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096 ep->irqs++;
3097
3098 /* make sure any leftover request state is cleared */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003099 stat &= ~BIT(ENDPOINT_0_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003100 while (!list_empty(&ep->queue)) {
3101 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 struct net2280_request, queue);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003103 done(ep, req, (req->req.actual == req->req.length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 ? 0 : -EPROTO);
3105 }
3106 ep->stopped = 0;
3107 dev->protocol_stall = 0;
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003108 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003109 ep->is_halt = 0;
3110 else{
3111 if (ep->dev->pdev->device == 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003112 tmp = BIT(FIFO_OVERFLOW) |
3113 BIT(FIFO_UNDERFLOW);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003114 else
3115 tmp = 0;
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003116
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003117 writel(tmp | BIT(TIMEOUT) |
3118 BIT(USB_STALL_SENT) |
3119 BIT(USB_IN_NAK_SENT) |
3120 BIT(USB_IN_ACK_RCVD) |
3121 BIT(USB_OUT_PING_NAK_SENT) |
3122 BIT(USB_OUT_ACK_SENT) |
3123 BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
3124 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
3125 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
3126 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
3127 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003128 BIT(DATA_IN_TOKEN_INTERRUPT),
3129 &ep->regs->ep_stat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003130 }
3131 u.raw[0] = readl(&dev->usb->setup0123);
3132 u.raw[1] = readl(&dev->usb->setup4567);
David Brownell901b3d72006-09-02 03:13:45 -07003133
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003134 cpu_to_le32s(&u.raw[0]);
3135 cpu_to_le32s(&u.raw[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003137 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003138 defect7374_workaround(dev, u.r);
3139
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003140 tmp = 0;
3141
David Brownell01ee7d72007-05-25 20:40:14 -07003142#define w_value le16_to_cpu(u.r.wValue)
3143#define w_index le16_to_cpu(u.r.wIndex)
3144#define w_length le16_to_cpu(u.r.wLength)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145
3146 /* ack the irq */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003147 writel(BIT(SETUP_PACKET_INTERRUPT), &dev->regs->irqstat0);
3148 stat ^= BIT(SETUP_PACKET_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149
3150 /* watch control traffic at the token level, and force
3151 * synchronization before letting the status stage happen.
3152 * FIXME ignore tokens we'll NAK, until driver responds.
3153 * that'll mean a lot less irqs for some drivers.
3154 */
3155 ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0;
3156 if (ep->is_in) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003157 scratch = BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
3158 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
3159 BIT(DATA_IN_TOKEN_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003160 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 } else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003162 scratch = BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
3163 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
3164 BIT(DATA_IN_TOKEN_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003165 writel(scratch, &dev->epregs[0].ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166
3167 /* we made the hardware handle most lowlevel requests;
3168 * everything else goes uplevel to the gadget code.
3169 */
Alan Stern1f26e282006-11-16 10:16:00 -05003170 ep->responded = 1;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003171
3172 if (dev->gadget.speed == USB_SPEED_SUPER) {
3173 handle_stat0_irqs_superspeed(dev, ep, u.r);
3174 goto next_endpoints;
3175 }
3176
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 switch (u.r.bRequest) {
3178 case USB_REQ_GET_STATUS: {
3179 struct net2280_ep *e;
David Brownell320f3452005-05-07 13:05:18 -07003180 __le32 status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181
3182 /* hw handles device and interface status */
3183 if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
3184 goto delegate;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003185 e = get_ep_by_addr(dev, w_index);
3186 if (!e || w_length > 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 goto do_stall;
3188
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003189 if (readl(&e->regs->ep_rsp) & BIT(SET_ENDPOINT_HALT))
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003190 status = cpu_to_le32(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003192 status = cpu_to_le32(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
3194 /* don't bother with a request object! */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003195 writel(0, &dev->epregs[0].ep_irqenb);
3196 set_fifo_bytecount(ep, w_length);
3197 writel((__force u32)status, &dev->epregs[0].ep_data);
3198 allow_status(ep);
3199 VDEBUG(dev, "%s stat %02x\n", ep->ep.name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200 goto next_endpoints;
3201 }
3202 break;
3203 case USB_REQ_CLEAR_FEATURE: {
3204 struct net2280_ep *e;
3205
3206 /* hw handles device features */
3207 if (u.r.bRequestType != USB_RECIP_ENDPOINT)
3208 goto delegate;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003209 if (w_value != USB_ENDPOINT_HALT || w_length != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003210 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003211 e = get_ep_by_addr(dev, w_index);
3212 if (!e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213 goto do_stall;
Alan Stern80661342008-08-14 15:49:11 -04003214 if (e->wedged) {
3215 VDEBUG(dev, "%s wedged, halt not cleared\n",
3216 ep->ep.name);
3217 } else {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003218 VDEBUG(dev, "%s clear halt\n", e->ep.name);
Alan Stern80661342008-08-14 15:49:11 -04003219 clear_halt(e);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003220 if (ep->dev->pdev->vendor ==
3221 PCI_VENDOR_ID_PLX &&
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003222 !list_empty(&e->queue) && e->td_dma)
3223 restart_dma(e);
Alan Stern80661342008-08-14 15:49:11 -04003224 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003225 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 goto next_endpoints;
3227 }
3228 break;
3229 case USB_REQ_SET_FEATURE: {
3230 struct net2280_ep *e;
3231
3232 /* hw handles device features */
3233 if (u.r.bRequestType != USB_RECIP_ENDPOINT)
3234 goto delegate;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003235 if (w_value != USB_ENDPOINT_HALT || w_length != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003237 e = get_ep_by_addr(dev, w_index);
3238 if (!e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239 goto do_stall;
Alan Stern80661342008-08-14 15:49:11 -04003240 if (e->ep.name == ep0name)
3241 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003242 set_halt(e);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003243 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX && e->dma)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003244 abort_dma(e);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003245 allow_status(ep);
3246 VDEBUG(dev, "%s set halt\n", ep->ep.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003247 goto next_endpoints;
3248 }
3249 break;
3250 default:
3251delegate:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003252 VDEBUG(dev, "setup %02x.%02x v%04x i%04x l%04x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07003253 "ep_cfg %08x\n",
3254 u.r.bRequestType, u.r.bRequest,
David Brownell320f3452005-05-07 13:05:18 -07003255 w_value, w_index, w_length,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003256 readl(&ep->cfg->ep_cfg));
Alan Stern1f26e282006-11-16 10:16:00 -05003257 ep->responded = 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003258 spin_unlock(&dev->lock);
3259 tmp = dev->driver->setup(&dev->gadget, &u.r);
3260 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003261 }
3262
3263 /* stall ep0 on error */
3264 if (tmp < 0) {
3265do_stall:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003266 VDEBUG(dev, "req %02x.%02x protocol STALL; stat %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003267 u.r.bRequestType, u.r.bRequest, tmp);
3268 dev->protocol_stall = 1;
3269 }
3270
3271 /* some in/out token irq should follow; maybe stall then.
3272 * driver must queue a request (even zlp) or halt ep0
3273 * before the host times out.
3274 */
3275 }
3276
David Brownell320f3452005-05-07 13:05:18 -07003277#undef w_value
3278#undef w_index
3279#undef w_length
3280
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281next_endpoints:
3282 /* endpoint data irq ? */
3283 scratch = stat & 0x7f;
3284 stat &= ~0x7f;
3285 for (num = 0; scratch; num++) {
3286 u32 t;
3287
3288 /* do this endpoint's FIFO and queue need tending? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003289 t = BIT(num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003290 if ((scratch & t) == 0)
3291 continue;
3292 scratch ^= t;
3293
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003294 ep = &dev->ep[num];
3295 handle_ep_small(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003296 }
3297
3298 if (stat)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003299 DEBUG(dev, "unhandled irqstat0 %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300}
3301
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003302#define DMA_INTERRUPTS (BIT(DMA_D_INTERRUPT) | \
3303 BIT(DMA_C_INTERRUPT) | \
3304 BIT(DMA_B_INTERRUPT) | \
3305 BIT(DMA_A_INTERRUPT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003306#define PCI_ERROR_INTERRUPTS ( \
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003307 BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT) | \
3308 BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT) | \
3309 BIT(PCI_RETRY_ABORT_INTERRUPT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003310
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003311static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312{
3313 struct net2280_ep *ep;
3314 u32 tmp, num, mask, scratch;
3315
3316 /* after disconnect there's nothing else to do! */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003317 tmp = BIT(VBUS_INTERRUPT) | BIT(ROOT_PORT_RESET_INTERRUPT);
3318 mask = BIT(SUPER_SPEED) | BIT(HIGH_SPEED) | BIT(FULL_SPEED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003319
3320 /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set.
Vitaliy Ivanovfb914eb2011-06-23 20:01:55 +03003321 * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and
David Brownell901b3d72006-09-02 03:13:45 -07003322 * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003323 * only indicates a change in the reset state).
3324 */
3325 if (stat & tmp) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003326 writel(tmp, &dev->regs->irqstat1);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003327 if ((((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
3328 (readl(&dev->usb->usbstat) & mask)) ||
3329 ((readl(&dev->usb->usbctl) &
3330 BIT(VBUS_PIN)) == 0)) &&
3331 (dev->gadget.speed != USB_SPEED_UNKNOWN)) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003332 DEBUG(dev, "disconnect %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333 dev->driver->driver.name);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003334 stop_activity(dev, dev->driver);
3335 ep0_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336 return;
3337 }
3338 stat &= ~tmp;
3339
3340 /* vBUS can bounce ... one of many reasons to ignore the
3341 * notion of hotplug events on bus connect/disconnect!
3342 */
3343 if (!stat)
3344 return;
3345 }
3346
3347 /* NOTE: chip stays in PCI D0 state for now, but it could
3348 * enter D1 to save more power
3349 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003350 tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003351 if (stat & tmp) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003352 writel(tmp, &dev->regs->irqstat1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003353 if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354 if (dev->driver->suspend)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003355 dev->driver->suspend(&dev->gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003356 if (!enable_suspend)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003357 stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 } else {
3359 if (dev->driver->resume)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003360 dev->driver->resume(&dev->gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003361 /* at high speed, note erratum 0133 */
3362 }
3363 stat &= ~tmp;
3364 }
3365
3366 /* clear any other status/irqs */
3367 if (stat)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003368 writel(stat, &dev->regs->irqstat1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003369
3370 /* some status we can just ignore */
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003371 if (dev->pdev->device == 0x2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003372 stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
3373 BIT(SUSPEND_REQUEST_INTERRUPT) |
3374 BIT(RESUME_INTERRUPT) |
3375 BIT(SOF_INTERRUPT));
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003376 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003377 stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
3378 BIT(RESUME_INTERRUPT) |
3379 BIT(SOF_DOWN_INTERRUPT) |
3380 BIT(SOF_INTERRUPT));
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003381
Linus Torvalds1da177e2005-04-16 15:20:36 -07003382 if (!stat)
3383 return;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003384 /* DEBUG(dev, "irqstat1 %08x\n", stat);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003385
3386 /* DMA status, for ep-{a,b,c,d} */
3387 scratch = stat & DMA_INTERRUPTS;
3388 stat &= ~DMA_INTERRUPTS;
3389 scratch >>= 9;
3390 for (num = 0; scratch; num++) {
3391 struct net2280_dma_regs __iomem *dma;
3392
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003393 tmp = BIT(num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003394 if ((tmp & scratch) == 0)
3395 continue;
3396 scratch ^= tmp;
3397
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003398 ep = &dev->ep[num + 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399 dma = ep->dma;
3400
3401 if (!dma)
3402 continue;
3403
3404 /* clear ep's dma status */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003405 tmp = readl(&dma->dmastat);
3406 writel(tmp, &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003407
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003408 /* dma sync*/
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003409 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003410 u32 r_dmacount = readl(&dma->dmacount);
3411 if (!ep->is_in && (r_dmacount & 0x00FFFFFF) &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003412 (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT)))
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003413 continue;
3414 }
3415
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416 /* chaining should stop on abort, short OUT from fifo,
3417 * or (stat0 codepath) short OUT transfer.
3418 */
3419 if (!use_dma_chaining) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003420 if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003421 DEBUG(ep->dev, "%s no xact done? %08x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422 ep->ep.name, tmp);
3423 continue;
3424 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003425 stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003426 }
3427
3428 /* OUT transfers terminate when the data from the
3429 * host is in our memory. Process whatever's done.
3430 * On this path, we know transfer's last packet wasn't
3431 * less than req->length. NAK_OUT_PACKETS may be set,
3432 * or the FIFO may already be holding new packets.
3433 *
3434 * IN transfers can linger in the FIFO for a very
3435 * long time ... we ignore that for now, accounting
3436 * precisely (like PIO does) needs per-packet irqs
3437 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003438 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439
3440 /* disable dma on inactive queues; else maybe restart */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003441 if (list_empty(&ep->queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442 if (use_dma_chaining)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003443 stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003445 tmp = readl(&dma->dmactl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003446 if (!use_dma_chaining || (tmp & BIT(DMA_ENABLE)) == 0)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003447 restart_dma(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003448 else if (ep->is_in && use_dma_chaining) {
3449 struct net2280_request *req;
David Brownell320f3452005-05-07 13:05:18 -07003450 __le32 dmacount;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003451
3452 /* the descriptor at the head of the chain
3453 * may still have VALID_BIT clear; that's
3454 * used to trigger changing DMA_FIFO_VALIDATE
3455 * (affects automagic zlp writes).
3456 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003457 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458 struct net2280_request, queue);
3459 dmacount = req->td->dmacount;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003460 dmacount &= cpu_to_le32(BIT(VALID_BIT) |
3461 DMA_BYTE_COUNT_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003462 if (dmacount && (dmacount & valid_bit) == 0)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003463 restart_dma(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464 }
3465 }
3466 ep->irqs++;
3467 }
3468
3469 /* NOTE: there are other PCI errors we might usefully notice.
3470 * if they appear very often, here's where to try recovering.
3471 */
3472 if (stat & PCI_ERROR_INTERRUPTS) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003473 ERROR(dev, "pci dma error; stat %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003474 stat &= ~PCI_ERROR_INTERRUPTS;
3475 /* these are fatal errors, but "maybe" they won't
3476 * happen again ...
3477 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003478 stop_activity(dev, dev->driver);
3479 ep0_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003480 stat = 0;
3481 }
3482
3483 if (stat)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003484 DEBUG(dev, "unhandled irqstat1 %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003485}
3486
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003487static irqreturn_t net2280_irq(int irq, void *_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488{
3489 struct net2280 *dev = _dev;
3490
Alan Stern658ad5e2006-04-14 16:44:11 -04003491 /* shared interrupt, not ours */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003492 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003493 (!(readl(&dev->regs->irqstat0) & BIT(INTA_ASSERTED))))
Alan Stern658ad5e2006-04-14 16:44:11 -04003494 return IRQ_NONE;
3495
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003496 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003497
3498 /* handle disconnect, dma, and more */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003499 handle_stat1_irqs(dev, readl(&dev->regs->irqstat1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500
3501 /* control requests and PIO */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003502 handle_stat0_irqs(dev, readl(&dev->regs->irqstat0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003503
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003504 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003505 /* re-enable interrupt to trigger any possible new interrupt */
3506 u32 pciirqenb1 = readl(&dev->regs->pciirqenb1);
3507 writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1);
3508 writel(pciirqenb1, &dev->regs->pciirqenb1);
3509 }
3510
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003511 spin_unlock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512
3513 return IRQ_HANDLED;
3514}
3515
3516/*-------------------------------------------------------------------------*/
3517
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003518static void gadget_release(struct device *_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003519{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003520 struct net2280 *dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003521
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003522 kfree(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003523}
3524
3525/* tear down the binding between this driver and the pci device */
3526
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003527static void net2280_remove(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003528{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003529 struct net2280 *dev = pci_get_drvdata(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003530
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003531 usb_del_gadget_udc(&dev->gadget);
3532
David Brownell6bea4762006-12-05 03:15:33 -08003533 BUG_ON(dev->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003534
3535 /* then clean up the resources we allocated during probe() */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003536 net2280_led_shutdown(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003537 if (dev->requests) {
3538 int i;
3539 for (i = 1; i < 5; i++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003540 if (!dev->ep[i].dummy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541 continue;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003542 pci_pool_free(dev->requests, dev->ep[i].dummy,
3543 dev->ep[i].td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003544 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003545 pci_pool_destroy(dev->requests);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003546 }
3547 if (dev->got_irq)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003548 free_irq(pdev->irq, dev);
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003549 if (use_msi && dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003550 pci_disable_msi(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003551 if (dev->regs)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003552 iounmap(dev->regs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003553 if (dev->region)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003554 release_mem_region(pci_resource_start(pdev, 0),
3555 pci_resource_len(pdev, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003556 if (dev->enabled)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003557 pci_disable_device(pdev);
3558 device_remove_file(&pdev->dev, &dev_attr_registers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003559
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003560 INFO(dev, "unbind\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561}
3562
3563/* wrap this driver around the specified device, but
3564 * don't respond over USB until a gadget driver binds to us.
3565 */
3566
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003567static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568{
3569 struct net2280 *dev;
3570 unsigned long resource, len;
3571 void __iomem *base = NULL;
3572 int retval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003573
Ricardo Ribalda Delgado9a028e42014-05-20 18:30:07 +02003574 if (!use_dma)
3575 use_dma_chaining = 0;
3576
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577 /* alloc, and start init */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003578 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
3579 if (dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003580 retval = -ENOMEM;
3581 goto done;
3582 }
3583
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003584 pci_set_drvdata(pdev, dev);
3585 spin_lock_init(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003586 dev->pdev = pdev;
3587 dev->gadget.ops = &net2280_ops;
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003588 dev->gadget.max_speed = (dev->pdev->vendor == PCI_VENDOR_ID_PLX) ?
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003589 USB_SPEED_SUPER : USB_SPEED_HIGH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003590
3591 /* the "gadget" abstracts/virtualizes the controller */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003592 dev->gadget.name = driver_name;
3593
3594 /* now all the pci goodies ... */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003595 if (pci_enable_device(pdev) < 0) {
3596 retval = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003597 goto done;
3598 }
3599 dev->enabled = 1;
3600
3601 /* BAR 0 holds all the registers
3602 * BAR 1 is 8051 memory; unused here (note erratum 0103)
3603 * BAR 2 is fifo memory; unused here
3604 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003605 resource = pci_resource_start(pdev, 0);
3606 len = pci_resource_len(pdev, 0);
3607 if (!request_mem_region(resource, len, driver_name)) {
3608 DEBUG(dev, "controller already in use\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003609 retval = -EBUSY;
3610 goto done;
3611 }
3612 dev->region = 1;
3613
David Brownell901b3d72006-09-02 03:13:45 -07003614 /* FIXME provide firmware download interface to put
3615 * 8051 code into the chip, e.g. to turn on PCI PM.
3616 */
3617
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003618 base = ioremap_nocache(resource, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619 if (base == NULL) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003620 DEBUG(dev, "can't map memory\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003621 retval = -EFAULT;
3622 goto done;
3623 }
3624 dev->regs = (struct net2280_regs __iomem *) base;
3625 dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080);
3626 dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100);
3627 dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180);
3628 dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200);
3629 dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300);
3630
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003631 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003632 u32 fsmvalue;
3633 u32 usbstat;
3634 dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *)
3635 (base + 0x00b4);
3636 dev->fiforegs = (struct usb338x_fifo_regs __iomem *)
3637 (base + 0x0500);
3638 dev->llregs = (struct usb338x_ll_regs __iomem *)
3639 (base + 0x0700);
3640 dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *)
3641 (base + 0x0748);
3642 dev->ll_tsn_regs = (struct usb338x_ll_tsn_regs __iomem *)
3643 (base + 0x077c);
3644 dev->ll_chicken_reg = (struct usb338x_ll_chi_regs __iomem *)
3645 (base + 0x079c);
3646 dev->plregs = (struct usb338x_pl_regs __iomem *)
3647 (base + 0x0800);
3648 usbstat = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003649 dev->enhanced_mode = !!(usbstat & BIT(11));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003650 dev->n_ep = (dev->enhanced_mode) ? 9 : 5;
3651 /* put into initial config, link up all endpoints */
3652 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
3653 (0xf << DEFECT7374_FSM_FIELD);
3654 /* See if firmware needs to set up for workaround: */
3655 if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ)
3656 writel(0, &dev->usb->usbctl);
3657 } else{
3658 dev->enhanced_mode = 0;
3659 dev->n_ep = 7;
3660 /* put into initial config, link up all endpoints */
3661 writel(0, &dev->usb->usbctl);
3662 }
3663
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003664 usb_reset(dev);
3665 usb_reinit(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003666
3667 /* irq setup after old hardware is cleaned up */
3668 if (!pdev->irq) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003669 ERROR(dev, "No IRQ. Check PCI setup!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670 retval = -ENODEV;
3671 goto done;
3672 }
David S. Millerc6387a42006-06-20 01:21:29 -07003673
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003674 if (use_msi && dev->pdev->vendor == PCI_VENDOR_ID_PLX)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003675 if (pci_enable_msi(pdev))
3676 ERROR(dev, "Failed to enable MSI mode\n");
3677
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003678 if (request_irq(pdev->irq, net2280_irq, IRQF_SHARED,
3679 driver_name, dev)) {
3680 ERROR(dev, "request interrupt %d failed\n", pdev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681 retval = -EBUSY;
3682 goto done;
3683 }
3684 dev->got_irq = 1;
3685
3686 /* DMA setup */
3687 /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003688 dev->requests = pci_pool_create("requests", pdev,
3689 sizeof(struct net2280_dma),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003690 0 /* no alignment requirements */,
3691 0 /* or page-crossing issues */);
3692 if (!dev->requests) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003693 DEBUG(dev, "can't get request pool\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694 retval = -ENOMEM;
3695 goto done;
3696 }
3697 for (i = 1; i < 5; i++) {
3698 struct net2280_dma *td;
3699
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003700 td = pci_pool_alloc(dev->requests, GFP_KERNEL,
3701 &dev->ep[i].td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702 if (!td) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003703 DEBUG(dev, "can't get dummy %d\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 retval = -ENOMEM;
3705 goto done;
3706 }
3707 td->dmacount = 0; /* not VALID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003708 td->dmadesc = td->dmaaddr;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003709 dev->ep[i].dummy = td;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003710 }
3711
3712 /* enable lower-overhead pci memory bursts during DMA */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003713 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003714 writel(BIT(DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) |
3715 /*
3716 * 256 write retries may not be enough...
3717 BIT(PCI_RETRY_ABORT_ENABLE) |
3718 */
3719 BIT(DMA_READ_MULTIPLE_ENABLE) |
3720 BIT(DMA_READ_LINE_ENABLE),
3721 &dev->pci->pcimstctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003722 /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003723 pci_set_master(pdev);
3724 pci_try_set_mwi(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003725
3726 /* ... also flushes any posted pci writes */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003727 dev->chiprev = get_idx_reg(dev->regs, REG_CHIPREV) & 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003728
3729 /* done */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003730 INFO(dev, "%s\n", driver_desc);
3731 INFO(dev, "irq %d, pci mem %p, chip rev %04x\n",
David S. Millerc6387a42006-06-20 01:21:29 -07003732 pdev->irq, base, dev->chiprev);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003733 INFO(dev, "version: " DRIVER_VERSION "; dma %s %s\n",
3734 use_dma ? (use_dma_chaining ? "chaining" : "enabled")
3735 : "disabled",
3736 dev->enhanced_mode ? "enhanced mode" : "legacy mode");
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003737 retval = device_create_file(&pdev->dev, &dev_attr_registers);
3738 if (retval)
3739 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003740
Felipe Balbi2901df62013-02-26 15:15:27 +02003741 retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget,
3742 gadget_release);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003743 if (retval)
3744 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 return 0;
3746
3747done:
3748 if (dev)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003749 net2280_remove(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003750 return retval;
3751}
3752
Alan Stern2d61bde2006-05-05 16:23:42 -04003753/* make sure the board is quiescent; otherwise it will continue
3754 * generating IRQs across the upcoming reboot.
3755 */
3756
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003757static void net2280_shutdown(struct pci_dev *pdev)
Alan Stern2d61bde2006-05-05 16:23:42 -04003758{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003759 struct net2280 *dev = pci_get_drvdata(pdev);
Alan Stern2d61bde2006-05-05 16:23:42 -04003760
3761 /* disable IRQs */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003762 writel(0, &dev->regs->pciirqenb0);
3763 writel(0, &dev->regs->pciirqenb1);
Alan Stern2d61bde2006-05-05 16:23:42 -04003764
3765 /* disable the pullup so the host will think we're gone */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003766 writel(0, &dev->usb->usbctl);
Alan Stern2f076072013-01-30 16:40:14 -05003767
3768 /* Disable full-speed test mode */
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003769 if (dev->pdev->vendor == PCI_VENDOR_ID_PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003770 writel(0, &dev->usb->xcvrdiag);
Alan Stern2d61bde2006-05-05 16:23:42 -04003771}
3772
Linus Torvalds1da177e2005-04-16 15:20:36 -07003773
3774/*-------------------------------------------------------------------------*/
3775
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003776static const struct pci_device_id pci_ids[] = { {
David Brownell901b3d72006-09-02 03:13:45 -07003777 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3778 .class_mask = ~0,
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003779 .vendor = PCI_VENDOR_ID_PLX_LEGACY,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003780 .device = 0x2280,
3781 .subvendor = PCI_ANY_ID,
3782 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003783 }, {
David Brownell901b3d72006-09-02 03:13:45 -07003784 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3785 .class_mask = ~0,
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003786 .vendor = PCI_VENDOR_ID_PLX_LEGACY,
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003787 .device = 0x2282,
3788 .subvendor = PCI_ANY_ID,
3789 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003790 },
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003791 {
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003792 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3793 .class_mask = ~0,
3794 .vendor = PCI_VENDOR_ID_PLX,
3795 .device = 0x3380,
3796 .subvendor = PCI_ANY_ID,
3797 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003798 },
3799 {
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003800 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3801 .class_mask = ~0,
3802 .vendor = PCI_VENDOR_ID_PLX,
3803 .device = 0x3382,
3804 .subvendor = PCI_ANY_ID,
3805 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003806 },
3807{ /* end: all zeroes */ }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003808};
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003809MODULE_DEVICE_TABLE(pci, pci_ids);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003810
3811/* pci driver glue; this is a "new style" PCI driver module */
3812static struct pci_driver net2280_pci_driver = {
3813 .name = (char *) driver_name,
3814 .id_table = pci_ids,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003815
3816 .probe = net2280_probe,
3817 .remove = net2280_remove,
Alan Stern2d61bde2006-05-05 16:23:42 -04003818 .shutdown = net2280_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003819
3820 /* FIXME add power management support */
3821};
3822
Ricardo Ribalda Delgado9a028e42014-05-20 18:30:07 +02003823module_pci_driver(net2280_pci_driver);
3824
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003825MODULE_DESCRIPTION(DRIVER_DESC);
3826MODULE_AUTHOR("David Brownell");
3827MODULE_LICENSE("GPL");