usb: gadget: net2280: add USB2380 support
authorTim Harvey <tharvey@gateworks.com>
Mon, 23 May 2016 13:58:41 +0000 (06:58 -0700)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 20 Jun 2016 09:30:03 +0000 (12:30 +0300)
The PLX USB2380 is a PCIe version of the NET2280 and behaves more like the
USB338x but without the USB3.0 superspeed support.

This was tested with g_ether, g_serial, g_mass_storage on a Gateworks
Ventana GW2383.

Cc: Justin DeFields <justindefields@gmail.com>
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/gadget/udc/Kconfig
drivers/usb/gadget/udc/net2280.c
drivers/usb/gadget/udc/net2280.h

index 7c289416f87dcfdc37fb4ff8cab6f58aa2c3b863..658b8da6091523c275fd225b16355fb40cdbd70e 100644 (file)
@@ -312,7 +312,7 @@ config USB_NET2272_DMA
          If unsure, say "N" here.  The driver works fine in PIO mode.
 
 config USB_NET2280
-       tristate "NetChip 228x / PLX USB338x"
+       tristate "NetChip NET228x / PLX USB3x8x"
        depends on PCI
        help
           NetChip 2280 / 2282 is a PCI based USB peripheral controller which
@@ -322,6 +322,8 @@ config USB_NET2280
           (for control transfers) and several endpoints with dedicated
           functions.
 
+          PLX 2380 is a PCIe version of the PLX 2380.
+
           PLX 3380 / 3382 is a PCIe based USB peripheral controller which
           supports full, high speed USB 2.0 and super speed USB 3.0
           data transfers.
index c894b94b234bf58aba86cea8a341abb88941e61a..614ab951a4ae6e0fca159a17ae9fd9914aedd727 100644 (file)
@@ -211,7 +211,7 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
                goto print_err;
        }
 
