blob: 08c16ee092f275ad89e5b58f45f650f9aa8effc2 [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 *
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +010015 * DMA is enabled by default.
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 *
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020017 * MSI is enabled by default. The legacy IRQ is used if MSI couldn't
18 * be enabled.
19 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 * Note that almost all the errata workarounds here are only needed for
21 * rev1 chips. Rev1a silicon (0110) fixes almost all of them.
22 */
23
24/*
25 * Copyright (C) 2003 David Brownell
26 * Copyright (C) 2003-2005 PLX Technology, Inc.
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020027 * Copyright (C) 2014 Ricardo Ribalda - Qtechnology/AS
Linus Torvalds1da177e2005-04-16 15:20:36 -070028 *
David Brownell901b3d72006-09-02 03:13:45 -070029 * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility
30 * with 2282 chip
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +010031 *
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020032 * Modified Ricardo Ribalda Qtechnology AS to provide compatibility
33 * with usb 338x chip. Based on PLX driver
34 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 * This program is free software; you can redistribute it and/or modify
36 * it under the terms of the GNU General Public License as published by
37 * the Free Software Foundation; either version 2 of the License, or
38 * (at your option) any later version.
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 */
40
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#include <linux/module.h>
42#include <linux/pci.h>
David Brownell682d4c82006-01-18 23:55:08 -080043#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <linux/kernel.h>
45#include <linux/delay.h>
46#include <linux/ioport.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <linux/errno.h>
49#include <linux/init.h>
50#include <linux/timer.h>
51#include <linux/list.h>
52#include <linux/interrupt.h>
53#include <linux/moduleparam.h>
54#include <linux/device.h>
David Brownell5f848132006-12-16 15:34:53 -080055#include <linux/usb/ch9.h>
David Brownell9454a572007-10-04 18:05:17 -070056#include <linux/usb/gadget.h>
Bryan Wub38b03b2011-06-02 12:51:29 +080057#include <linux/prefetch.h>
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020058#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60#include <asm/byteorder.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070061#include <asm/irq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070062#include <asm/unaligned.h>
63
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020064#define DRIVER_DESC "PLX NET228x/USB338x USB Peripheral Controller"
65#define DRIVER_VERSION "2005 Sept 27/v3.0"
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
Linus Torvalds1da177e2005-04-16 15:20:36 -070067#define EP_DONTUSE 13 /* nonzero */
68
69#define USE_RDK_LEDS /* GPIO pins control three LEDs */
70
71
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020072static const char driver_name[] = "net2280";
73static const char driver_desc[] = DRIVER_DESC;
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020075static const u32 ep_bit[9] = { 0, 17, 2, 19, 4, 1, 18, 3, 20 };
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +020076static const char ep0name[] = "ep0";
77static const char *const ep_name[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 ep0name,
79 "ep-a", "ep-b", "ep-c", "ep-d",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +020080 "ep-e", "ep-f", "ep-g", "ep-h",
Linus Torvalds1da177e2005-04-16 15:20:36 -070081};
82
83/* use_dma -- general goodness, fewer interrupts, less cpu load (vs PIO)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 *
85 * The net2280 DMA engines are not tightly integrated with their FIFOs;
86 * not all cases are (yet) handled well in this driver or the silicon.
87 * Some gadget drivers work better with the dma support here than others.
88 * These two parameters let you use PIO or more aggressive DMA.
89 */
Ricardo Ribalda Delgado00d4db02014-05-20 18:30:06 +020090static bool use_dma = true;
Ricardo Ribalda Delgado00d4db02014-05-20 18:30:06 +020091static bool use_msi = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93/* "modprobe net2280 use_dma=n" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +020094module_param(use_dma, bool, 0444);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +020095module_param(use_msi, bool, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97/* mode 0 == ep-{a,b,c,d} 1K fifo each
98 * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
99 * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable
100 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200101static ushort fifo_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103/* "modprobe net2280 fifo_mode=1" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200104module_param(fifo_mode, ushort, 0644);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106/* enable_suspend -- When enabled, the driver will respond to
107 * USB suspend requests by powering down the NET2280. Otherwise,
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300108 * USB suspend requests will be ignored. This is acceptable for
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100109 * self-powered devices
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 */
Ricardo Ribalda Delgado00d4db02014-05-20 18:30:06 +0200111static bool enable_suspend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
113/* "modprobe net2280 enable_suspend=1" etc */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200114module_param(enable_suspend, bool, 0444);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Alan Stern2f076072013-01-30 16:40:14 -0500116/* force full-speed operation */
117static bool full_speed;
118module_param(full_speed, bool, 0444);
119MODULE_PARM_DESC(full_speed, "force full-speed mode -- for testing only!");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
121#define DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
122
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200123static char *type_string(u8 bmAttributes)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124{
125 switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
126 case USB_ENDPOINT_XFER_BULK: return "bulk";
127 case USB_ENDPOINT_XFER_ISOC: return "iso";
128 case USB_ENDPOINT_XFER_INT: return "intr";
Joe Perches2b84f922013-10-08 16:01:37 -0700129 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 return "control";
131}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133#include "net2280.h"
134
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200135#define valid_bit cpu_to_le32(BIT(VALID_BIT))
136#define dma_done_ie cpu_to_le32(BIT(DMA_DONE_INTERRUPT_ENABLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
138/*-------------------------------------------------------------------------*/
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200139static inline void enable_pciirqenb(struct net2280_ep *ep)
140{
141 u32 tmp = readl(&ep->dev->regs->pciirqenb0);
142
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200143 if (ep->dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200144 tmp |= BIT(ep->num);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200145 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200146 tmp |= BIT(ep_bit[ep->num]);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200147 writel(tmp, &ep->dev->regs->pciirqenb0);
148
149 return;
150}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152static int
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200153net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154{
155 struct net2280 *dev;
156 struct net2280_ep *ep;
157 u32 max, tmp;
158 unsigned long flags;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200159 static const u32 ep_key[9] = { 1, 0, 1, 0, 1, 1, 0, 1, 0 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200161 ep = container_of(_ep, struct net2280_ep, ep);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200162 if (!_ep || !desc || ep->desc || _ep->name == ep0name ||
163 desc->bDescriptorType != USB_DT_ENDPOINT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 return -EINVAL;
165 dev = ep->dev;
166 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
167 return -ESHUTDOWN;
168
169 /* erratum 0119 workaround ties up an endpoint number */
170 if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE)
171 return -EDOM;
172
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200173 if (dev->quirks & PLX_SUPERSPEED) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200174 if ((desc->bEndpointAddress & 0x0f) >= 0x0c)
175 return -EDOM;
176 ep->is_in = !!usb_endpoint_dir_in(desc);
177 if (dev->enhanced_mode && ep->is_in && ep_key[ep->num])
178 return -EINVAL;
179 }
180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 /* sanity check ep-e/ep-f since their fifos are small */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200182 max = usb_endpoint_maxp(desc) & 0x1fff;
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200183 if (ep->num > 4 && max > 64 && (dev->quirks & PLX_LEGACY))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 return -ERANGE;
185
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200186 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 _ep->maxpacket = max & 0x7ff;
188 ep->desc = desc;
189
190 /* ep_reset() has already been called */
191 ep->stopped = 0;
Alan Stern80661342008-08-14 15:49:11 -0400192 ep->wedged = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 ep->out_overflow = 0;
194
195 /* set speed-dependent max packet; may kick in high bandwidth */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200196 set_max_speed(ep, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 /* set type, direction, address; reset fifo counters */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200199 writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
201 if (tmp == USB_ENDPOINT_XFER_INT) {
202 /* erratum 0105 workaround prevents hs NYET */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200203 if (dev->chiprev == 0100 &&
204 dev->gadget.speed == USB_SPEED_HIGH &&
205 !(desc->bEndpointAddress & USB_DIR_IN))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200206 writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 &ep->regs->ep_rsp);
208 } else if (tmp == USB_ENDPOINT_XFER_BULK) {
209 /* catch some particularly blatant driver bugs */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200210 if ((dev->gadget.speed == USB_SPEED_SUPER && max != 1024) ||
211 (dev->gadget.speed == USB_SPEED_HIGH && max != 512) ||
212 (dev->gadget.speed == USB_SPEED_FULL && max > 64)) {
213 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 return -ERANGE;
215 }
216 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200217 ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200218 /* Enable this endpoint */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200219 if (dev->quirks & PLX_LEGACY) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200220 tmp <<= ENDPOINT_TYPE;
221 tmp |= desc->bEndpointAddress;
222 /* default full fifo lines */
223 tmp |= (4 << ENDPOINT_BYTE_COUNT);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200224 tmp |= BIT(ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200225 ep->is_in = (tmp & USB_DIR_IN) != 0;
226 } else {
227 /* In Legacy mode, only OUT endpoints are used */
228 if (dev->enhanced_mode && ep->is_in) {
229 tmp <<= IN_ENDPOINT_TYPE;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200230 tmp |= BIT(IN_ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200231 /* Not applicable to Legacy */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200232 tmp |= BIT(ENDPOINT_DIRECTION);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200233 } else {
234 tmp <<= OUT_ENDPOINT_TYPE;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200235 tmp |= BIT(OUT_ENDPOINT_ENABLE);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200236 tmp |= (ep->is_in << ENDPOINT_DIRECTION);
237 }
238
239 tmp |= usb_endpoint_num(desc);
240 tmp |= (ep->ep.maxburst << MAX_BURST_SIZE);
241 }
242
243 /* Make sure all the registers are written before ep_rsp*/
244 wmb();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
246 /* for OUT transfers, block the rx fifo until a read is posted */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 if (!ep->is_in)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200248 writel(BIT(SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200249 else if (!(dev->quirks & PLX_2280)) {
David Brownell901b3d72006-09-02 03:13:45 -0700250 /* Added for 2282, Don't use nak packets on an in endpoint,
251 * this was ignored on 2280
252 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200253 writel(BIT(CLEAR_NAK_OUT_PACKETS) |
254 BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200257 writel(tmp, &ep->cfg->ep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258
259 /* enable irqs */
260 if (!ep->dma) { /* pio, per-packet */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200261 enable_pciirqenb(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200263 tmp = BIT(DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) |
264 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200265 if (dev->quirks & PLX_2280)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200266 tmp |= readl(&ep->regs->ep_irqenb);
267 writel(tmp, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 } else { /* dma, per-request */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200269 tmp = BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200270 tmp |= readl(&dev->regs->pciirqenb1);
271 writel(tmp, &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
273 /* for short OUT transfers, dma completions can't
274 * advance the queue; do it pio-style, by hand.
275 * NOTE erratum 0112 workaround #2
276 */
277 if ((desc->bEndpointAddress & USB_DIR_IN) == 0) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200278 tmp = BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200279 writel(tmp, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200281 enable_pciirqenb(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 }
283 }
284
285 tmp = desc->bEndpointAddress;
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200286 ep_dbg(dev, "enabled %s (ep%d%s-%s) %s max %04x\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200287 _ep->name, tmp & 0x0f, DIR_STRING(tmp),
288 type_string(desc->bmAttributes),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 ep->dma ? "dma" : "pio", max);
290
291 /* pci writes may still be posted */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200292 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 return 0;
294}
295
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200296static int handshake(u32 __iomem *ptr, u32 mask, u32 done, int usec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297{
298 u32 result;
299
300 do {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200301 result = readl(ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 if (result == ~(u32)0) /* "device unplugged" */
303 return -ENODEV;
304 result &= mask;
305 if (result == done)
306 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200307 udelay(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 usec--;
309 } while (usec > 0);
310 return -ETIMEDOUT;
311}
312
David Brownell901b3d72006-09-02 03:13:45 -0700313static const struct usb_ep_ops net2280_ep_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200315static void ep_reset_228x(struct net2280_regs __iomem *regs,
316 struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317{
318 u32 tmp;
319
320 ep->desc = NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200321 INIT_LIST_HEAD(&ep->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
Robert Baldygae117e742013-12-13 12:23:38 +0100323 usb_ep_set_maxpacket_limit(&ep->ep, ~0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 ep->ep.ops = &net2280_ep_ops;
325
326 /* disable the dma, irqs, endpoint... */
327 if (ep->dma) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200328 writel(0, &ep->dma->dmactl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200329 writel(BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
330 BIT(DMA_TRANSACTION_DONE_INTERRUPT) |
331 BIT(DMA_ABORT),
332 &ep->dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200334 tmp = readl(&regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200335 tmp &= ~BIT(ep->num);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200336 writel(tmp, &regs->pciirqenb0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200338 tmp = readl(&regs->pciirqenb1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200339 tmp &= ~BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200340 writel(tmp, &regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200342 writel(0, &ep->regs->ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
344 /* init to our chosen defaults, notably so that we NAK OUT
345 * packets until the driver queues a read (+note erratum 0112)
346 */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200347 if (!ep->is_in || (ep->dev->quirks & PLX_2280)) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200348 tmp = BIT(SET_NAK_OUT_PACKETS_MODE) |
349 BIT(SET_NAK_OUT_PACKETS) |
350 BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
351 BIT(CLEAR_INTERRUPT_MODE);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100352 } else {
353 /* added for 2282 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200354 tmp = BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
355 BIT(CLEAR_NAK_OUT_PACKETS) |
356 BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
357 BIT(CLEAR_INTERRUPT_MODE);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100358 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359
360 if (ep->num != 0) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200361 tmp |= BIT(CLEAR_ENDPOINT_TOGGLE) |
362 BIT(CLEAR_ENDPOINT_HALT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200364 writel(tmp, &ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366 /* scrub most status bits, and flush any fifo state */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200367 if (ep->dev->quirks & PLX_2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200368 tmp = BIT(FIFO_OVERFLOW) |
369 BIT(FIFO_UNDERFLOW);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100370 else
371 tmp = 0;
372
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200373 writel(tmp | BIT(TIMEOUT) |
374 BIT(USB_STALL_SENT) |
375 BIT(USB_IN_NAK_SENT) |
376 BIT(USB_IN_ACK_RCVD) |
377 BIT(USB_OUT_PING_NAK_SENT) |
378 BIT(USB_OUT_ACK_SENT) |
379 BIT(FIFO_FLUSH) |
380 BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
381 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
382 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
383 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
384 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200385 BIT(DATA_IN_TOKEN_INTERRUPT),
386 &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387
388 /* fifo size is handled separately */
389}
390
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200391static void ep_reset_338x(struct net2280_regs __iomem *regs,
392 struct net2280_ep *ep)
393{
394 u32 tmp, dmastat;
395
396 ep->desc = NULL;
397 INIT_LIST_HEAD(&ep->queue);
398
399 usb_ep_set_maxpacket_limit(&ep->ep, ~0);
400 ep->ep.ops = &net2280_ep_ops;
401
402 /* disable the dma, irqs, endpoint... */
403 if (ep->dma) {
404 writel(0, &ep->dma->dmactl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200405 writel(BIT(DMA_ABORT_DONE_INTERRUPT) |
406 BIT(DMA_PAUSE_DONE_INTERRUPT) |
407 BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200408 BIT(DMA_TRANSACTION_DONE_INTERRUPT),
409 /* | BIT(DMA_ABORT), */
410 &ep->dma->dmastat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200411
412 dmastat = readl(&ep->dma->dmastat);
413 if (dmastat == 0x5002) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200414 ep_warn(ep->dev, "The dmastat return = %x!!\n",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200415 dmastat);
416 writel(0x5a, &ep->dma->dmastat);
417 }
418
419 tmp = readl(&regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200420 tmp &= ~BIT(ep_bit[ep->num]);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200421 writel(tmp, &regs->pciirqenb0);
422 } else {
423 if (ep->num < 5) {
424 tmp = readl(&regs->pciirqenb1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200425 tmp &= ~BIT((8 + ep->num)); /* completion */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200426 writel(tmp, &regs->pciirqenb1);
427 }
428 }
429 writel(0, &ep->regs->ep_irqenb);
430
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200431 writel(BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
432 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
433 BIT(FIFO_OVERFLOW) |
434 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
435 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
436 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
437 BIT(DATA_IN_TOKEN_INTERRUPT), &ep->regs->ep_stat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200438}
439
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200440static void nuke(struct net2280_ep *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200442static int net2280_disable(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
444 struct net2280_ep *ep;
445 unsigned long flags;
446
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200447 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 if (!_ep || !ep->desc || _ep->name == ep0name)
449 return -EINVAL;
450
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200451 spin_lock_irqsave(&ep->dev->lock, flags);
452 nuke(ep);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200453
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200454 if (ep->dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200455 ep_reset_338x(ep->dev->regs, ep);
456 else
457 ep_reset_228x(ep->dev->regs, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200459 ep_vdbg(ep->dev, "disabled %s %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 ep->dma ? "dma" : "pio", _ep->name);
461
462 /* synch memory views with the device */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200463 (void)readl(&ep->cfg->ep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464
465 if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200466 ep->dma = &ep->dev->dma[ep->num - 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200468 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 return 0;
470}
471
472/*-------------------------------------------------------------------------*/
473
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200474static struct usb_request
475*net2280_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476{
477 struct net2280_ep *ep;
478 struct net2280_request *req;
479
480 if (!_ep)
481 return NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200482 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
Eric Sesterhenn7039f422006-02-27 13:34:10 -0800484 req = kzalloc(sizeof(*req), gfp_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 if (!req)
486 return NULL;
487
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200488 INIT_LIST_HEAD(&req->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
490 /* this dma descriptor may be swapped with the previous dummy */
491 if (ep->dma) {
492 struct net2280_dma *td;
493
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200494 td = pci_pool_alloc(ep->dev->requests, gfp_flags,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 &req->td_dma);
496 if (!td) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200497 kfree(req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 return NULL;
499 }
500 td->dmacount = 0; /* not VALID */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 td->dmadesc = td->dmaaddr;
502 req->td = td;
503 }
504 return &req->req;
505}
506
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200507static void net2280_free_request(struct usb_ep *_ep, struct usb_request *_req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508{
509 struct net2280_ep *ep;
510 struct net2280_request *req;
511
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200512 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 if (!_ep || !_req)
514 return;
515
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200516 req = container_of(_req, struct net2280_request, req);
517 WARN_ON(!list_empty(&req->queue));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 if (req->td)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200519 pci_pool_free(ep->dev->requests, req->td, req->td_dma);
520 kfree(req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521}
522
523/*-------------------------------------------------------------------------*/
524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525/* load a packet into the fifo we use for usb IN transfers.
526 * works for all endpoints.
527 *
528 * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo
529 * at a time, but this code is simpler because it knows it only writes
530 * one packet. ep-a..ep-d should use dma instead.
531 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200532static void write_fifo(struct net2280_ep *ep, struct usb_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533{
534 struct net2280_ep_regs __iomem *regs = ep->regs;
535 u8 *buf;
536 u32 tmp;
537 unsigned count, total;
538
539 /* INVARIANT: fifo is currently empty. (testable) */
540
541 if (req) {
542 buf = req->buf + req->actual;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200543 prefetch(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 total = req->length - req->actual;
545 } else {
546 total = 0;
547 buf = NULL;
548 }
549
550 /* write just one packet at a time */
551 count = ep->ep.maxpacket;
552 if (count > total) /* min() cannot be used on a bitfield */
553 count = total;
554
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200555 ep_vdbg(ep->dev, "write %s fifo (IN) %d bytes%s req %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 ep->ep.name, count,
557 (count != ep->ep.maxpacket) ? " (short)" : "",
558 req);
559 while (count >= 4) {
560 /* NOTE be careful if you try to align these. fifo lines
561 * should normally be full (4 bytes) and successive partial
562 * lines are ok only in certain cases.
563 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200564 tmp = get_unaligned((u32 *)buf);
565 cpu_to_le32s(&tmp);
566 writel(tmp, &regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 buf += 4;
568 count -= 4;
569 }
570
571 /* last fifo entry is "short" unless we wrote a full packet.
572 * also explicitly validate last word in (periodic) transfers
573 * when maxpacket is not a multiple of 4 bytes.
574 */
575 if (count || total < ep->ep.maxpacket) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200576 tmp = count ? get_unaligned((u32 *)buf) : count;
577 cpu_to_le32s(&tmp);
578 set_fifo_bytecount(ep, count & 0x03);
579 writel(tmp, &regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 }
581
582 /* pci writes may still be posted */
583}
584
585/* work around erratum 0106: PCI and USB race over the OUT fifo.
586 * caller guarantees chiprev 0100, out endpoint is NAKing, and
587 * there's no real data in the fifo.
588 *
589 * NOTE: also used in cases where that erratum doesn't apply:
590 * where the host wrote "too much" data to us.
591 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200592static void out_flush(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593{
594 u32 __iomem *statp;
595 u32 tmp;
596
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200597 ASSERT_OUT_NAKING(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 statp = &ep->regs->ep_stat;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200600 writel(BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200601 BIT(DATA_PACKET_RECEIVED_INTERRUPT),
602 statp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200603 writel(BIT(FIFO_FLUSH), statp);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200604 /* Make sure that stap is written */
605 mb();
606 tmp = readl(statp);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200607 if (tmp & BIT(DATA_OUT_PING_TOKEN_INTERRUPT) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 /* high speed did bulk NYET; fifo isn't filling */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200609 ep->dev->gadget.speed == USB_SPEED_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 unsigned usec;
611
612 usec = 50; /* 64 byte bulk/interrupt */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200613 handshake(statp, BIT(USB_OUT_PING_NAK_SENT),
614 BIT(USB_OUT_PING_NAK_SENT), usec);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 /* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */
616 }
617}
618
619/* unload packet(s) from the fifo we use for usb OUT transfers.
620 * returns true iff the request completed, because of short packet
621 * or the request buffer having filled with full packets.
622 *
623 * for ep-a..ep-d this will read multiple packets out when they
624 * have been accepted.
625 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200626static int read_fifo(struct net2280_ep *ep, struct net2280_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627{
628 struct net2280_ep_regs __iomem *regs = ep->regs;
629 u8 *buf = req->req.buf + req->req.actual;
630 unsigned count, tmp, is_short;
631 unsigned cleanup = 0, prevent = 0;
632
633 /* erratum 0106 ... packets coming in during fifo reads might
634 * be incompletely rejected. not all cases have workarounds.
635 */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200636 if (ep->dev->chiprev == 0x0100 &&
637 ep->dev->gadget.speed == USB_SPEED_FULL) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200638 udelay(1);
639 tmp = readl(&ep->regs->ep_stat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200640 if ((tmp & BIT(NAK_OUT_PACKETS)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 cleanup = 1;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200642 else if ((tmp & BIT(FIFO_FULL))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200643 start_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 prevent = 1;
645 }
646 /* else: hope we don't see the problem */
647 }
648
649 /* never overflow the rx buffer. the fifo reads packets until
650 * it sees a short one; we might not be ready for them all.
651 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200652 prefetchw(buf);
653 count = readl(&regs->ep_avail);
654 if (unlikely(count == 0)) {
655 udelay(1);
656 tmp = readl(&ep->regs->ep_stat);
657 count = readl(&regs->ep_avail);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 /* handled that data already? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200659 if (count == 0 && (tmp & BIT(NAK_OUT_PACKETS)) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 return 0;
661 }
662
663 tmp = req->req.length - req->req.actual;
664 if (count > tmp) {
665 /* as with DMA, data overflow gets flushed */
666 if ((tmp % ep->ep.maxpacket) != 0) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200667 ep_err(ep->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 "%s out fifo %d bytes, expected %d\n",
669 ep->ep.name, count, tmp);
670 req->req.status = -EOVERFLOW;
671 cleanup = 1;
672 /* NAK_OUT_PACKETS will be set, so flushing is safe;
673 * the next read will start with the next packet
674 */
675 } /* else it's a ZLP, no worries */
676 count = tmp;
677 }
678 req->req.actual += count;
679
680 is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0);
681
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200682 ep_vdbg(ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 ep->ep.name, count, is_short ? " (short)" : "",
684 cleanup ? " flush" : "", prevent ? " nak" : "",
685 req, req->req.actual, req->req.length);
686
687 while (count >= 4) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200688 tmp = readl(&regs->ep_data);
689 cpu_to_le32s(&tmp);
690 put_unaligned(tmp, (u32 *)buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 buf += 4;
692 count -= 4;
693 }
694 if (count) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200695 tmp = readl(&regs->ep_data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 /* LE conversion is implicit here: */
697 do {
698 *buf++ = (u8) tmp;
699 tmp >>= 8;
700 } while (--count);
701 }
702 if (cleanup)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200703 out_flush(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 if (prevent) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200705 writel(BIT(CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200706 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 }
708
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200709 return is_short || ((req->req.actual == req->req.length) &&
710 !req->req.zero);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711}
712
713/* fill out dma descriptor to match a given request */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200714static void fill_dma_desc(struct net2280_ep *ep,
715 struct net2280_request *req, int valid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716{
717 struct net2280_dma *td = req->td;
718 u32 dmacount = req->req.length;
719
720 /* don't let DMA continue after a short OUT packet,
721 * so overruns can't affect the next transfer.
722 * in case of overruns on max-size packets, we can't
723 * stop the fifo from filling but we can flush it.
724 */
725 if (ep->is_in)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200726 dmacount |= BIT(DMA_DIRECTION);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200727 if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) ||
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200728 !(ep->dev->quirks & PLX_2280))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200729 dmacount |= BIT(END_OF_CHAIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 req->valid = valid;
732 if (valid)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200733 dmacount |= BIT(VALID_BIT);
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +0100734 dmacount |= BIT(DMA_DONE_INTERRUPT_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
736 /* td->dmadesc = previously set by caller */
737 td->dmaaddr = cpu_to_le32 (req->req.dma);
738
739 /* 2280 may be polling VALID_BIT through ep->dma->dmadesc */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200740 wmb();
Harvey Harrisonda2bbdc2008-10-29 14:25:51 -0700741 td->dmacount = cpu_to_le32(dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742}
743
744static const u32 dmactl_default =
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200745 BIT(DMA_SCATTER_GATHER_DONE_INTERRUPT) |
746 BIT(DMA_CLEAR_COUNT_ENABLE) |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 /* erratum 0116 workaround part 1 (use POLLING) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200748 (POLL_100_USEC << DESCRIPTOR_POLLING_RATE) |
749 BIT(DMA_VALID_BIT_POLLING_ENABLE) |
750 BIT(DMA_VALID_BIT_ENABLE) |
751 BIT(DMA_SCATTER_GATHER_ENABLE) |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 /* erratum 0116 workaround part 2 (no AUTOSTART) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200753 BIT(DMA_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200755static inline void spin_stop_dma(struct net2280_dma_regs __iomem *dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200757 handshake(&dma->dmactl, BIT(DMA_ENABLE), 0, 50);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758}
759
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200760static inline void stop_dma(struct net2280_dma_regs __iomem *dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200762 writel(readl(&dma->dmactl) & ~BIT(DMA_ENABLE), &dma->dmactl);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200763 spin_stop_dma(dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764}
765
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200766static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767{
768 struct net2280_dma_regs __iomem *dma = ep->dma;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200769 unsigned int tmp = BIT(VALID_BIT) | (ep->is_in << DMA_DIRECTION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700770
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200771 if (!(ep->dev->quirks & PLX_2280))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200772 tmp |= BIT(END_OF_CHAIN);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +0100773
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200774 writel(tmp, &dma->dmacount);
775 writel(readl(&dma->dmastat), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200777 writel(td_dma, &dma->dmadesc);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200778 if (ep->dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200779 dmactl |= BIT(DMA_REQUEST_OUTSTANDING);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200780 writel(dmactl, &dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 /* erratum 0116 workaround part 3: pci arbiter away from net2280 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200783 (void) readl(&ep->dev->pci->pcimstctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200785 writel(BIT(DMA_START), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
787 if (!ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200788 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789}
790
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200791static void start_dma(struct net2280_ep *ep, struct net2280_request *req)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792{
793 u32 tmp;
794 struct net2280_dma_regs __iomem *dma = ep->dma;
795
796 /* FIXME can't use DMA for ZLPs */
797
798 /* on this path we "know" there's no dma active (yet) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200799 WARN_ON(readl(&dma->dmactl) & BIT(DMA_ENABLE));
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200800 writel(0, &ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 /* previous OUT packet might have been short */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200803 if (!ep->is_in && (readl(&ep->regs->ep_stat) &
804 BIT(NAK_OUT_PACKETS))) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200805 writel(BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 &ep->regs->ep_stat);
807
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200808 tmp = readl(&ep->regs->ep_avail);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 if (tmp) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200810 writel(readl(&dma->dmastat), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 /* transfer all/some fifo data */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200813 writel(req->req.dma, &dma->dmaaddr);
814 tmp = min(tmp, req->req.length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
816 /* dma irq, faking scatterlist status */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200817 req->td->dmacount = cpu_to_le32(req->req.length - tmp);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +0200818 writel(BIT(DMA_DONE_INTERRUPT_ENABLE) | tmp,
819 &dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820 req->td->dmadesc = 0;
821 req->valid = 1;
822
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200823 writel(BIT(DMA_ENABLE), &dma->dmactl);
824 writel(BIT(DMA_START), &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 return;
826 }
827 }
828
829 tmp = dmactl_default;
830
831 /* force packet boundaries between dma requests, but prevent the
832 * controller from automagically writing a last "short" packet
833 * (zero length) unless the driver explicitly said to do that.
834 */
835 if (ep->is_in) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200836 if (likely((req->req.length % ep->ep.maxpacket) ||
837 req->req.zero)){
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200838 tmp |= BIT(DMA_FIFO_VALIDATE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 ep->in_fifo_validate = 1;
840 } else
841 ep->in_fifo_validate = 0;
842 }
843
844 /* init req->td, pointing to the current dummy */
845 req->td->dmadesc = cpu_to_le32 (ep->td_dma);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200846 fill_dma_desc(ep, req, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +0100848 req->td->dmacount |= cpu_to_le32(BIT(END_OF_CHAIN));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200850 start_queue(ep, tmp, req->td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851}
852
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200853static inline void resume_dma(struct net2280_ep *ep)
854{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200855 writel(readl(&ep->dma->dmactl) | BIT(DMA_ENABLE), &ep->dma->dmactl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200856
857 ep->dma_started = true;
858}
859
860static inline void ep_stop_dma(struct net2280_ep *ep)
861{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200862 writel(readl(&ep->dma->dmactl) & ~BIT(DMA_ENABLE), &ep->dma->dmactl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200863 spin_stop_dma(ep->dma);
864
865 ep->dma_started = false;
866}
867
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868static inline void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200869queue_dma(struct net2280_ep *ep, struct net2280_request *req, int valid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870{
871 struct net2280_dma *end;
872 dma_addr_t tmp;
873
874 /* swap new dummy for old, link; fill and maybe activate */
875 end = ep->dummy;
876 ep->dummy = req->td;
877 req->td = end;
878
879 tmp = ep->td_dma;
880 ep->td_dma = req->td_dma;
881 req->td_dma = tmp;
882
883 end->dmadesc = cpu_to_le32 (ep->td_dma);
884
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200885 fill_dma_desc(ep, req, valid);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886}
887
888static void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200889done(struct net2280_ep *ep, struct net2280_request *req, int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890{
891 struct net2280 *dev;
892 unsigned stopped = ep->stopped;
893
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200894 list_del_init(&req->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896 if (req->req.status == -EINPROGRESS)
897 req->req.status = status;
898 else
899 status = req->req.status;
900
901 dev = ep->dev;
Felipe Balbiae4d7932011-12-19 12:09:56 +0200902 if (ep->dma)
903 usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
905 if (status && status != -ESHUTDOWN)
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200906 ep_vdbg(dev, "complete %s req %p stat %d len %u/%u\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 ep->ep.name, &req->req, status,
908 req->req.actual, req->req.length);
909
910 /* don't modify queue heads during completion callback */
911 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200912 spin_unlock(&dev->lock);
Michal Sojka304f7e52014-09-24 22:43:19 +0200913 usb_gadget_giveback_request(&ep->ep, &req->req);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200914 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 ep->stopped = stopped;
916}
917
918/*-------------------------------------------------------------------------*/
919
920static int
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200921net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922{
923 struct net2280_request *req;
924 struct net2280_ep *ep;
925 struct net2280 *dev;
926 unsigned long flags;
927
928 /* we always require a cpu-view buffer, so that we can
929 * always use pio (as fallback or whatever).
930 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200931 req = container_of(_req, struct net2280_request, req);
932 if (!_req || !_req->complete || !_req->buf ||
933 !list_empty(&req->queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 return -EINVAL;
935 if (_req->length > (~0 & DMA_BYTE_COUNT_MASK))
936 return -EDOM;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200937 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 if (!_ep || (!ep->desc && ep->num != 0))
939 return -EINVAL;
940 dev = ep->dev;
941 if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
942 return -ESHUTDOWN;
943
944 /* FIXME implement PIO fallback for ZLPs with DMA */
945 if (ep->dma && _req->length == 0)
946 return -EOPNOTSUPP;
947
948 /* set up dma mapping in case the caller didn't */
Felipe Balbiae4d7932011-12-19 12:09:56 +0200949 if (ep->dma) {
950 int ret;
951
952 ret = usb_gadget_map_request(&dev->gadget, _req,
953 ep->is_in);
954 if (ret)
955 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 }
957
958#if 0
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200959 ep_vdbg(dev, "%s queue req %p, len %d buf %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 _ep->name, _req, _req->length, _req->buf);
961#endif
962
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200963 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
965 _req->status = -EINPROGRESS;
966 _req->actual = 0;
967
968 /* kickstart this i/o queue? */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200969 if (list_empty(&ep->queue) && !ep->stopped) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200970 /* DMA request while EP halted */
971 if (ep->dma &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +0200972 (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)) &&
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +0200973 (dev->quirks & PLX_SUPERSPEED)) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200974 int valid = 1;
975 if (ep->is_in) {
976 int expect;
977 expect = likely(req->req.zero ||
978 ((req->req.length %
979 ep->ep.maxpacket) != 0));
980 if (expect != ep->in_fifo_validate)
981 valid = 0;
982 }
983 queue_dma(ep, req, valid);
984 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 /* use DMA if the endpoint supports it, else pio */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +0200986 else if (ep->dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200987 start_dma(ep, req);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 else {
989 /* maybe there's no control data, just status ack */
990 if (ep->num == 0 && _req->length == 0) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200991 allow_status(ep);
992 done(ep, req, 0);
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +0200993 ep_vdbg(dev, "%s status ack\n", ep->ep.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 goto done;
995 }
996
997 /* PIO ... stuff the fifo, or unblock it. */
998 if (ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +0200999 write_fifo(ep, _req);
1000 else if (list_empty(&ep->queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 u32 s;
1002
1003 /* OUT FIFO might have packet(s) buffered */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001004 s = readl(&ep->regs->ep_stat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001005 if ((s & BIT(FIFO_EMPTY)) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 /* note: _req->short_not_ok is
1007 * ignored here since PIO _always_
1008 * stops queue advance here, and
1009 * _req->status doesn't change for
1010 * short reads (only _req->actual)
1011 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001012 if (read_fifo(ep, req) &&
1013 ep->num == 0) {
1014 done(ep, req, 0);
1015 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 /* don't queue it */
1017 req = NULL;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001018 } else if (read_fifo(ep, req) &&
1019 ep->num != 0) {
1020 done(ep, req, 0);
1021 req = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 } else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001023 s = readl(&ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 }
1025
1026 /* don't NAK, let the fifo fill */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001027 if (req && (s & BIT(NAK_OUT_PACKETS)))
1028 writel(BIT(CLEAR_NAK_OUT_PACKETS),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 &ep->regs->ep_rsp);
1030 }
1031 }
1032
1033 } else if (ep->dma) {
1034 int valid = 1;
1035
1036 if (ep->is_in) {
1037 int expect;
1038
1039 /* preventing magic zlps is per-engine state, not
1040 * per-transfer; irq logic must recover hiccups.
1041 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001042 expect = likely(req->req.zero ||
1043 (req->req.length % ep->ep.maxpacket));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 if (expect != ep->in_fifo_validate)
1045 valid = 0;
1046 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001047 queue_dma(ep, req, valid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049 } /* else the irq handler advances the queue. */
1050
Alan Stern1f26e282006-11-16 10:16:00 -05001051 ep->responded = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001053 list_add_tail(&req->queue, &ep->queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054done:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001055 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057 /* pci writes may still be posted */
1058 return 0;
1059}
1060
1061static inline void
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001062dma_done(struct net2280_ep *ep, struct net2280_request *req, u32 dmacount,
1063 int status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064{
1065 req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001066 done(ep, req, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067}
1068
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001069static void restart_dma(struct net2280_ep *ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001071static void scan_dma_completions(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072{
1073 /* only look at descriptors that were "naturally" retired,
1074 * so fifo and list head state won't matter
1075 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001076 while (!list_empty(&ep->queue)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 struct net2280_request *req;
1078 u32 tmp;
1079
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001080 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 struct net2280_request, queue);
1082 if (!req->valid)
1083 break;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001084 rmb();
1085 tmp = le32_to_cpup(&req->td->dmacount);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001086 if ((tmp & BIT(VALID_BIT)) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 break;
1088
1089 /* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
1090 * cases where DMA must be aborted; this code handles
1091 * all non-abort DMA completions.
1092 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001093 if (unlikely(req->td->dmadesc == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 /* paranoia */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001095 tmp = readl(&ep->dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (tmp & DMA_BYTE_COUNT_MASK)
1097 break;
1098 /* single transfer mode */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001099 dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 break;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02001101 } else if (!ep->is_in &&
1102 (req->req.length % ep->ep.maxpacket) != 0) {
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02001103 if (ep->dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001104 return dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Mario Schuknecht18a4e652014-11-16 21:21:45 +01001106 tmp = readl(&ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 /* AVOID TROUBLE HERE by not issuing short reads from
1108 * your gadget driver. That helps avoids errata 0121,
1109 * 0122, and 0124; not all cases trigger the warning.
1110 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001111 if ((tmp & BIT(NAK_OUT_PACKETS)) == 0) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001112 ep_warn(ep->dev, "%s lost packet sync!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 ep->ep.name);
1114 req->req.status = -EOVERFLOW;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001115 } else {
1116 tmp = readl(&ep->regs->ep_avail);
1117 if (tmp) {
1118 /* fifo gets flushed later */
1119 ep->out_overflow = 1;
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001120 ep_dbg(ep->dev,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001121 "%s dma, discard %d len %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 ep->ep.name, tmp,
1123 req->req.length);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001124 req->req.status = -EOVERFLOW;
1125 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 }
1127 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001128 dma_done(ep, req, tmp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 }
1130}
1131
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001132static void restart_dma(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133{
1134 struct net2280_request *req;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
1136 if (ep->stopped)
1137 return;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001138 req = list_entry(ep->queue.next, struct net2280_request, queue);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01001140 start_dma(ep, req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141}
1142
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001143static void abort_dma_228x(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144{
1145 /* abort the current transfer */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001146 if (likely(!list_empty(&ep->queue))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 /* FIXME work around errata 0121, 0122, 0124 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001148 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001149 spin_stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 } else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001151 stop_dma(ep->dma);
1152 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153}
1154
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001155static void abort_dma_338x(struct net2280_ep *ep)
1156{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001157 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001158 spin_stop_dma(ep->dma);
1159}
1160
1161static void abort_dma(struct net2280_ep *ep)
1162{
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02001163 if (ep->dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001164 return abort_dma_228x(ep);
1165 return abort_dma_338x(ep);
1166}
1167
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168/* dequeue ALL requests */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001169static void nuke(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170{
1171 struct net2280_request *req;
1172
1173 /* called with spinlock held */
1174 ep->stopped = 1;
1175 if (ep->dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001176 abort_dma(ep);
1177 while (!list_empty(&ep->queue)) {
1178 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 struct net2280_request,
1180 queue);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001181 done(ep, req, -ESHUTDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 }
1183}
1184
1185/* dequeue JUST ONE request */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001186static int net2280_dequeue(struct usb_ep *_ep, struct usb_request *_req)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187{
1188 struct net2280_ep *ep;
1189 struct net2280_request *req;
1190 unsigned long flags;
1191 u32 dmactl;
1192 int stopped;
1193
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001194 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 if (!_ep || (!ep->desc && ep->num != 0) || !_req)
1196 return -EINVAL;
1197
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001198 spin_lock_irqsave(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 stopped = ep->stopped;
1200
1201 /* quiesce dma while we patch the queue */
1202 dmactl = 0;
1203 ep->stopped = 1;
1204 if (ep->dma) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001205 dmactl = readl(&ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 /* WARNING erratum 0127 may kick in ... */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001207 stop_dma(ep->dma);
1208 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 }
1210
1211 /* make sure it's still queued on this endpoint */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001212 list_for_each_entry(req, &ep->queue, queue) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if (&req->req == _req)
1214 break;
1215 }
1216 if (&req->req != _req) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001217 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 return -EINVAL;
1219 }
1220
1221 /* queue head may be partially complete. */
1222 if (ep->queue.next == &req->queue) {
1223 if (ep->dma) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001224 ep_dbg(ep->dev, "unlink (%s) dma\n", _ep->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 _req->status = -ECONNRESET;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001226 abort_dma(ep);
1227 if (likely(ep->queue.next == &req->queue)) {
1228 /* NOTE: misreports single-transfer mode*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 req->td->dmacount = 0; /* invalidate */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001230 dma_done(ep, req,
1231 readl(&ep->dma->dmacount),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 -ECONNRESET);
1233 }
1234 } else {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001235 ep_dbg(ep->dev, "unlink (%s) pio\n", _ep->name);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001236 done(ep, req, -ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 }
1238 req = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 }
1240
1241 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001242 done(ep, req, -ECONNRESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 ep->stopped = stopped;
1244
1245 if (ep->dma) {
1246 /* turn off dma on inactive queues */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001247 if (list_empty(&ep->queue))
1248 stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 else if (!ep->stopped) {
1250 /* resume current request, or start new one */
1251 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001252 writel(dmactl, &ep->dma->dmactl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001254 start_dma(ep, list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 struct net2280_request, queue));
1256 }
1257 }
1258
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001259 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 return 0;
1261}
1262
1263/*-------------------------------------------------------------------------*/
1264
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001265static int net2280_fifo_status(struct usb_ep *_ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266
1267static int
Alan Stern80661342008-08-14 15:49:11 -04001268net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269{
1270 struct net2280_ep *ep;
1271 unsigned long flags;
1272 int retval = 0;
1273
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001274 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 if (!_ep || (!ep->desc && ep->num != 0))
1276 return -EINVAL;
1277 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1278 return -ESHUTDOWN;
1279 if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03)
1280 == USB_ENDPOINT_XFER_ISOC)
1281 return -EINVAL;
1282
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001283 spin_lock_irqsave(&ep->dev->lock, flags);
1284 if (!list_empty(&ep->queue))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 retval = -EAGAIN;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001286 else if (ep->is_in && value && net2280_fifo_status(_ep) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 retval = -EAGAIN;
1288 else {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001289 ep_vdbg(ep->dev, "%s %s %s\n", _ep->name,
Alan Stern80661342008-08-14 15:49:11 -04001290 value ? "set" : "clear",
1291 wedged ? "wedge" : "halt");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 /* set/clear, then synch memory views with the device */
1293 if (value) {
1294 if (ep->num == 0)
1295 ep->dev->protocol_stall = 1;
1296 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001297 set_halt(ep);
Alan Stern80661342008-08-14 15:49:11 -04001298 if (wedged)
1299 ep->wedged = 1;
1300 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001301 clear_halt(ep);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02001302 if (ep->dev->quirks & PLX_SUPERSPEED &&
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001303 !list_empty(&ep->queue) && ep->td_dma)
1304 restart_dma(ep);
Alan Stern80661342008-08-14 15:49:11 -04001305 ep->wedged = 0;
1306 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001307 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001309 spin_unlock_irqrestore(&ep->dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310
1311 return retval;
1312}
1313
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001314static int net2280_set_halt(struct usb_ep *_ep, int value)
Alan Stern80661342008-08-14 15:49:11 -04001315{
1316 return net2280_set_halt_and_wedge(_ep, value, 0);
1317}
1318
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001319static int net2280_set_wedge(struct usb_ep *_ep)
Alan Stern80661342008-08-14 15:49:11 -04001320{
1321 if (!_ep || _ep->name == ep0name)
1322 return -EINVAL;
1323 return net2280_set_halt_and_wedge(_ep, 1, 1);
1324}
1325
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001326static int net2280_fifo_status(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327{
1328 struct net2280_ep *ep;
1329 u32 avail;
1330
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001331 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 if (!_ep || (!ep->desc && ep->num != 0))
1333 return -ENODEV;
1334 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1335 return -ESHUTDOWN;
1336
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001337 avail = readl(&ep->regs->ep_avail) & (BIT(12) - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 if (avail > ep->fifo_size)
1339 return -EOVERFLOW;
1340 if (ep->is_in)
1341 avail = ep->fifo_size - avail;
1342 return avail;
1343}
1344
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001345static void net2280_fifo_flush(struct usb_ep *_ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346{
1347 struct net2280_ep *ep;
1348
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001349 ep = container_of(_ep, struct net2280_ep, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 if (!_ep || (!ep->desc && ep->num != 0))
1351 return;
1352 if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
1353 return;
1354
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001355 writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001356 (void) readl(&ep->regs->ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357}
1358
David Brownell901b3d72006-09-02 03:13:45 -07001359static const struct usb_ep_ops net2280_ep_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 .enable = net2280_enable,
1361 .disable = net2280_disable,
1362
1363 .alloc_request = net2280_alloc_request,
1364 .free_request = net2280_free_request,
1365
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 .queue = net2280_queue,
1367 .dequeue = net2280_dequeue,
1368
1369 .set_halt = net2280_set_halt,
Alan Stern80661342008-08-14 15:49:11 -04001370 .set_wedge = net2280_set_wedge,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 .fifo_status = net2280_fifo_status,
1372 .fifo_flush = net2280_fifo_flush,
1373};
1374
1375/*-------------------------------------------------------------------------*/
1376
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001377static int net2280_get_frame(struct usb_gadget *_gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378{
1379 struct net2280 *dev;
1380 unsigned long flags;
1381 u16 retval;
1382
1383 if (!_gadget)
1384 return -ENODEV;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001385 dev = container_of(_gadget, struct net2280, gadget);
1386 spin_lock_irqsave(&dev->lock, flags);
1387 retval = get_idx_reg(dev->regs, REG_FRAME) & 0x03ff;
1388 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 return retval;
1390}
1391
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001392static int net2280_wakeup(struct usb_gadget *_gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393{
1394 struct net2280 *dev;
1395 u32 tmp;
1396 unsigned long flags;
1397
1398 if (!_gadget)
1399 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001400 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001402 spin_lock_irqsave(&dev->lock, flags);
1403 tmp = readl(&dev->usb->usbctl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001404 if (tmp & BIT(DEVICE_REMOTE_WAKEUP_ENABLE))
1405 writel(BIT(GENERATE_RESUME), &dev->usb->usbstat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001406 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408 /* pci writes may still be posted */
1409 return 0;
1410}
1411
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001412static int net2280_set_selfpowered(struct usb_gadget *_gadget, int value)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413{
1414 struct net2280 *dev;
1415 u32 tmp;
1416 unsigned long flags;
1417
1418 if (!_gadget)
1419 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001420 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001422 spin_lock_irqsave(&dev->lock, flags);
1423 tmp = readl(&dev->usb->usbctl);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001424 if (value) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001425 tmp |= BIT(SELF_POWERED_STATUS);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001426 dev->selfpowered = 1;
1427 } else {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001428 tmp &= ~BIT(SELF_POWERED_STATUS);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001429 dev->selfpowered = 0;
1430 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001431 writel(tmp, &dev->usb->usbctl);
1432 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
1434 return 0;
1435}
1436
1437static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
1438{
1439 struct net2280 *dev;
1440 u32 tmp;
1441 unsigned long flags;
1442
1443 if (!_gadget)
1444 return -ENODEV;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001445 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001447 spin_lock_irqsave(&dev->lock, flags);
1448 tmp = readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 dev->softconnect = (is_on != 0);
1450 if (is_on)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001451 tmp |= BIT(USB_DETECT_ENABLE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001453 tmp &= ~BIT(USB_DETECT_ENABLE);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001454 writel(tmp, &dev->usb->usbctl);
1455 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457 return 0;
1458}
1459
Felipe Balbi4cf5e002011-10-10 10:37:17 +03001460static int net2280_start(struct usb_gadget *_gadget,
1461 struct usb_gadget_driver *driver);
Felipe Balbi22835b82014-10-17 12:05:12 -05001462static int net2280_stop(struct usb_gadget *_gadget);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001463
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464static const struct usb_gadget_ops net2280_ops = {
1465 .get_frame = net2280_get_frame,
1466 .wakeup = net2280_wakeup,
1467 .set_selfpowered = net2280_set_selfpowered,
1468 .pullup = net2280_pullup,
Felipe Balbi4cf5e002011-10-10 10:37:17 +03001469 .udc_start = net2280_start,
1470 .udc_stop = net2280_stop,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471};
1472
1473/*-------------------------------------------------------------------------*/
1474
Ricardo Ribalda Delgadob99b4062014-07-04 11:27:03 +02001475#ifdef CONFIG_USB_GADGET_DEBUG_FILES
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476
1477/* FIXME move these into procfs, and use seq_file.
1478 * Sysfs _still_ doesn't behave for arbitrarily sized files,
1479 * and also doesn't help products using this with 2.4 kernels.
1480 */
1481
1482/* "function" sysfs attribute */
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001483static ssize_t function_show(struct device *_dev, struct device_attribute *attr,
1484 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001486 struct net2280 *dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001488 if (!dev->driver || !dev->driver->function ||
1489 strlen(dev->driver->function) > PAGE_SIZE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 return 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001491 return scnprintf(buf, PAGE_SIZE, "%s\n", dev->driver->function);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001493static DEVICE_ATTR_RO(function);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001495static ssize_t registers_show(struct device *_dev,
1496 struct device_attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497{
1498 struct net2280 *dev;
1499 char *next;
1500 unsigned size, t;
1501 unsigned long flags;
1502 int i;
1503 u32 t1, t2;
Andrew Morton30e69592005-06-26 17:18:46 -07001504 const char *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001506 dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 next = buf;
1508 size = PAGE_SIZE;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001509 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 if (dev->driver)
1512 s = dev->driver->driver.name;
1513 else
1514 s = "(none)";
1515
1516 /* Main Control Registers */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001517 t = scnprintf(next, size, "%s version " DRIVER_VERSION
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 ", chiprev %04x, dma %s\n\n"
1519 "devinit %03x fifoctl %08x gadget '%s'\n"
1520 "pci irqenb0 %02x irqenb1 %08x "
1521 "irqstat0 %04x irqstat1 %08x\n",
1522 driver_name, dev->chiprev,
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01001523 use_dma ? "enabled" : "disabled",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001524 readl(&dev->regs->devinit),
1525 readl(&dev->regs->fifoctl),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 s,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001527 readl(&dev->regs->pciirqenb0),
1528 readl(&dev->regs->pciirqenb1),
1529 readl(&dev->regs->irqstat0),
1530 readl(&dev->regs->irqstat1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 size -= t;
1532 next += t;
1533
1534 /* USB Control Registers */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001535 t1 = readl(&dev->usb->usbctl);
1536 t2 = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001537 if (t1 & BIT(VBUS_PIN)) {
1538 if (t2 & BIT(HIGH_SPEED))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 s = "high speed";
1540 else if (dev->gadget.speed == USB_SPEED_UNKNOWN)
1541 s = "powered";
1542 else
1543 s = "full speed";
1544 /* full speed bit (6) not working?? */
1545 } else
1546 s = "not attached";
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001547 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 "stdrsp %08x usbctl %08x usbstat %08x "
1549 "addr 0x%02x (%s)\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001550 readl(&dev->usb->stdrsp), t1, t2,
1551 readl(&dev->usb->ouraddr), s);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 size -= t;
1553 next += t;
1554
1555 /* PCI Master Control Registers */
1556
1557 /* DMA Control Registers */
1558
1559 /* Configurable EP Control Registers */
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001560 for (i = 0; i < dev->n_ep; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 struct net2280_ep *ep;
1562
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001563 ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 if (i && !ep->desc)
1565 continue;
1566
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001567 t1 = readl(&ep->cfg->ep_cfg);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001568 t2 = readl(&ep->regs->ep_rsp) & 0xff;
1569 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 "\n%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
1571 "irqenb %02x\n",
1572 ep->ep.name, t1, t2,
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001573 (t2 & BIT(CLEAR_NAK_OUT_PACKETS))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 ? "NAK " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001575 (t2 & BIT(CLEAR_EP_HIDE_STATUS_PHASE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 ? "hide " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001577 (t2 & BIT(CLEAR_EP_FORCE_CRC_ERROR))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 ? "CRC " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001579 (t2 & BIT(CLEAR_INTERRUPT_MODE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 ? "interrupt " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001581 (t2 & BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 ? "status " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001583 (t2 & BIT(CLEAR_NAK_OUT_PACKETS_MODE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 ? "NAKmode " : "",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001585 (t2 & BIT(CLEAR_ENDPOINT_TOGGLE))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 ? "DATA1 " : "DATA0 ",
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001587 (t2 & BIT(CLEAR_ENDPOINT_HALT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 ? "HALT " : "",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001589 readl(&ep->regs->ep_irqenb));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 size -= t;
1591 next += t;
1592
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001593 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 "\tstat %08x avail %04x "
1595 "(ep%d%s-%s)%s\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001596 readl(&ep->regs->ep_stat),
1597 readl(&ep->regs->ep_avail),
1598 t1 & 0x0f, DIR_STRING(t1),
1599 type_string(t1 >> 8),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 ep->stopped ? "*" : "");
1601 size -= t;
1602 next += t;
1603
1604 if (!ep->dma)
1605 continue;
1606
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001607 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 " dma\tctl %08x stat %08x count %08x\n"
1609 "\taddr %08x desc %08x\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001610 readl(&ep->dma->dmactl),
1611 readl(&ep->dma->dmastat),
1612 readl(&ep->dma->dmacount),
1613 readl(&ep->dma->dmaaddr),
1614 readl(&ep->dma->dmadesc));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 size -= t;
1616 next += t;
1617
1618 }
1619
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001620 /* Indexed Registers (none yet) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
1622 /* Statistics */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001623 t = scnprintf(next, size, "\nirqs: ");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 size -= t;
1625 next += t;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001626 for (i = 0; i < dev->n_ep; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 struct net2280_ep *ep;
1628
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001629 ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 if (i && !ep->irqs)
1631 continue;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001632 t = scnprintf(next, size, " %s/%lu", ep->ep.name, ep->irqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 size -= t;
1634 next += t;
1635
1636 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001637 t = scnprintf(next, size, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 size -= t;
1639 next += t;
1640
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001641 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
1643 return PAGE_SIZE - size;
1644}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001645static DEVICE_ATTR_RO(registers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001647static ssize_t queues_show(struct device *_dev, struct device_attribute *attr,
1648 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649{
1650 struct net2280 *dev;
1651 char *next;
1652 unsigned size;
1653 unsigned long flags;
1654 int i;
1655
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001656 dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 next = buf;
1658 size = PAGE_SIZE;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001659 spin_lock_irqsave(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001661 for (i = 0; i < dev->n_ep; i++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001662 struct net2280_ep *ep = &dev->ep[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 struct net2280_request *req;
1664 int t;
1665
1666 if (i != 0) {
1667 const struct usb_endpoint_descriptor *d;
1668
1669 d = ep->desc;
1670 if (!d)
1671 continue;
1672 t = d->bEndpointAddress;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001673 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 "\n%s (ep%d%s-%s) max %04x %s fifo %d\n",
1675 ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
1676 (t & USB_DIR_IN) ? "in" : "out",
Ricardo Ribalda Delgadoa27f37a2014-05-20 18:30:08 +02001677 type_string(d->bmAttributes),
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001678 usb_endpoint_maxp(d) & 0x1fff,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 ep->dma ? "dma" : "pio", ep->fifo_size
1680 );
1681 } else /* ep0 should only have one transfer queued */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001682 t = scnprintf(next, size, "ep0 max 64 pio %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 ep->is_in ? "in" : "out");
1684 if (t <= 0 || t > size)
1685 goto done;
1686 size -= t;
1687 next += t;
1688
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001689 if (list_empty(&ep->queue)) {
1690 t = scnprintf(next, size, "\t(nothing queued)\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 if (t <= 0 || t > size)
1692 goto done;
1693 size -= t;
1694 next += t;
1695 continue;
1696 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001697 list_for_each_entry(req, &ep->queue, queue) {
1698 if (ep->dma && req->td_dma == readl(&ep->dma->dmadesc))
1699 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 "\treq %p len %d/%d "
1701 "buf %p (dmacount %08x)\n",
1702 &req->req, req->req.actual,
1703 req->req.length, req->req.buf,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001704 readl(&ep->dma->dmacount));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001706 t = scnprintf(next, size,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 "\treq %p len %d/%d buf %p\n",
1708 &req->req, req->req.actual,
1709 req->req.length, req->req.buf);
1710 if (t <= 0 || t > size)
1711 goto done;
1712 size -= t;
1713 next += t;
1714
1715 if (ep->dma) {
1716 struct net2280_dma *td;
1717
1718 td = req->td;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001719 t = scnprintf(next, size, "\t td %08x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 " count %08x buf %08x desc %08x\n",
1721 (u32) req->td_dma,
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001722 le32_to_cpu(td->dmacount),
1723 le32_to_cpu(td->dmaaddr),
1724 le32_to_cpu(td->dmadesc));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 if (t <= 0 || t > size)
1726 goto done;
1727 size -= t;
1728 next += t;
1729 }
1730 }
1731 }
1732
1733done:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001734 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 return PAGE_SIZE - size;
1736}
Greg Kroah-Hartmance26bd22013-08-23 16:34:43 -07001737static DEVICE_ATTR_RO(queues);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
1739
1740#else
1741
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001742#define device_create_file(a, b) (0)
1743#define device_remove_file(a, b) do { } while (0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
1745#endif
1746
1747/*-------------------------------------------------------------------------*/
1748
1749/* another driver-specific mode might be a request type doing dma
1750 * to/from another device fifo instead of to/from memory.
1751 */
1752
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001753static void set_fifo_mode(struct net2280 *dev, int mode)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754{
1755 /* keeping high bits preserves BAR2 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001756 writel((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
1758 /* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001759 INIT_LIST_HEAD(&dev->gadget.ep_list);
1760 list_add_tail(&dev->ep[1].ep.ep_list, &dev->gadget.ep_list);
1761 list_add_tail(&dev->ep[2].ep.ep_list, &dev->gadget.ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 switch (mode) {
1763 case 0:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001764 list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
1765 list_add_tail(&dev->ep[4].ep.ep_list, &dev->gadget.ep_list);
1766 dev->ep[1].fifo_size = dev->ep[2].fifo_size = 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 break;
1768 case 1:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001769 dev->ep[1].fifo_size = dev->ep[2].fifo_size = 2048;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 break;
1771 case 2:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001772 list_add_tail(&dev->ep[3].ep.ep_list, &dev->gadget.ep_list);
1773 dev->ep[1].fifo_size = 2048;
1774 dev->ep[2].fifo_size = 1024;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 break;
1776 }
1777 /* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001778 list_add_tail(&dev->ep[5].ep.ep_list, &dev->gadget.ep_list);
1779 list_add_tail(&dev->ep[6].ep.ep_list, &dev->gadget.ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780}
1781
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001782static void defect7374_disable_data_eps(struct net2280 *dev)
1783{
1784 /*
1785 * For Defect 7374, disable data EPs (and more):
1786 * - This phase undoes the earlier phase of the Defect 7374 workaround,
1787 * returing ep regs back to normal.
1788 */
1789 struct net2280_ep *ep;
1790 int i;
1791 unsigned char ep_sel;
1792 u32 tmp_reg;
1793
1794 for (i = 1; i < 5; i++) {
1795 ep = &dev->ep[i];
1796 writel(0, &ep->cfg->ep_cfg);
1797 }
1798
1799 /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */
1800 for (i = 0; i < 6; i++)
1801 writel(0, &dev->dep[i].dep_cfg);
1802
1803 for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
1804 /* Select an endpoint for subsequent operations: */
1805 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
1806 writel(((tmp_reg & ~0x1f) | ep_sel), &dev->plregs->pl_ep_ctrl);
1807
1808 if (ep_sel < 2 || (ep_sel > 9 && ep_sel < 14) ||
1809 ep_sel == 18 || ep_sel == 20)
1810 continue;
1811
1812 /* Change settings on some selected endpoints */
1813 tmp_reg = readl(&dev->plregs->pl_ep_cfg_4);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001814 tmp_reg &= ~BIT(NON_CTRL_IN_TOLERATE_BAD_DIR);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001815 writel(tmp_reg, &dev->plregs->pl_ep_cfg_4);
1816 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001817 tmp_reg |= BIT(EP_INITIALIZED);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001818 writel(tmp_reg, &dev->plregs->pl_ep_ctrl);
1819 }
1820}
1821
1822static void defect7374_enable_data_eps_zero(struct net2280 *dev)
1823{
1824 u32 tmp = 0, tmp_reg;
1825 u32 fsmvalue, scratch;
1826 int i;
1827 unsigned char ep_sel;
1828
1829 scratch = get_idx_reg(dev->regs, SCRATCH);
1830 fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
1831 scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
1832
1833 /*See if firmware needs to set up for workaround*/
1834 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001835 ep_warn(dev, "Operate Defect 7374 workaround soft this time");
1836 ep_warn(dev, "It will operate on cold-reboot and SS connect");
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001837
1838 /*GPEPs:*/
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001839 tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_DIRECTION) |
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001840 (2 << OUT_ENDPOINT_TYPE) | (2 << IN_ENDPOINT_TYPE) |
1841 ((dev->enhanced_mode) ?
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001842 BIT(OUT_ENDPOINT_ENABLE) : BIT(ENDPOINT_ENABLE)) |
1843 BIT(IN_ENDPOINT_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001844
1845 for (i = 1; i < 5; i++)
1846 writel(tmp, &dev->ep[i].cfg->ep_cfg);
1847
1848 /* CSRIN, PCIIN, STATIN, RCIN*/
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001849 tmp = ((0 << ENDPOINT_NUMBER) | BIT(ENDPOINT_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001850 writel(tmp, &dev->dep[1].dep_cfg);
1851 writel(tmp, &dev->dep[3].dep_cfg);
1852 writel(tmp, &dev->dep[4].dep_cfg);
1853 writel(tmp, &dev->dep[5].dep_cfg);
1854
1855 /*Implemented for development and debug.
1856 * Can be refined/tuned later.*/
1857 for (ep_sel = 0; ep_sel <= 21; ep_sel++) {
1858 /* Select an endpoint for subsequent operations: */
1859 tmp_reg = readl(&dev->plregs->pl_ep_ctrl);
1860 writel(((tmp_reg & ~0x1f) | ep_sel),
1861 &dev->plregs->pl_ep_ctrl);
1862
1863 if (ep_sel == 1) {
1864 tmp =
1865 (readl(&dev->plregs->pl_ep_ctrl) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001866 BIT(CLEAR_ACK_ERROR_CODE) | 0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001867 writel(tmp, &dev->plregs->pl_ep_ctrl);
1868 continue;
1869 }
1870
1871 if (ep_sel == 0 || (ep_sel > 9 && ep_sel < 14) ||
1872 ep_sel == 18 || ep_sel == 20)
1873 continue;
1874
1875 tmp = (readl(&dev->plregs->pl_ep_cfg_4) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001876 BIT(NON_CTRL_IN_TOLERATE_BAD_DIR) | 0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001877 writel(tmp, &dev->plregs->pl_ep_cfg_4);
1878
1879 tmp = readl(&dev->plregs->pl_ep_ctrl) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001880 ~BIT(EP_INITIALIZED);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001881 writel(tmp, &dev->plregs->pl_ep_ctrl);
1882
1883 }
1884
1885 /* Set FSM to focus on the first Control Read:
1886 * - Tip: Connection speed is known upon the first
1887 * setup request.*/
1888 scratch |= DEFECT7374_FSM_WAITING_FOR_CONTROL_READ;
1889 set_idx_reg(dev->regs, SCRATCH, scratch);
1890
1891 } else{
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001892 ep_warn(dev, "Defect 7374 workaround soft will NOT operate");
1893 ep_warn(dev, "It will operate on cold-reboot and SS connect");
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001894 }
1895}
1896
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897/* keeping it simple:
1898 * - one bus driver, initted first;
1899 * - one function driver, initted second
1900 *
1901 * most of the work to support multiple net2280 controllers would
1902 * be to associate this gadget driver (yes?) with all of them, or
1903 * perhaps to bind specific drivers to specific devices.
1904 */
1905
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001906static void usb_reset_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907{
1908 u32 tmp;
1909
1910 dev->gadget.speed = USB_SPEED_UNKNOWN;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001911 (void) readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001913 net2280_led_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
1915 /* disable automatic responses, and irqs */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001916 writel(0, &dev->usb->stdrsp);
1917 writel(0, &dev->regs->pciirqenb0);
1918 writel(0, &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
1920 /* clear old dma and irq state */
1921 for (tmp = 0; tmp < 4; tmp++) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001922 struct net2280_ep *ep = &dev->ep[tmp + 1];
Greg Kroah-Hartman357d596e2014-05-28 11:35:41 -07001923 if (ep->dma)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001924 abort_dma(ep);
Greg Kroah-Hartman357d596e2014-05-28 11:35:41 -07001925 }
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001926
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001927 writel(~0, &dev->regs->irqstat0),
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001928 writel(~(u32)BIT(SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929
1930 /* reset, and enable pci */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001931 tmp = readl(&dev->regs->devinit) |
1932 BIT(PCI_ENABLE) |
1933 BIT(FIFO_SOFT_RESET) |
1934 BIT(USB_SOFT_RESET) |
1935 BIT(M8051_RESET);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001936 writel(tmp, &dev->regs->devinit);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
1938 /* standard fifo and endpoint allocations */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02001939 set_fifo_mode(dev, (fifo_mode <= 2) ? fifo_mode : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940}
1941
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001942static void usb_reset_338x(struct net2280 *dev)
1943{
1944 u32 tmp;
1945 u32 fsmvalue;
1946
1947 dev->gadget.speed = USB_SPEED_UNKNOWN;
1948 (void)readl(&dev->usb->usbctl);
1949
1950 net2280_led_init(dev);
1951
1952 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
1953 (0xf << DEFECT7374_FSM_FIELD);
1954
1955 /* See if firmware needs to set up for workaround: */
1956 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02001957 ep_info(dev, "%s: Defect 7374 FsmValue 0x%08x\n", __func__,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001958 fsmvalue);
1959 } else {
1960 /* disable automatic responses, and irqs */
1961 writel(0, &dev->usb->stdrsp);
1962 writel(0, &dev->regs->pciirqenb0);
1963 writel(0, &dev->regs->pciirqenb1);
1964 }
1965
1966 /* clear old dma and irq state */
1967 for (tmp = 0; tmp < 4; tmp++) {
1968 struct net2280_ep *ep = &dev->ep[tmp + 1];
1969
1970 if (ep->dma)
1971 abort_dma(ep);
1972 }
1973
1974 writel(~0, &dev->regs->irqstat0), writel(~0, &dev->regs->irqstat1);
1975
1976 if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ) {
1977 /* reset, and enable pci */
1978 tmp = readl(&dev->regs->devinit) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02001979 BIT(PCI_ENABLE) |
1980 BIT(FIFO_SOFT_RESET) |
1981 BIT(USB_SOFT_RESET) |
1982 BIT(M8051_RESET);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001983
1984 writel(tmp, &dev->regs->devinit);
1985 }
1986
1987 /* always ep-{1,2,3,4} ... maybe not ep-3 or ep-4 */
1988 INIT_LIST_HEAD(&dev->gadget.ep_list);
1989
1990 for (tmp = 1; tmp < dev->n_ep; tmp++)
1991 list_add_tail(&dev->ep[tmp].ep.ep_list, &dev->gadget.ep_list);
1992
1993}
1994
1995static void usb_reset(struct net2280 *dev)
1996{
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02001997 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02001998 return usb_reset_228x(dev);
1999 return usb_reset_338x(dev);
2000}
2001
2002static void usb_reinit_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003{
2004 u32 tmp;
2005 int init_dma;
2006
2007 /* use_dma changes are ignored till next device re-init */
2008 init_dma = use_dma;
2009
2010 /* basic endpoint init */
2011 for (tmp = 0; tmp < 7; tmp++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002012 struct net2280_ep *ep = &dev->ep[tmp];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002014 ep->ep.name = ep_name[tmp];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 ep->dev = dev;
2016 ep->num = tmp;
2017
2018 if (tmp > 0 && tmp <= 4) {
2019 ep->fifo_size = 1024;
2020 if (init_dma)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002021 ep->dma = &dev->dma[tmp - 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 } else
2023 ep->fifo_size = 64;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002024 ep->regs = &dev->epregs[tmp];
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002025 ep->cfg = &dev->epregs[tmp];
2026 ep_reset_228x(dev->regs, ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002028 usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 64);
2029 usb_ep_set_maxpacket_limit(&dev->ep[5].ep, 64);
2030 usb_ep_set_maxpacket_limit(&dev->ep[6].ep, 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002032 dev->gadget.ep0 = &dev->ep[0].ep;
2033 dev->ep[0].stopped = 0;
2034 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035
2036 /* we want to prevent lowlevel/insecure access from the USB host,
2037 * but erratum 0119 means this enable bit is ignored
2038 */
2039 for (tmp = 0; tmp < 5; tmp++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002040 writel(EP_DONTUSE, &dev->dep[tmp].dep_cfg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041}
2042
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002043static void usb_reinit_338x(struct net2280 *dev)
2044{
2045 int init_dma;
2046 int i;
2047 u32 tmp, val;
2048 u32 fsmvalue;
2049 static const u32 ne[9] = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };
2050 static const u32 ep_reg_addr[9] = { 0x00, 0xC0, 0x00, 0xC0, 0x00,
2051 0x00, 0xC0, 0x00, 0xC0 };
2052
2053 /* use_dma changes are ignored till next device re-init */
2054 init_dma = use_dma;
2055
2056 /* basic endpoint init */
2057 for (i = 0; i < dev->n_ep; i++) {
2058 struct net2280_ep *ep = &dev->ep[i];
2059
2060 ep->ep.name = ep_name[i];
2061 ep->dev = dev;
2062 ep->num = i;
2063
2064 if (i > 0 && i <= 4 && init_dma)
2065 ep->dma = &dev->dma[i - 1];
2066
2067 if (dev->enhanced_mode) {
2068 ep->cfg = &dev->epregs[ne[i]];
2069 ep->regs = (struct net2280_ep_regs __iomem *)
Felipe Balbic43e97b2014-07-16 12:20:25 -05002070 (((void __iomem *)&dev->epregs[ne[i]]) +
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002071 ep_reg_addr[i]);
2072 ep->fiforegs = &dev->fiforegs[i];
2073 } else {
2074 ep->cfg = &dev->epregs[i];
2075 ep->regs = &dev->epregs[i];
2076 ep->fiforegs = &dev->fiforegs[i];
2077 }
2078
2079 ep->fifo_size = (i != 0) ? 2048 : 512;
2080
2081 ep_reset_338x(dev->regs, ep);
2082 }
2083 usb_ep_set_maxpacket_limit(&dev->ep[0].ep, 512);
2084
2085 dev->gadget.ep0 = &dev->ep[0].ep;
2086 dev->ep[0].stopped = 0;
2087
2088 /* Link layer set up */
2089 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
2090 (0xf << DEFECT7374_FSM_FIELD);
2091
2092 /* See if driver needs to set up for workaround: */
2093 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002094 ep_info(dev, "%s: Defect 7374 FsmValue %08x\n",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002095 __func__, fsmvalue);
2096 else {
2097 tmp = readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002098 ~(BIT(U1_ENABLE) | BIT(U2_ENABLE) | BIT(LTM_ENABLE));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002099 writel(tmp, &dev->usb_ext->usbctl2);
2100 }
2101
2102 /* Hardware Defect and Workaround */
2103 val = readl(&dev->ll_lfps_regs->ll_lfps_5);
2104 val &= ~(0xf << TIMER_LFPS_6US);
2105 val |= 0x5 << TIMER_LFPS_6US;
2106 writel(val, &dev->ll_lfps_regs->ll_lfps_5);
2107
2108 val = readl(&dev->ll_lfps_regs->ll_lfps_6);
2109 val &= ~(0xffff << TIMER_LFPS_80US);
2110 val |= 0x0100 << TIMER_LFPS_80US;
2111 writel(val, &dev->ll_lfps_regs->ll_lfps_6);
2112
2113 /*
2114 * AA_AB Errata. Issue 4. Workaround for SuperSpeed USB
2115 * Hot Reset Exit Handshake may Fail in Specific Case using
2116 * Default Register Settings. Workaround for Enumeration test.
2117 */
2118 val = readl(&dev->ll_tsn_regs->ll_tsn_counters_2);
2119 val &= ~(0x1f << HOT_TX_NORESET_TS2);
2120 val |= 0x10 << HOT_TX_NORESET_TS2;
2121 writel(val, &dev->ll_tsn_regs->ll_tsn_counters_2);
2122
2123 val = readl(&dev->ll_tsn_regs->ll_tsn_counters_3);
2124 val &= ~(0x1f << HOT_RX_RESET_TS2);
2125 val |= 0x3 << HOT_RX_RESET_TS2;
2126 writel(val, &dev->ll_tsn_regs->ll_tsn_counters_3);
2127
2128 /*
2129 * Set Recovery Idle to Recover bit:
2130 * - On SS connections, setting Recovery Idle to Recover Fmw improves
2131 * link robustness with various hosts and hubs.
2132 * - It is safe to set for all connection speeds; all chip revisions.
2133 * - R-M-W to leave other bits undisturbed.
2134 * - Reference PLX TT-7372
2135 */
2136 val = readl(&dev->ll_chicken_reg->ll_tsn_chicken_bit);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002137 val |= BIT(RECOVERY_IDLE_TO_RECOVER_FMW);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002138 writel(val, &dev->ll_chicken_reg->ll_tsn_chicken_bit);
2139
2140 INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
2141
2142 /* disable dedicated endpoints */
2143 writel(0x0D, &dev->dep[0].dep_cfg);
2144 writel(0x0D, &dev->dep[1].dep_cfg);
2145 writel(0x0E, &dev->dep[2].dep_cfg);
2146 writel(0x0E, &dev->dep[3].dep_cfg);
2147 writel(0x0F, &dev->dep[4].dep_cfg);
2148 writel(0x0C, &dev->dep[5].dep_cfg);
2149}
2150
2151static void usb_reinit(struct net2280 *dev)
2152{
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002153 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002154 return usb_reinit_228x(dev);
2155 return usb_reinit_338x(dev);
2156}
2157
2158static void ep0_start_228x(struct net2280 *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159{
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002160 writel(BIT(CLEAR_EP_HIDE_STATUS_PHASE) |
2161 BIT(CLEAR_NAK_OUT_PACKETS) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002162 BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
2163 &dev->epregs[0].ep_rsp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164
2165 /*
2166 * hardware optionally handles a bunch of standard requests
2167 * that the API hides from drivers anyway. have it do so.
2168 * endpoint status/features are handled in software, to
2169 * help pass tests for some dubious behavior.
2170 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002171 writel(BIT(SET_TEST_MODE) |
2172 BIT(SET_ADDRESS) |
2173 BIT(DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP) |
2174 BIT(GET_DEVICE_STATUS) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002175 BIT(GET_INTERFACE_STATUS),
2176 &dev->usb->stdrsp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002177 writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
2178 BIT(SELF_POWERED_USB_DEVICE) |
2179 BIT(REMOTE_WAKEUP_SUPPORT) |
2180 (dev->softconnect << USB_DETECT_ENABLE) |
2181 BIT(SELF_POWERED_STATUS),
2182 &dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
2184 /* enable irqs so we can see ep0 and general operation */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002185 writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
2186 BIT(ENDPOINT_0_INTERRUPT_ENABLE),
2187 &dev->regs->pciirqenb0);
2188 writel(BIT(PCI_INTERRUPT_ENABLE) |
2189 BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE) |
2190 BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE) |
2191 BIT(PCI_RETRY_ABORT_INTERRUPT_ENABLE) |
2192 BIT(VBUS_INTERRUPT_ENABLE) |
2193 BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
2194 BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE),
2195 &dev->regs->pciirqenb1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196
2197 /* don't leave any writes posted */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002198 (void) readl(&dev->usb->usbctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199}
2200
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002201static void ep0_start_338x(struct net2280 *dev)
2202{
2203 u32 fsmvalue;
2204
2205 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
2206 (0xf << DEFECT7374_FSM_FIELD);
2207
2208 if (fsmvalue != DEFECT7374_FSM_SS_CONTROL_READ)
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002209 ep_info(dev, "%s: Defect 7374 FsmValue %08x\n", __func__,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002210 fsmvalue);
2211 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002212 writel(BIT(CLEAR_NAK_OUT_PACKETS_MODE) |
2213 BIT(SET_EP_HIDE_STATUS_PHASE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002214 &dev->epregs[0].ep_rsp);
2215
2216 /*
2217 * hardware optionally handles a bunch of standard requests
2218 * that the API hides from drivers anyway. have it do so.
2219 * endpoint status/features are handled in software, to
2220 * help pass tests for some dubious behavior.
2221 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002222 writel(BIT(SET_ISOCHRONOUS_DELAY) |
2223 BIT(SET_SEL) |
2224 BIT(SET_TEST_MODE) |
2225 BIT(SET_ADDRESS) |
2226 BIT(GET_INTERFACE_STATUS) |
2227 BIT(GET_DEVICE_STATUS),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002228 &dev->usb->stdrsp);
2229 dev->wakeup_enable = 1;
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002230 writel(BIT(USB_ROOT_PORT_WAKEUP_ENABLE) |
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002231 (dev->softconnect << USB_DETECT_ENABLE) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002232 BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002233 &dev->usb->usbctl);
2234
2235 /* enable irqs so we can see ep0 and general operation */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002236 writel(BIT(SETUP_PACKET_INTERRUPT_ENABLE) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002237 BIT(ENDPOINT_0_INTERRUPT_ENABLE),
2238 &dev->regs->pciirqenb0);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002239 writel(BIT(PCI_INTERRUPT_ENABLE) |
2240 BIT(ROOT_PORT_RESET_INTERRUPT_ENABLE) |
2241 BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE) |
2242 BIT(VBUS_INTERRUPT_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002243 &dev->regs->pciirqenb1);
2244
2245 /* don't leave any writes posted */
2246 (void)readl(&dev->usb->usbctl);
2247}
2248
2249static void ep0_start(struct net2280 *dev)
2250{
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002251 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002252 return ep0_start_228x(dev);
2253 return ep0_start_338x(dev);
2254}
2255
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256/* when a driver is successfully registered, it will receive
2257 * control requests including set_configuration(), which enables
2258 * non-control requests. then usb traffic follows until a
2259 * disconnect is reported. then a host may connect again, or
2260 * the driver might get unbound.
2261 */
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002262static int net2280_start(struct usb_gadget *_gadget,
2263 struct usb_gadget_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264{
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002265 struct net2280 *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 int retval;
2267 unsigned i;
2268
2269 /* insist on high speed support from the driver, since
2270 * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
2271 * "must not be used in normal operation"
2272 */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002273 if (!driver || driver->max_speed < USB_SPEED_HIGH ||
2274 !driver->setup)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 return -EINVAL;
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002276
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002277 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002278
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002279 for (i = 0; i < dev->n_ep; i++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002280 dev->ep[i].irqs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281
2282 /* hook up the driver ... */
2283 dev->softconnect = 1;
2284 driver->driver.bus = NULL;
2285 dev->driver = driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002287 retval = device_create_file(&dev->pdev->dev, &dev_attr_function);
2288 if (retval)
2289 goto err_unbind;
2290 retval = device_create_file(&dev->pdev->dev, &dev_attr_queues);
2291 if (retval)
2292 goto err_func;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
Alan Stern2f076072013-01-30 16:40:14 -05002294 /* Enable force-full-speed testing mode, if desired */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002295 if (full_speed && (dev->quirks & PLX_LEGACY))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002296 writel(BIT(FORCE_FULL_SPEED_MODE), &dev->usb->xcvrdiag);
Alan Stern2f076072013-01-30 16:40:14 -05002297
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 /* ... then enable host detection and ep0; and we're ready
2299 * for set_configuration as well as eventual disconnect.
2300 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002301 net2280_led_active(dev, 1);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002302
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002303 if (dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002304 defect7374_enable_data_eps_zero(dev);
2305
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002306 ep0_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 /* pci writes may still be posted */
2309 return 0;
Jeff Garzikb3899da2006-10-11 21:50:24 -04002310
2311err_func:
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002312 device_remove_file(&dev->pdev->dev, &dev_attr_function);
Jeff Garzikb3899da2006-10-11 21:50:24 -04002313err_unbind:
Jeff Garzikb3899da2006-10-11 21:50:24 -04002314 dev->driver = NULL;
2315 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002318static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319{
2320 int i;
2321
2322 /* don't disconnect if it's not connected */
2323 if (dev->gadget.speed == USB_SPEED_UNKNOWN)
2324 driver = NULL;
2325
2326 /* stop hardware; prevent new request submissions;
2327 * and kill any outstanding requests.
2328 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002329 usb_reset(dev);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002330 for (i = 0; i < dev->n_ep; i++)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002331 nuke(&dev->ep[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332
Felipe Balbi699412d2013-03-18 10:14:47 +02002333 /* report disconnect; the driver is already quiesced */
2334 if (driver) {
2335 spin_unlock(&dev->lock);
2336 driver->disconnect(&dev->gadget);
2337 spin_lock(&dev->lock);
2338 }
2339
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002340 usb_reinit(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341}
2342
Felipe Balbi22835b82014-10-17 12:05:12 -05002343static int net2280_stop(struct usb_gadget *_gadget)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344{
Felipe Balbi4cf5e002011-10-10 10:37:17 +03002345 struct net2280 *dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346 unsigned long flags;
2347
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002348 dev = container_of(_gadget, struct net2280, gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002350 spin_lock_irqsave(&dev->lock, flags);
Felipe Balbibfd0ed52014-10-17 11:23:33 -05002351 stop_activity(dev, NULL);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002352 spin_unlock_irqrestore(&dev->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002354 net2280_led_active(dev, 0);
Alan Stern2f076072013-01-30 16:40:14 -05002355
2356 /* Disable full-speed test mode */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002357 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002358 writel(0, &dev->usb->xcvrdiag);
Alan Stern2f076072013-01-30 16:40:14 -05002359
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002360 device_remove_file(&dev->pdev->dev, &dev_attr_function);
2361 device_remove_file(&dev->pdev->dev, &dev_attr_queues);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362
Felipe Balbibfd0ed52014-10-17 11:23:33 -05002363 dev->driver = NULL;
Ricardo Ribalda Delgado84237bf2014-05-15 14:28:45 +02002364
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 return 0;
2366}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367
2368/*-------------------------------------------------------------------------*/
2369
2370/* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq.
2371 * also works for dma-capable endpoints, in pio mode or just
2372 * to manually advance the queue after short OUT transfers.
2373 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002374static void handle_ep_small(struct net2280_ep *ep)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375{
2376 struct net2280_request *req;
2377 u32 t;
2378 /* 0 error, 1 mid-data, 2 done */
2379 int mode = 1;
2380
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002381 if (!list_empty(&ep->queue))
2382 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383 struct net2280_request, queue);
2384 else
2385 req = NULL;
2386
2387 /* ack all, and handle what we care about */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002388 t = readl(&ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389 ep->irqs++;
2390#if 0
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002391 ep_vdbg(ep->dev, "%s ack ep_stat %08x, req %p\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392 ep->ep.name, t, req ? &req->req : 0);
2393#endif
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02002394 if (!ep->is_in || (ep->dev->quirks & PLX_2280))
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002395 writel(t & ~BIT(NAK_OUT_PACKETS), &ep->regs->ep_stat);
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01002396 else
2397 /* Added for 2282 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002398 writel(t, &ep->regs->ep_stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
2400 /* for ep0, monitor token irqs to catch data stage length errors
2401 * and to synchronize on status.
2402 *
2403 * also, to defer reporting of protocol stalls ... here's where
2404 * data or status first appears, handling stalls here should never
2405 * cause trouble on the host side..
2406 *
2407 * control requests could be slightly faster without token synch for
2408 * status, but status can jam up that way.
2409 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002410 if (unlikely(ep->num == 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 if (ep->is_in) {
2412 /* status; stop NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002413 if (t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 if (ep->dev->protocol_stall) {
2415 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002416 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 }
2418 if (!req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002419 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420 mode = 2;
2421 /* reply to extra IN data tokens with a zlp */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002422 } else if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423 if (ep->dev->protocol_stall) {
2424 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002425 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 mode = 2;
Alan Stern1f26e282006-11-16 10:16:00 -05002427 } else if (ep->responded &&
2428 !req && !ep->stopped)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002429 write_fifo(ep, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430 }
2431 } else {
2432 /* status; stop NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002433 if (t & BIT(DATA_IN_TOKEN_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434 if (ep->dev->protocol_stall) {
2435 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002436 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 }
2438 mode = 2;
2439 /* an extra OUT token is an error */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002440 } else if (((t & BIT(DATA_OUT_PING_TOKEN_INTERRUPT)) &&
2441 req &&
2442 req->req.actual == req->req.length) ||
2443 (ep->responded && !req)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 ep->dev->protocol_stall = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002445 set_halt(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 ep->stopped = 1;
2447 if (req)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002448 done(ep, req, -EOVERFLOW);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 req = NULL;
2450 }
2451 }
2452 }
2453
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002454 if (unlikely(!req))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 return;
2456
2457 /* manual DMA queue advance after short OUT */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002458 if (likely(ep->dma)) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002459 if (t & BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 u32 count;
2461 int stopped = ep->stopped;
2462
2463 /* TRANSFERRED works around OUT_DONE erratum 0112.
2464 * we expect (N <= maxpacket) bytes; host wrote M.
2465 * iff (M < N) we won't ever see a DMA interrupt.
2466 */
2467 ep->stopped = 1;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002468 for (count = 0; ; t = readl(&ep->regs->ep_stat)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469
2470 /* any preceding dma transfers must finish.
2471 * dma handles (M >= N), may empty the queue
2472 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002473 scan_dma_completions(ep);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002474 if (unlikely(list_empty(&ep->queue) ||
2475 ep->out_overflow)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 req = NULL;
2477 break;
2478 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002479 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480 struct net2280_request, queue);
2481
2482 /* here either (M < N), a "real" short rx;
2483 * or (M == N) and the queue didn't empty
2484 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002485 if (likely(t & BIT(FIFO_EMPTY))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002486 count = readl(&ep->dma->dmacount);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 count &= DMA_BYTE_COUNT_MASK;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002488 if (readl(&ep->dma->dmadesc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489 != req->td_dma)
2490 req = NULL;
2491 break;
2492 }
2493 udelay(1);
2494 }
2495
2496 /* stop DMA, leave ep NAKing */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002497 writel(BIT(DMA_ABORT), &ep->dma->dmastat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002498 spin_stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002500 if (likely(req)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501 req->td->dmacount = 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002502 t = readl(&ep->regs->ep_avail);
2503 dma_done(ep, req, count,
David Brownell901b3d72006-09-02 03:13:45 -07002504 (ep->out_overflow || t)
2505 ? -EOVERFLOW : 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 }
2507
2508 /* also flush to prevent erratum 0106 trouble */
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002509 if (unlikely(ep->out_overflow ||
2510 (ep->dev->chiprev == 0x0100 &&
2511 ep->dev->gadget.speed
2512 == USB_SPEED_FULL))) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002513 out_flush(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 ep->out_overflow = 0;
2515 }
2516
2517 /* (re)start dma if needed, stop NAKing */
2518 ep->stopped = stopped;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002519 if (!list_empty(&ep->queue))
2520 restart_dma(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521 } else
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002522 ep_dbg(ep->dev, "%s dma ep_stat %08x ??\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 ep->ep.name, t);
2524 return;
2525
2526 /* data packet(s) received (in the fifo, OUT) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002527 } else if (t & BIT(DATA_PACKET_RECEIVED_INTERRUPT)) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002528 if (read_fifo(ep, req) && ep->num != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 mode = 2;
2530
2531 /* data packet(s) transmitted (IN) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002532 } else if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 unsigned len;
2534
2535 len = req->req.length - req->req.actual;
2536 if (len > ep->ep.maxpacket)
2537 len = ep->ep.maxpacket;
2538 req->req.actual += len;
2539
2540 /* if we wrote it all, we're usually done */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002541 /* send zlps until the status stage */
2542 if ((req->req.actual == req->req.length) &&
2543 (!req->req.zero || len != ep->ep.maxpacket) && ep->num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 mode = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545
2546 /* there was nothing to do ... */
2547 } else if (mode == 1)
2548 return;
2549
2550 /* done */
2551 if (mode == 2) {
2552 /* stream endpoints often resubmit/unlink in completion */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002553 done(ep, req, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554
2555 /* maybe advance queue to next request */
2556 if (ep->num == 0) {
2557 /* NOTE: net2280 could let gadget driver start the
2558 * status stage later. since not all controllers let
2559 * them control that, the api doesn't (yet) allow it.
2560 */
2561 if (!ep->stopped)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002562 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563 req = NULL;
2564 } else {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002565 if (!list_empty(&ep->queue) && !ep->stopped)
2566 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 struct net2280_request, queue);
2568 else
2569 req = NULL;
2570 if (req && !ep->is_in)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002571 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002572 }
2573 }
2574
2575 /* is there a buffer for the next packet?
2576 * for best streaming performance, make sure there is one.
2577 */
2578 if (req && !ep->stopped) {
2579
2580 /* load IN fifo with next packet (may be zlp) */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002581 if (t & BIT(DATA_PACKET_TRANSMITTED_INTERRUPT))
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002582 write_fifo(ep, &req->req);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 }
2584}
2585
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002586static struct net2280_ep *get_ep_by_addr(struct net2280 *dev, u16 wIndex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587{
2588 struct net2280_ep *ep;
2589
2590 if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002591 return &dev->ep[0];
2592 list_for_each_entry(ep, &dev->gadget.ep_list, ep.ep_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 u8 bEndpointAddress;
2594
2595 if (!ep->desc)
2596 continue;
2597 bEndpointAddress = ep->desc->bEndpointAddress;
2598 if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
2599 continue;
2600 if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f))
2601 return ep;
2602 }
2603 return NULL;
2604}
2605
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002606static void defect7374_workaround(struct net2280 *dev, struct usb_ctrlrequest r)
2607{
2608 u32 scratch, fsmvalue;
2609 u32 ack_wait_timeout, state;
2610
2611 /* Workaround for Defect 7374 (U1/U2 erroneously rejected): */
2612 scratch = get_idx_reg(dev->regs, SCRATCH);
2613 fsmvalue = scratch & (0xf << DEFECT7374_FSM_FIELD);
2614 scratch &= ~(0xf << DEFECT7374_FSM_FIELD);
2615
2616 if (!((fsmvalue == DEFECT7374_FSM_WAITING_FOR_CONTROL_READ) &&
2617 (r.bRequestType & USB_DIR_IN)))
2618 return;
2619
2620 /* This is the first Control Read for this connection: */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002621 if (!(readl(&dev->usb->usbstat) & BIT(SUPER_SPEED_MODE))) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002622 /*
2623 * Connection is NOT SS:
2624 * - Connection must be FS or HS.
2625 * - This FSM state should allow workaround software to
2626 * run after the next USB connection.
2627 */
2628 scratch |= DEFECT7374_FSM_NON_SS_CONTROL_READ;
2629 goto restore_data_eps;
2630 }
2631
2632 /* Connection is SS: */
2633 for (ack_wait_timeout = 0;
2634 ack_wait_timeout < DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS;
2635 ack_wait_timeout++) {
2636
2637 state = readl(&dev->plregs->pl_ep_status_1)
2638 & (0xff << STATE);
2639 if ((state >= (ACK_GOOD_NORMAL << STATE)) &&
2640 (state <= (ACK_GOOD_MORE_ACKS_TO_COME << STATE))) {
2641 scratch |= DEFECT7374_FSM_SS_CONTROL_READ;
2642 break;
2643 }
2644
2645 /*
2646 * We have not yet received host's Data Phase ACK
2647 * - Wait and try again.
2648 */
2649 udelay(DEFECT_7374_PROCESSOR_WAIT_TIME);
2650
2651 continue;
2652 }
2653
2654
2655 if (ack_wait_timeout >= DEFECT_7374_NUMBEROF_MAX_WAIT_LOOPS) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002656 ep_err(dev, "FAIL: Defect 7374 workaround waited but failed "
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002657 "to detect SS host's data phase ACK.");
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002658 ep_err(dev, "PL_EP_STATUS_1(23:16):.Expected from 0x11 to 0x16"
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002659 "got 0x%2.2x.\n", state >> STATE);
2660 } else {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002661 ep_warn(dev, "INFO: Defect 7374 workaround waited about\n"
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002662 "%duSec for Control Read Data Phase ACK\n",
2663 DEFECT_7374_PROCESSOR_WAIT_TIME * ack_wait_timeout);
2664 }
2665
2666restore_data_eps:
2667 /*
2668 * Restore data EPs to their pre-workaround settings (disabled,
2669 * initialized, and other details).
2670 */
2671 defect7374_disable_data_eps(dev);
2672
2673 set_idx_reg(dev->regs, SCRATCH, scratch);
2674
2675 return;
2676}
2677
2678static void ep_stall(struct net2280_ep *ep, int stall)
2679{
2680 struct net2280 *dev = ep->dev;
2681 u32 val;
2682 static const u32 ep_pl[9] = { 0, 3, 4, 7, 8, 2, 5, 6, 9 };
2683
2684 if (stall) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002685 writel(BIT(SET_ENDPOINT_HALT) |
2686 /* BIT(SET_NAK_PACKETS) | */
2687 BIT(CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002688 &ep->regs->ep_rsp);
2689 ep->is_halt = 1;
2690 } else {
2691 if (dev->gadget.speed == USB_SPEED_SUPER) {
2692 /*
2693 * Workaround for SS SeqNum not cleared via
2694 * Endpoint Halt (Clear) bit. select endpoint
2695 */
2696 val = readl(&dev->plregs->pl_ep_ctrl);
2697 val = (val & ~0x1f) | ep_pl[ep->num];
2698 writel(val, &dev->plregs->pl_ep_ctrl);
2699
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002700 val |= BIT(SEQUENCE_NUMBER_RESET);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002701 writel(val, &dev->plregs->pl_ep_ctrl);
2702 }
2703 val = readl(&ep->regs->ep_rsp);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002704 val |= BIT(CLEAR_ENDPOINT_HALT) |
2705 BIT(CLEAR_ENDPOINT_TOGGLE);
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02002706 writel(val,
2707 /* | BIT(CLEAR_NAK_PACKETS),*/
2708 &ep->regs->ep_rsp);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002709 ep->is_halt = 0;
2710 val = readl(&ep->regs->ep_rsp);
2711 }
2712}
2713
2714static void ep_stdrsp(struct net2280_ep *ep, int value, int wedged)
2715{
2716 /* set/clear, then synch memory views with the device */
2717 if (value) {
2718 ep->stopped = 1;
2719 if (ep->num == 0)
2720 ep->dev->protocol_stall = 1;
2721 else {
2722 if (ep->dma)
2723 ep_stop_dma(ep);
2724 ep_stall(ep, true);
2725 }
2726
2727 if (wedged)
2728 ep->wedged = 1;
2729 } else {
2730 ep->stopped = 0;
2731 ep->wedged = 0;
2732
2733 ep_stall(ep, false);
2734
2735 /* Flush the queue */
2736 if (!list_empty(&ep->queue)) {
2737 struct net2280_request *req =
2738 list_entry(ep->queue.next, struct net2280_request,
2739 queue);
2740 if (ep->dma)
2741 resume_dma(ep);
2742 else {
2743 if (ep->is_in)
2744 write_fifo(ep, &req->req);
2745 else {
2746 if (read_fifo(ep, req))
2747 done(ep, req, 0);
2748 }
2749 }
2750 }
2751 }
2752}
2753
2754static void handle_stat0_irqs_superspeed(struct net2280 *dev,
2755 struct net2280_ep *ep, struct usb_ctrlrequest r)
2756{
2757 int tmp = 0;
2758
2759#define w_value le16_to_cpu(r.wValue)
2760#define w_index le16_to_cpu(r.wIndex)
2761#define w_length le16_to_cpu(r.wLength)
2762
2763 switch (r.bRequest) {
2764 struct net2280_ep *e;
2765 u16 status;
2766
2767 case USB_REQ_SET_CONFIGURATION:
2768 dev->addressed_state = !w_value;
2769 goto usb3_delegate;
2770
2771 case USB_REQ_GET_STATUS:
2772 switch (r.bRequestType) {
2773 case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2774 status = dev->wakeup_enable ? 0x02 : 0x00;
2775 if (dev->selfpowered)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002776 status |= BIT(0);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002777 status |= (dev->u1_enable << 2 | dev->u2_enable << 3 |
2778 dev->ltm_enable << 4);
2779 writel(0, &dev->epregs[0].ep_irqenb);
2780 set_fifo_bytecount(ep, sizeof(status));
2781 writel((__force u32) status, &dev->epregs[0].ep_data);
2782 allow_status_338x(ep);
2783 break;
2784
2785 case (USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
2786 e = get_ep_by_addr(dev, w_index);
2787 if (!e)
2788 goto do_stall3;
2789 status = readl(&e->regs->ep_rsp) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002790 BIT(CLEAR_ENDPOINT_HALT);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002791 writel(0, &dev->epregs[0].ep_irqenb);
2792 set_fifo_bytecount(ep, sizeof(status));
2793 writel((__force u32) status, &dev->epregs[0].ep_data);
2794 allow_status_338x(ep);
2795 break;
2796
2797 default:
2798 goto usb3_delegate;
2799 }
2800 break;
2801
2802 case USB_REQ_CLEAR_FEATURE:
2803 switch (r.bRequestType) {
2804 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2805 if (!dev->addressed_state) {
2806 switch (w_value) {
2807 case USB_DEVICE_U1_ENABLE:
2808 dev->u1_enable = 0;
2809 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002810 ~BIT(U1_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002811 &dev->usb_ext->usbctl2);
2812 allow_status_338x(ep);
2813 goto next_endpoints3;
2814
2815 case USB_DEVICE_U2_ENABLE:
2816 dev->u2_enable = 0;
2817 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002818 ~BIT(U2_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002819 &dev->usb_ext->usbctl2);
2820 allow_status_338x(ep);
2821 goto next_endpoints3;
2822
2823 case USB_DEVICE_LTM_ENABLE:
2824 dev->ltm_enable = 0;
2825 writel(readl(&dev->usb_ext->usbctl2) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002826 ~BIT(LTM_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002827 &dev->usb_ext->usbctl2);
2828 allow_status_338x(ep);
2829 goto next_endpoints3;
2830
2831 default:
2832 break;
2833 }
2834 }
2835 if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
2836 dev->wakeup_enable = 0;
2837 writel(readl(&dev->usb->usbctl) &
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002838 ~BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002839 &dev->usb->usbctl);
2840 allow_status_338x(ep);
2841 break;
2842 }
2843 goto usb3_delegate;
2844
2845 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
2846 e = get_ep_by_addr(dev, w_index);
2847 if (!e)
2848 goto do_stall3;
2849 if (w_value != USB_ENDPOINT_HALT)
2850 goto do_stall3;
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002851 ep_vdbg(dev, "%s clear halt\n", e->ep.name);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002852 ep_stall(e, false);
2853 if (!list_empty(&e->queue) && e->td_dma)
2854 restart_dma(e);
2855 allow_status(ep);
2856 ep->stopped = 1;
2857 break;
2858
2859 default:
2860 goto usb3_delegate;
2861 }
2862 break;
2863 case USB_REQ_SET_FEATURE:
2864 switch (r.bRequestType) {
2865 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE):
2866 if (!dev->addressed_state) {
2867 switch (w_value) {
2868 case USB_DEVICE_U1_ENABLE:
2869 dev->u1_enable = 1;
2870 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002871 BIT(U1_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002872 &dev->usb_ext->usbctl2);
2873 allow_status_338x(ep);
2874 goto next_endpoints3;
2875
2876 case USB_DEVICE_U2_ENABLE:
2877 dev->u2_enable = 1;
2878 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002879 BIT(U2_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002880 &dev->usb_ext->usbctl2);
2881 allow_status_338x(ep);
2882 goto next_endpoints3;
2883
2884 case USB_DEVICE_LTM_ENABLE:
2885 dev->ltm_enable = 1;
2886 writel(readl(&dev->usb_ext->usbctl2) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002887 BIT(LTM_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002888 &dev->usb_ext->usbctl2);
2889 allow_status_338x(ep);
2890 goto next_endpoints3;
2891 default:
2892 break;
2893 }
2894 }
2895
2896 if (w_value == USB_DEVICE_REMOTE_WAKEUP) {
2897 dev->wakeup_enable = 1;
2898 writel(readl(&dev->usb->usbctl) |
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002899 BIT(DEVICE_REMOTE_WAKEUP_ENABLE),
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002900 &dev->usb->usbctl);
2901 allow_status_338x(ep);
2902 break;
2903 }
2904 goto usb3_delegate;
2905
2906 case (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT):
2907 e = get_ep_by_addr(dev, w_index);
2908 if (!e || (w_value != USB_ENDPOINT_HALT))
2909 goto do_stall3;
2910 ep_stdrsp(e, true, false);
2911 allow_status_338x(ep);
2912 break;
2913
2914 default:
2915 goto usb3_delegate;
2916 }
2917
2918 break;
2919 default:
2920
2921usb3_delegate:
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002922 ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x ep_cfg %08x\n",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002923 r.bRequestType, r.bRequest,
2924 w_value, w_index, w_length,
2925 readl(&ep->cfg->ep_cfg));
2926
2927 ep->responded = 0;
2928 spin_unlock(&dev->lock);
2929 tmp = dev->driver->setup(&dev->gadget, &r);
2930 spin_lock(&dev->lock);
2931 }
2932do_stall3:
2933 if (tmp < 0) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002934 ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002935 r.bRequestType, r.bRequest, tmp);
2936 dev->protocol_stall = 1;
2937 /* TD 9.9 Halt Endpoint test. TD 9.22 Set feature test */
2938 ep_stall(ep, true);
2939 }
2940
2941next_endpoints3:
2942
2943#undef w_value
2944#undef w_index
2945#undef w_length
2946
2947 return;
2948}
2949
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002950static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951{
2952 struct net2280_ep *ep;
2953 u32 num, scratch;
2954
2955 /* most of these don't need individual acks */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002956 stat &= ~BIT(INTA_ASSERTED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 if (!stat)
2958 return;
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002959 /* ep_dbg(dev, "irqstat0 %04x\n", stat); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960
2961 /* starting a control request? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002962 if (unlikely(stat & BIT(SETUP_PACKET_INTERRUPT))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 union {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002964 u32 raw[2];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 struct usb_ctrlrequest r;
2966 } u;
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01002967 int tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 struct net2280_request *req;
2969
2970 if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002971 u32 val = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002972 if (val & BIT(SUPER_SPEED)) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002973 dev->gadget.speed = USB_SPEED_SUPER;
2974 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
2975 EP0_SS_MAX_PACKET_SIZE);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002976 } else if (val & BIT(HIGH_SPEED)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 dev->gadget.speed = USB_SPEED_HIGH;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002978 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
2979 EP0_HS_MAX_PACKET_SIZE);
2980 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 dev->gadget.speed = USB_SPEED_FULL;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02002982 usb_ep_set_maxpacket_limit(&dev->ep[0].ep,
2983 EP0_HS_MAX_PACKET_SIZE);
2984 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002985 net2280_led_speed(dev, dev->gadget.speed);
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02002986 ep_dbg(dev, "%s\n",
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002987 usb_speed_string(dev->gadget.speed));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988 }
2989
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002990 ep = &dev->ep[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002991 ep->irqs++;
2992
2993 /* make sure any leftover request state is cleared */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02002994 stat &= ~BIT(ENDPOINT_0_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002995 while (!list_empty(&ep->queue)) {
2996 req = list_entry(ep->queue.next,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 struct net2280_request, queue);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02002998 done(ep, req, (req->req.actual == req->req.length)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999 ? 0 : -EPROTO);
3000 }
3001 ep->stopped = 0;
3002 dev->protocol_stall = 0;
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003003 if (dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003004 ep->is_halt = 0;
3005 else{
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003006 if (ep->dev->quirks & PLX_2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003007 tmp = BIT(FIFO_OVERFLOW) |
3008 BIT(FIFO_UNDERFLOW);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003009 else
3010 tmp = 0;
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003011
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003012 writel(tmp | BIT(TIMEOUT) |
3013 BIT(USB_STALL_SENT) |
3014 BIT(USB_IN_NAK_SENT) |
3015 BIT(USB_IN_ACK_RCVD) |
3016 BIT(USB_OUT_PING_NAK_SENT) |
3017 BIT(USB_OUT_ACK_SENT) |
3018 BIT(SHORT_PACKET_OUT_DONE_INTERRUPT) |
3019 BIT(SHORT_PACKET_TRANSFERRED_INTERRUPT) |
3020 BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
3021 BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
3022 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003023 BIT(DATA_IN_TOKEN_INTERRUPT),
3024 &ep->regs->ep_stat);
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003025 }
3026 u.raw[0] = readl(&dev->usb->setup0123);
3027 u.raw[1] = readl(&dev->usb->setup4567);
David Brownell901b3d72006-09-02 03:13:45 -07003028
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003029 cpu_to_le32s(&u.raw[0]);
3030 cpu_to_le32s(&u.raw[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003031
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003032 if (dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003033 defect7374_workaround(dev, u.r);
3034
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003035 tmp = 0;
3036
David Brownell01ee7d72007-05-25 20:40:14 -07003037#define w_value le16_to_cpu(u.r.wValue)
3038#define w_index le16_to_cpu(u.r.wIndex)
3039#define w_length le16_to_cpu(u.r.wLength)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040
3041 /* ack the irq */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003042 writel(BIT(SETUP_PACKET_INTERRUPT), &dev->regs->irqstat0);
3043 stat ^= BIT(SETUP_PACKET_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044
3045 /* watch control traffic at the token level, and force
3046 * synchronization before letting the status stage happen.
3047 * FIXME ignore tokens we'll NAK, until driver responds.
3048 * that'll mean a lot less irqs for some drivers.
3049 */
3050 ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0;
3051 if (ep->is_in) {
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003052 scratch = BIT(DATA_PACKET_TRANSMITTED_INTERRUPT) |
3053 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
3054 BIT(DATA_IN_TOKEN_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003055 stop_out_naking(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056 } else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003057 scratch = BIT(DATA_PACKET_RECEIVED_INTERRUPT) |
3058 BIT(DATA_OUT_PING_TOKEN_INTERRUPT) |
3059 BIT(DATA_IN_TOKEN_INTERRUPT);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003060 writel(scratch, &dev->epregs[0].ep_irqenb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061
3062 /* we made the hardware handle most lowlevel requests;
3063 * everything else goes uplevel to the gadget code.
3064 */
Alan Stern1f26e282006-11-16 10:16:00 -05003065 ep->responded = 1;
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003066
3067 if (dev->gadget.speed == USB_SPEED_SUPER) {
3068 handle_stat0_irqs_superspeed(dev, ep, u.r);
3069 goto next_endpoints;
3070 }
3071
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072 switch (u.r.bRequest) {
3073 case USB_REQ_GET_STATUS: {
3074 struct net2280_ep *e;
David Brownell320f3452005-05-07 13:05:18 -07003075 __le32 status;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076
3077 /* hw handles device and interface status */
3078 if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
3079 goto delegate;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003080 e = get_ep_by_addr(dev, w_index);
3081 if (!e || w_length > 2)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 goto do_stall;
3083
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003084 if (readl(&e->regs->ep_rsp) & BIT(SET_ENDPOINT_HALT))
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003085 status = cpu_to_le32(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 else
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003087 status = cpu_to_le32(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088
3089 /* don't bother with a request object! */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003090 writel(0, &dev->epregs[0].ep_irqenb);
3091 set_fifo_bytecount(ep, w_length);
3092 writel((__force u32)status, &dev->epregs[0].ep_data);
3093 allow_status(ep);
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003094 ep_vdbg(dev, "%s stat %02x\n", ep->ep.name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 goto next_endpoints;
3096 }
3097 break;
3098 case USB_REQ_CLEAR_FEATURE: {
3099 struct net2280_ep *e;
3100
3101 /* hw handles device features */
3102 if (u.r.bRequestType != USB_RECIP_ENDPOINT)
3103 goto delegate;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003104 if (w_value != USB_ENDPOINT_HALT || w_length != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003106 e = get_ep_by_addr(dev, w_index);
3107 if (!e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 goto do_stall;
Alan Stern80661342008-08-14 15:49:11 -04003109 if (e->wedged) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003110 ep_vdbg(dev, "%s wedged, halt not cleared\n",
Alan Stern80661342008-08-14 15:49:11 -04003111 ep->ep.name);
3112 } else {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003113 ep_vdbg(dev, "%s clear halt\n", e->ep.name);
Alan Stern80661342008-08-14 15:49:11 -04003114 clear_halt(e);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003115 if ((ep->dev->quirks & PLX_SUPERSPEED) &&
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003116 !list_empty(&e->queue) && e->td_dma)
3117 restart_dma(e);
Alan Stern80661342008-08-14 15:49:11 -04003118 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003119 allow_status(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120 goto next_endpoints;
3121 }
3122 break;
3123 case USB_REQ_SET_FEATURE: {
3124 struct net2280_ep *e;
3125
3126 /* hw handles device features */
3127 if (u.r.bRequestType != USB_RECIP_ENDPOINT)
3128 goto delegate;
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003129 if (w_value != USB_ENDPOINT_HALT || w_length != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003131 e = get_ep_by_addr(dev, w_index);
3132 if (!e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133 goto do_stall;
Alan Stern80661342008-08-14 15:49:11 -04003134 if (e->ep.name == ep0name)
3135 goto do_stall;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003136 set_halt(e);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003137 if ((dev->quirks & PLX_SUPERSPEED) && e->dma)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003138 abort_dma(e);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003139 allow_status(ep);
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003140 ep_vdbg(dev, "%s set halt\n", ep->ep.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 goto next_endpoints;
3142 }
3143 break;
3144 default:
3145delegate:
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003146 ep_vdbg(dev, "setup %02x.%02x v%04x i%04x l%04x "
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 "ep_cfg %08x\n",
3148 u.r.bRequestType, u.r.bRequest,
David Brownell320f3452005-05-07 13:05:18 -07003149 w_value, w_index, w_length,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003150 readl(&ep->cfg->ep_cfg));
Alan Stern1f26e282006-11-16 10:16:00 -05003151 ep->responded = 0;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003152 spin_unlock(&dev->lock);
3153 tmp = dev->driver->setup(&dev->gadget, &u.r);
3154 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003155 }
3156
3157 /* stall ep0 on error */
3158 if (tmp < 0) {
3159do_stall:
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003160 ep_vdbg(dev, "req %02x.%02x protocol STALL; stat %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 u.r.bRequestType, u.r.bRequest, tmp);
3162 dev->protocol_stall = 1;
3163 }
3164
3165 /* some in/out token irq should follow; maybe stall then.
3166 * driver must queue a request (even zlp) or halt ep0
3167 * before the host times out.
3168 */
3169 }
3170
David Brownell320f3452005-05-07 13:05:18 -07003171#undef w_value
3172#undef w_index
3173#undef w_length
3174
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175next_endpoints:
3176 /* endpoint data irq ? */
3177 scratch = stat & 0x7f;
3178 stat &= ~0x7f;
3179 for (num = 0; scratch; num++) {
3180 u32 t;
3181
3182 /* do this endpoint's FIFO and queue need tending? */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003183 t = BIT(num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184 if ((scratch & t) == 0)
3185 continue;
3186 scratch ^= t;
3187
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003188 ep = &dev->ep[num];
3189 handle_ep_small(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 }
3191
3192 if (stat)
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003193 ep_dbg(dev, "unhandled irqstat0 %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194}
3195
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003196#define DMA_INTERRUPTS (BIT(DMA_D_INTERRUPT) | \
3197 BIT(DMA_C_INTERRUPT) | \
3198 BIT(DMA_B_INTERRUPT) | \
3199 BIT(DMA_A_INTERRUPT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200#define PCI_ERROR_INTERRUPTS ( \
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003201 BIT(PCI_MASTER_ABORT_RECEIVED_INTERRUPT) | \
3202 BIT(PCI_TARGET_ABORT_RECEIVED_INTERRUPT) | \
3203 BIT(PCI_RETRY_ABORT_INTERRUPT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003204
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003205static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206{
3207 struct net2280_ep *ep;
3208 u32 tmp, num, mask, scratch;
3209
3210 /* after disconnect there's nothing else to do! */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003211 tmp = BIT(VBUS_INTERRUPT) | BIT(ROOT_PORT_RESET_INTERRUPT);
3212 mask = BIT(SUPER_SPEED) | BIT(HIGH_SPEED) | BIT(FULL_SPEED);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003213
3214 /* VBUS disconnect is indicated by VBUS_PIN and VBUS_INTERRUPT set.
Vitaliy Ivanovfb914eb2011-06-23 20:01:55 +03003215 * Root Port Reset is indicated by ROOT_PORT_RESET_INTERRUPT set and
David Brownell901b3d72006-09-02 03:13:45 -07003216 * both HIGH_SPEED and FULL_SPEED clear (as ROOT_PORT_RESET_INTERRUPT
Linus Torvalds1da177e2005-04-16 15:20:36 -07003217 * only indicates a change in the reset state).
3218 */
3219 if (stat & tmp) {
Alan Sternb611e422014-11-06 14:27:56 +08003220 bool reset = false;
3221 bool disconnect = false;
3222
3223 /*
3224 * Ignore disconnects and resets if the speed hasn't been set.
3225 * VBUS can bounce and there's always an initial reset.
3226 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003227 writel(tmp, &dev->regs->irqstat1);
Alan Sternb611e422014-11-06 14:27:56 +08003228 if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
3229 if ((stat & BIT(VBUS_INTERRUPT)) &&
3230 (readl(&dev->usb->usbctl) &
3231 BIT(VBUS_PIN)) == 0) {
3232 disconnect = true;
3233 ep_dbg(dev, "disconnect %s\n",
3234 dev->driver->driver.name);
3235 } else if ((stat & BIT(ROOT_PORT_RESET_INTERRUPT)) &&
3236 (readl(&dev->usb->usbstat) & mask)
3237 == 0) {
3238 reset = true;
3239 ep_dbg(dev, "reset %s\n",
3240 dev->driver->driver.name);
3241 }
3242
3243 if (disconnect || reset) {
3244 stop_activity(dev, dev->driver);
3245 ep0_start(dev);
3246 spin_unlock(&dev->lock);
3247 if (reset)
3248 usb_gadget_udc_reset
3249 (&dev->gadget, dev->driver);
3250 else
3251 (dev->driver->disconnect)
3252 (&dev->gadget);
3253 spin_lock(&dev->lock);
3254 return;
3255 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256 }
3257 stat &= ~tmp;
3258
3259 /* vBUS can bounce ... one of many reasons to ignore the
3260 * notion of hotplug events on bus connect/disconnect!
3261 */
3262 if (!stat)
3263 return;
3264 }
3265
3266 /* NOTE: chip stays in PCI D0 state for now, but it could
3267 * enter D1 to save more power
3268 */
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003269 tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003270 if (stat & tmp) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003271 writel(tmp, &dev->regs->irqstat1);
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003272 if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 if (dev->driver->suspend)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003274 dev->driver->suspend(&dev->gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003275 if (!enable_suspend)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003276 stat &= ~BIT(SUSPEND_REQUEST_INTERRUPT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277 } else {
3278 if (dev->driver->resume)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003279 dev->driver->resume(&dev->gadget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003280 /* at high speed, note erratum 0133 */
3281 }
3282 stat &= ~tmp;
3283 }
3284
3285 /* clear any other status/irqs */
3286 if (stat)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003287 writel(stat, &dev->regs->irqstat1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003288
3289 /* some status we can just ignore */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003290 if (dev->quirks & PLX_2280)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003291 stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
3292 BIT(SUSPEND_REQUEST_INTERRUPT) |
3293 BIT(RESUME_INTERRUPT) |
3294 BIT(SOF_INTERRUPT));
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003295 else
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003296 stat &= ~(BIT(CONTROL_STATUS_INTERRUPT) |
3297 BIT(RESUME_INTERRUPT) |
3298 BIT(SOF_DOWN_INTERRUPT) |
3299 BIT(SOF_INTERRUPT));
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003300
Linus Torvalds1da177e2005-04-16 15:20:36 -07003301 if (!stat)
3302 return;
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003303 /* ep_dbg(dev, "irqstat1 %08x\n", stat);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003304
3305 /* DMA status, for ep-{a,b,c,d} */
3306 scratch = stat & DMA_INTERRUPTS;
3307 stat &= ~DMA_INTERRUPTS;
3308 scratch >>= 9;
3309 for (num = 0; scratch; num++) {
3310 struct net2280_dma_regs __iomem *dma;
3311
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003312 tmp = BIT(num);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003313 if ((tmp & scratch) == 0)
3314 continue;
3315 scratch ^= tmp;
3316
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003317 ep = &dev->ep[num + 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -07003318 dma = ep->dma;
3319
3320 if (!dma)
3321 continue;
3322
3323 /* clear ep's dma status */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003324 tmp = readl(&dma->dmastat);
3325 writel(tmp, &dma->dmastat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003327 /* dma sync*/
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003328 if (dev->quirks & PLX_SUPERSPEED) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003329 u32 r_dmacount = readl(&dma->dmacount);
3330 if (!ep->is_in && (r_dmacount & 0x00FFFFFF) &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003331 (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT)))
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003332 continue;
3333 }
3334
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01003335 if (!(tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT))) {
3336 ep_dbg(ep->dev, "%s no xact done? %08x\n",
3337 ep->ep.name, tmp);
3338 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003339 }
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01003340 stop_dma(ep->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003341
3342 /* OUT transfers terminate when the data from the
3343 * host is in our memory. Process whatever's done.
3344 * On this path, we know transfer's last packet wasn't
3345 * less than req->length. NAK_OUT_PACKETS may be set,
3346 * or the FIFO may already be holding new packets.
3347 *
3348 * IN transfers can linger in the FIFO for a very
3349 * long time ... we ignore that for now, accounting
3350 * precisely (like PIO does) needs per-packet irqs
3351 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003352 scan_dma_completions(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353
3354 /* disable dma on inactive queues; else maybe restart */
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01003355 if (!list_empty(&ep->queue)) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003356 tmp = readl(&dma->dmactl);
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01003357 restart_dma(ep);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003358 }
3359 ep->irqs++;
3360 }
3361
3362 /* NOTE: there are other PCI errors we might usefully notice.
3363 * if they appear very often, here's where to try recovering.
3364 */
3365 if (stat & PCI_ERROR_INTERRUPTS) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003366 ep_err(dev, "pci dma error; stat %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367 stat &= ~PCI_ERROR_INTERRUPTS;
3368 /* these are fatal errors, but "maybe" they won't
3369 * happen again ...
3370 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003371 stop_activity(dev, dev->driver);
3372 ep0_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 stat = 0;
3374 }
3375
3376 if (stat)
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003377 ep_dbg(dev, "unhandled irqstat1 %08x\n", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003378}
3379
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003380static irqreturn_t net2280_irq(int irq, void *_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003381{
3382 struct net2280 *dev = _dev;
3383
Alan Stern658ad5e2006-04-14 16:44:11 -04003384 /* shared interrupt, not ours */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003385 if ((dev->quirks & PLX_LEGACY) &&
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003386 (!(readl(&dev->regs->irqstat0) & BIT(INTA_ASSERTED))))
Alan Stern658ad5e2006-04-14 16:44:11 -04003387 return IRQ_NONE;
3388
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003389 spin_lock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003390
3391 /* handle disconnect, dma, and more */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003392 handle_stat1_irqs(dev, readl(&dev->regs->irqstat1));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003393
3394 /* control requests and PIO */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003395 handle_stat0_irqs(dev, readl(&dev->regs->irqstat0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003396
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003397 if (dev->quirks & PLX_SUPERSPEED) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003398 /* re-enable interrupt to trigger any possible new interrupt */
3399 u32 pciirqenb1 = readl(&dev->regs->pciirqenb1);
3400 writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1);
3401 writel(pciirqenb1, &dev->regs->pciirqenb1);
3402 }
3403
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003404 spin_unlock(&dev->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003405
3406 return IRQ_HANDLED;
3407}
3408
3409/*-------------------------------------------------------------------------*/
3410
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003411static void gadget_release(struct device *_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003413 struct net2280 *dev = dev_get_drvdata(_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003414
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003415 kfree(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003416}
3417
3418/* tear down the binding between this driver and the pci device */
3419
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003420static void net2280_remove(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003421{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003422 struct net2280 *dev = pci_get_drvdata(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003423
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003424 usb_del_gadget_udc(&dev->gadget);
3425
David Brownell6bea4762006-12-05 03:15:33 -08003426 BUG_ON(dev->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003427
3428 /* then clean up the resources we allocated during probe() */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003429 net2280_led_shutdown(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430 if (dev->requests) {
3431 int i;
3432 for (i = 1; i < 5; i++) {
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003433 if (!dev->ep[i].dummy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003434 continue;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003435 pci_pool_free(dev->requests, dev->ep[i].dummy,
3436 dev->ep[i].td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003437 }
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003438 pci_pool_destroy(dev->requests);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003439 }
3440 if (dev->got_irq)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003441 free_irq(pdev->irq, dev);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003442 if (use_msi && dev->quirks & PLX_SUPERSPEED)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003443 pci_disable_msi(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003444 if (dev->regs)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003445 iounmap(dev->regs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003446 if (dev->region)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003447 release_mem_region(pci_resource_start(pdev, 0),
3448 pci_resource_len(pdev, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003449 if (dev->enabled)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003450 pci_disable_device(pdev);
3451 device_remove_file(&pdev->dev, &dev_attr_registers);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003452
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003453 ep_info(dev, "unbind\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003454}
3455
3456/* wrap this driver around the specified device, but
3457 * don't respond over USB until a gadget driver binds to us.
3458 */
3459
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003460static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461{
3462 struct net2280 *dev;
3463 unsigned long resource, len;
3464 void __iomem *base = NULL;
3465 int retval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466
Linus Torvalds1da177e2005-04-16 15:20:36 -07003467 /* alloc, and start init */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003468 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
3469 if (dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003470 retval = -ENOMEM;
3471 goto done;
3472 }
3473
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003474 pci_set_drvdata(pdev, dev);
3475 spin_lock_init(&dev->lock);
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003476 dev->quirks = id->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003477 dev->pdev = pdev;
3478 dev->gadget.ops = &net2280_ops;
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003479 dev->gadget.max_speed = (dev->quirks & PLX_SUPERSPEED) ?
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003480 USB_SPEED_SUPER : USB_SPEED_HIGH;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003481
3482 /* the "gadget" abstracts/virtualizes the controller */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003483 dev->gadget.name = driver_name;
3484
3485 /* now all the pci goodies ... */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003486 if (pci_enable_device(pdev) < 0) {
3487 retval = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003488 goto done;
3489 }
3490 dev->enabled = 1;
3491
3492 /* BAR 0 holds all the registers
3493 * BAR 1 is 8051 memory; unused here (note erratum 0103)
3494 * BAR 2 is fifo memory; unused here
3495 */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003496 resource = pci_resource_start(pdev, 0);
3497 len = pci_resource_len(pdev, 0);
3498 if (!request_mem_region(resource, len, driver_name)) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003499 ep_dbg(dev, "controller already in use\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 retval = -EBUSY;
3501 goto done;
3502 }
3503 dev->region = 1;
3504
David Brownell901b3d72006-09-02 03:13:45 -07003505 /* FIXME provide firmware download interface to put
3506 * 8051 code into the chip, e.g. to turn on PCI PM.
3507 */
3508
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003509 base = ioremap_nocache(resource, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003510 if (base == NULL) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003511 ep_dbg(dev, "can't map memory\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003512 retval = -EFAULT;
3513 goto done;
3514 }
3515 dev->regs = (struct net2280_regs __iomem *) base;
3516 dev->usb = (struct net2280_usb_regs __iomem *) (base + 0x0080);
3517 dev->pci = (struct net2280_pci_regs __iomem *) (base + 0x0100);
3518 dev->dma = (struct net2280_dma_regs __iomem *) (base + 0x0180);
3519 dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200);
3520 dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300);
3521
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003522 if (dev->quirks & PLX_SUPERSPEED) {
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003523 u32 fsmvalue;
3524 u32 usbstat;
3525 dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *)
3526 (base + 0x00b4);
3527 dev->fiforegs = (struct usb338x_fifo_regs __iomem *)
3528 (base + 0x0500);
3529 dev->llregs = (struct usb338x_ll_regs __iomem *)
3530 (base + 0x0700);
3531 dev->ll_lfps_regs = (struct usb338x_ll_lfps_regs __iomem *)
3532 (base + 0x0748);
3533 dev->ll_tsn_regs = (struct usb338x_ll_tsn_regs __iomem *)
3534 (base + 0x077c);
3535 dev->ll_chicken_reg = (struct usb338x_ll_chi_regs __iomem *)
3536 (base + 0x079c);
3537 dev->plregs = (struct usb338x_pl_regs __iomem *)
3538 (base + 0x0800);
3539 usbstat = readl(&dev->usb->usbstat);
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003540 dev->enhanced_mode = !!(usbstat & BIT(11));
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003541 dev->n_ep = (dev->enhanced_mode) ? 9 : 5;
3542 /* put into initial config, link up all endpoints */
3543 fsmvalue = get_idx_reg(dev->regs, SCRATCH) &
3544 (0xf << DEFECT7374_FSM_FIELD);
3545 /* See if firmware needs to set up for workaround: */
3546 if (fsmvalue == DEFECT7374_FSM_SS_CONTROL_READ)
3547 writel(0, &dev->usb->usbctl);
3548 } else{
3549 dev->enhanced_mode = 0;
3550 dev->n_ep = 7;
3551 /* put into initial config, link up all endpoints */
3552 writel(0, &dev->usb->usbctl);
3553 }
3554
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003555 usb_reset(dev);
3556 usb_reinit(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003557
3558 /* irq setup after old hardware is cleaned up */
3559 if (!pdev->irq) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003560 ep_err(dev, "No IRQ. Check PCI setup!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003561 retval = -ENODEV;
3562 goto done;
3563 }
David S. Millerc6387a42006-06-20 01:21:29 -07003564
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003565 if (use_msi && (dev->quirks & PLX_SUPERSPEED))
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003566 if (pci_enable_msi(pdev))
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003567 ep_err(dev, "Failed to enable MSI mode\n");
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003568
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003569 if (request_irq(pdev->irq, net2280_irq, IRQF_SHARED,
3570 driver_name, dev)) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003571 ep_err(dev, "request interrupt %d failed\n", pdev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003572 retval = -EBUSY;
3573 goto done;
3574 }
3575 dev->got_irq = 1;
3576
3577 /* DMA setup */
3578 /* NOTE: we know only the 32 LSBs of dma addresses may be nonzero */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003579 dev->requests = pci_pool_create("requests", pdev,
3580 sizeof(struct net2280_dma),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003581 0 /* no alignment requirements */,
3582 0 /* or page-crossing issues */);
3583 if (!dev->requests) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003584 ep_dbg(dev, "can't get request pool\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003585 retval = -ENOMEM;
3586 goto done;
3587 }
3588 for (i = 1; i < 5; i++) {
3589 struct net2280_dma *td;
3590
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003591 td = pci_pool_alloc(dev->requests, GFP_KERNEL,
3592 &dev->ep[i].td_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003593 if (!td) {
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003594 ep_dbg(dev, "can't get dummy %d\n", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003595 retval = -ENOMEM;
3596 goto done;
3597 }
3598 td->dmacount = 0; /* not VALID */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003599 td->dmadesc = td->dmaaddr;
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003600 dev->ep[i].dummy = td;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003601 }
3602
3603 /* enable lower-overhead pci memory bursts during DMA */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003604 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgado3e76fdc2014-05-20 18:30:05 +02003605 writel(BIT(DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE) |
3606 /*
3607 * 256 write retries may not be enough...
3608 BIT(PCI_RETRY_ABORT_ENABLE) |
3609 */
3610 BIT(DMA_READ_MULTIPLE_ENABLE) |
3611 BIT(DMA_READ_LINE_ENABLE),
3612 &dev->pci->pcimstctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003613 /* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003614 pci_set_master(pdev);
3615 pci_try_set_mwi(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003616
3617 /* ... also flushes any posted pci writes */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003618 dev->chiprev = get_idx_reg(dev->regs, REG_CHIPREV) & 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003619
3620 /* done */
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003621 ep_info(dev, "%s\n", driver_desc);
3622 ep_info(dev, "irq %d, pci mem %p, chip rev %04x\n",
David S. Millerc6387a42006-06-20 01:21:29 -07003623 pdev->irq, base, dev->chiprev);
Ricardo Ribalda Delgadoe56e69c2014-05-20 18:30:11 +02003624 ep_info(dev, "version: " DRIVER_VERSION "; dma %s %s\n",
Ricardo Ribalda Delgado90664192014-11-28 14:50:46 +01003625 use_dma ? "enabled" : "disabled",
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003626 dev->enhanced_mode ? "enhanced mode" : "legacy mode");
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003627 retval = device_create_file(&pdev->dev, &dev_attr_registers);
3628 if (retval)
3629 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003630
Felipe Balbi2901df62013-02-26 15:15:27 +02003631 retval = usb_add_gadget_udc_release(&pdev->dev, &dev->gadget,
3632 gadget_release);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003633 if (retval)
3634 goto done;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003635 return 0;
3636
3637done:
3638 if (dev)
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003639 net2280_remove(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 return retval;
3641}
3642
Alan Stern2d61bde2006-05-05 16:23:42 -04003643/* make sure the board is quiescent; otherwise it will continue
3644 * generating IRQs across the upcoming reboot.
3645 */
3646
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003647static void net2280_shutdown(struct pci_dev *pdev)
Alan Stern2d61bde2006-05-05 16:23:42 -04003648{
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003649 struct net2280 *dev = pci_get_drvdata(pdev);
Alan Stern2d61bde2006-05-05 16:23:42 -04003650
3651 /* disable IRQs */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003652 writel(0, &dev->regs->pciirqenb0);
3653 writel(0, &dev->regs->pciirqenb1);
Alan Stern2d61bde2006-05-05 16:23:42 -04003654
3655 /* disable the pullup so the host will think we're gone */
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003656 writel(0, &dev->usb->usbctl);
Alan Stern2f076072013-01-30 16:40:14 -05003657
3658 /* Disable full-speed test mode */
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003659 if (dev->quirks & PLX_LEGACY)
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003660 writel(0, &dev->usb->xcvrdiag);
Alan Stern2d61bde2006-05-05 16:23:42 -04003661}
3662
Linus Torvalds1da177e2005-04-16 15:20:36 -07003663
3664/*-------------------------------------------------------------------------*/
3665
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003666static const struct pci_device_id pci_ids[] = { {
David Brownell901b3d72006-09-02 03:13:45 -07003667 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3668 .class_mask = ~0,
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003669 .vendor = PCI_VENDOR_ID_PLX_LEGACY,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003670 .device = 0x2280,
3671 .subvendor = PCI_ANY_ID,
3672 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003673 .driver_data = PLX_LEGACY | PLX_2280,
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003674 }, {
David Brownell901b3d72006-09-02 03:13:45 -07003675 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3676 .class_mask = ~0,
Ricardo Ribalda Delgadoc2db8a82014-05-20 18:30:04 +02003677 .vendor = PCI_VENDOR_ID_PLX_LEGACY,
Guennadi Liakhovetski950ee4c2006-03-19 20:49:14 +01003678 .device = 0x2282,
3679 .subvendor = PCI_ANY_ID,
3680 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003681 .driver_data = PLX_LEGACY,
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003682 },
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003683 {
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003684 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3685 .class_mask = ~0,
3686 .vendor = PCI_VENDOR_ID_PLX,
3687 .device = 0x3380,
3688 .subvendor = PCI_ANY_ID,
3689 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003690 .driver_data = PLX_SUPERSPEED,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003691 },
3692 {
Ricardo Ribalda Delgadoae8e5302014-05-20 18:30:10 +02003693 .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
3694 .class_mask = ~0,
3695 .vendor = PCI_VENDOR_ID_PLX,
3696 .device = 0x3382,
3697 .subvendor = PCI_ANY_ID,
3698 .subdevice = PCI_ANY_ID,
Ricardo Ribalda Delgado2eeb0012014-05-20 18:30:12 +02003699 .driver_data = PLX_SUPERSPEED,
Ricardo Ribalda Delgadoadc82f72014-05-20 18:30:03 +02003700 },
3701{ /* end: all zeroes */ }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003702};
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003703MODULE_DEVICE_TABLE(pci, pci_ids);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704
3705/* pci driver glue; this is a "new style" PCI driver module */
3706static struct pci_driver net2280_pci_driver = {
3707 .name = (char *) driver_name,
3708 .id_table = pci_ids,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709
3710 .probe = net2280_probe,
3711 .remove = net2280_remove,
Alan Stern2d61bde2006-05-05 16:23:42 -04003712 .shutdown = net2280_shutdown,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713
3714 /* FIXME add power management support */
3715};
3716
Ricardo Ribalda Delgado9a028e42014-05-20 18:30:07 +02003717module_pci_driver(net2280_pci_driver);
3718
Ricardo Ribalda Delgadofae3c152014-05-20 18:30:09 +02003719MODULE_DESCRIPTION(DRIVER_DESC);
3720MODULE_AUTHOR("David Brownell");
3721MODULE_LICENSE("GPL");