-       if (dev->quirks & PLX_SUPERSPEED) {
+       if (dev->quirks & PLX_PCIE) {
                if ((desc->bEndpointAddress & 0x0f) >= 0x0c) {
                        ret = -EDOM;
                        goto print_err;
@@ -245,7 +245,7 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
        /* set type, direction, address; reset fifo counters */
        writel(BIT(FIFO_FLUSH), &ep->regs->ep_stat);
 
-       if ((dev->quirks & PLX_SUPERSPEED) && dev->enhanced_mode) {
+       if ((dev->quirks & PLX_PCIE) && dev->enhanced_mode) {
                tmp = readl(&ep->cfg->ep_cfg);
                /* If USB ep number doesn't match hardware ep number */
                if ((tmp & 0xf) != usb_endpoint_num(desc)) {
@@ -316,7 +316,7 @@ net2280_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
                        BIT(CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp);
        }
 
-       if (dev->quirks & PLX_SUPERSPEED)
+       if (dev->quirks & PLX_PCIE)
                ep_clear_seqnum(ep);
        writel(tmp, &ep->cfg->ep_cfg);
 
@@ -527,7 +527,7 @@ static int net2280_disable(struct usb_ep *_ep)
        spin_lock_irqsave(&ep->dev->lock, flags);
        nuke(ep);
 
-       if (ep->dev->quirks & PLX_SUPERSPEED)
+       if (ep->dev->quirks & PLX_PCIE)
                ep_reset_338x(ep->dev->regs, ep);
        else
                ep_reset_228x(ep->dev->regs, ep);
@@ -862,7 +862,7 @@ static void start_queue(struct net2280_ep *ep, u32 dmactl, u32 td_dma)
        writel(readl(&dma->dmastat), &dma->dmastat);
 
        writel(td_dma, &dma->dmadesc);
-       if (ep->dev->quirks & PLX_SUPERSPEED)
+       if (ep->dev->quirks & PLX_PCIE)
                dmactl |= BIT(DMA_REQUEST_OUTSTANDING);
        writel(dmactl, &dma->dmactl);
 
@@ -1046,7 +1046,7 @@ net2280_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 
        /* kickstart this i/o queue? */
        if  (list_empty(&ep->queue) && !ep->stopped &&
-               !((dev->quirks & PLX_SUPERSPEED) && ep->dma &&
+               !((dev->quirks & PLX_PCIE) && ep->dma &&
                  (readl(&ep->regs->ep_rsp) & BIT(CLEAR_ENDPOINT_HALT)))) {
 
                /* use DMA if the endpoint supports it, else pio */
@@ -1169,7 +1169,7 @@ static void scan_dma_completions(struct net2280_ep *ep)
                        break;
                } else if (!ep->is_in &&
                           (req->req.length % ep->ep.maxpacket) &&
-                          !(ep->dev->quirks & PLX_SUPERSPEED)) {
+                          !(ep->dev->quirks & PLX_PCIE)) {
 
                        tmp = readl(&ep->regs->ep_stat);
                        /* AVOID TROUBLE HERE by not issuing short reads from
@@ -1367,7 +1367,7 @@ net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
                                ep->wedged = 1;
                } else {
                        clear_halt(ep);
-                       if (ep->dev->quirks & PLX_SUPERSPEED &&
+                       if (ep->dev->quirks & PLX_PCIE &&
                                !list_empty(&ep->queue) && ep->td_dma)
                                        restart_dma(ep);
                        ep->wedged = 0;
@@ -2394,7 +2394,7 @@ static int net2280_start(struct usb_gadget *_gadget,
         */
        net2280_led_active(dev, 1);
 
-       if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
+       if ((dev->quirks & PLX_PCIE) && !dev->bug7734_patched)
                defect7374_enable_data_eps_zero(dev);
 
        ep0_start(dev);
@@ -3063,7 +3063,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
                }
                ep->stopped = 0;
                dev->protocol_stall = 0;
-               if (!(dev->quirks & PLX_SUPERSPEED)) {
+               if (!(dev->quirks & PLX_PCIE)) {
                        if (ep->dev->quirks & PLX_2280)
                                tmp = BIT(FIFO_OVERFLOW) |
                                    BIT(FIFO_UNDERFLOW);
@@ -3090,7 +3090,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
                cpu_to_le32s(&u.raw[0]);
                cpu_to_le32s(&u.raw[1]);
 
-               if ((dev->quirks & PLX_SUPERSPEED) && !dev->bug7734_patched)
+               if ((dev->quirks & PLX_PCIE) && !dev->bug7734_patched)
                        defect7374_workaround(dev, u.r);
 
                tmp = 0;
@@ -3173,7 +3173,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
                        } else {
                                ep_vdbg(dev, "%s clear halt\n", e->ep.name);
                                clear_halt(e);
-                               if ((ep->dev->quirks & PLX_SUPERSPEED) &&
+                               if ((ep->dev->quirks & PLX_PCIE) &&
                                        !list_empty(&e->queue) && e->td_dma)
                                                restart_dma(e);
                        }
@@ -3195,7 +3195,7 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
                        if (e->ep.name == ep0name)
                                goto do_stall;
                        set_halt(e);
-                       if ((dev->quirks & PLX_SUPERSPEED) && e->dma)
+                       if ((dev->quirks & PLX_PCIE) && e->dma)
                                abort_dma(e);
                        allow_status(ep);
                        ep_vdbg(dev, "%s set halt\n", ep->ep.name);
@@ -3234,7 +3234,7 @@ do_stall:
 #undef w_length
 
 next_endpoints:
-       if ((dev->quirks & PLX_SUPERSPEED) && dev->enhanced_mode) {
+       if ((dev->quirks & PLX_PCIE) && dev->enhanced_mode) {
                u32 mask = (BIT(ENDPOINT_0_INTERRUPT) |
                        USB3380_IRQSTAT0_EP_INTR_MASK_IN |
                        USB3380_IRQSTAT0_EP_INTR_MASK_OUT);
@@ -3399,7 +3399,7 @@ __acquires(dev->lock)
                writel(tmp, &dma->dmastat);
 
                /* dma sync*/
-               if (dev->quirks & PLX_SUPERSPEED) {
+               if (dev->quirks & PLX_PCIE) {
                        u32 r_dmacount = readl(&dma->dmacount);
                        if (!ep->is_in &&  (r_dmacount & 0x00FFFFFF) &&
                            (tmp & BIT(DMA_TRANSACTION_DONE_INTERRUPT)))
@@ -3468,7 +3468,7 @@ static irqreturn_t net2280_irq(int irq, void *_dev)
        /* control requests and PIO */
        handle_stat0_irqs(dev, readl(&dev->regs->irqstat0));
 
-       if (dev->quirks & PLX_SUPERSPEED) {
+       if (dev->quirks & PLX_PCIE) {
                /* re-enable interrupt to trigger any possible new interrupt */
                u32 pciirqenb1 = readl(&dev->regs->pciirqenb1);
                writel(pciirqenb1 & 0x7FFFFFFF, &dev->regs->pciirqenb1);
@@ -3513,7 +3513,7 @@ static void net2280_remove(struct pci_dev *pdev)
        }
        if (dev->got_irq)
                free_irq(pdev->irq, dev);
-       if (dev->quirks & PLX_SUPERSPEED)
+       if (dev->quirks & PLX_PCIE)
                pci_disable_msi(pdev);
        if (dev->regs)
                iounmap(dev->regs);
@@ -3593,7 +3593,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        dev->dep = (struct net2280_dep_regs __iomem *) (base + 0x0200);
        dev->epregs = (struct net2280_ep_regs __iomem *) (base + 0x0300);
 
-       if (dev->quirks & PLX_SUPERSPEED) {
+       if (dev->quirks & PLX_PCIE) {
                u32 fsmvalue;
                u32 usbstat;
                dev->usb_ext = (struct usb338x_usb_ext_regs __iomem *)
@@ -3637,7 +3637,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto done;
        }
 
-       if (dev->quirks & PLX_SUPERSPEED)
+       if (dev->quirks & PLX_PCIE)
                if (pci_enable_msi(pdev))
                        ep_err(dev, "Failed to enable MSI mode\n");
 
@@ -3755,10 +3755,19 @@ static const struct pci_device_id pci_ids[] = { {
        .class =        PCI_CLASS_SERIAL_USB_DEVICE,
        .class_mask =   ~0,
        .vendor =       PCI_VENDOR_ID_PLX,
+       .device =       0x2380,
+       .subvendor =    PCI_ANY_ID,
+       .subdevice =    PCI_ANY_ID,
+       .driver_data =  PLX_PCIE,
+        },
+       {
+       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
+       .class_mask =   ~0,
+       .vendor =       PCI_VENDOR_ID_PLX,
        .device =       0x3380,
        .subvendor =    PCI_ANY_ID,
        .subdevice =    PCI_ANY_ID,
-       .driver_data =  PLX_SUPERSPEED,
+       .driver_data =  PLX_PCIE | PLX_SUPERSPEED,
         },
        {
        .class =        PCI_CLASS_SERIAL_USB_DEVICE,
@@ -3767,7 +3776,7 @@ static const struct pci_device_id pci_ids[] = { {
        .device =       0x3382,
        .subvendor =    PCI_ANY_ID,
        .subdevice =    PCI_ANY_ID,
-       .driver_data =  PLX_SUPERSPEED,
+       .driver_data =  PLX_PCIE | PLX_SUPERSPEED,
         },
 { /* end: all zeroes */ }
 };
index 0d32052bf16f90d5e1ace964cedd484c14a6f65d..2736a95751c3834fe5110f36201fa6363a00f33f 100644 (file)
@@ -47,6 +47,7 @@ set_idx_reg(struct net2280_regs __iomem *regs, u32 index, u32 value)
 #define PLX_LEGACY             BIT(0)
 #define PLX_2280               BIT(1)
 #define PLX_SUPERSPEED         BIT(2)
+#define PLX_PCIE               BIT(3)
 
 #define REG_DIAG               0x0
 #define     RETRY_COUNTER                                       16