Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
0004  */
0005 
0006 #include <linux/kernel.h>
0007 #include <linux/module.h>
0008 #include <linux/usb.h>
0009 
0010 #include "mt7601u.h"
0011 #include "usb.h"
0012 #include "trace.h"
0013 
0014 static const struct usb_device_id mt7601u_device_table[] = {
0015     { USB_DEVICE(0x0b05, 0x17d3) },
0016     { USB_DEVICE(0x0e8d, 0x760a) },
0017     { USB_DEVICE(0x0e8d, 0x760b) },
0018     { USB_DEVICE(0x13d3, 0x3431) },
0019     { USB_DEVICE(0x13d3, 0x3434) },
0020     { USB_DEVICE(0x148f, 0x7601) },
0021     { USB_DEVICE(0x148f, 0x760a) },
0022     { USB_DEVICE(0x148f, 0x760b) },
0023     { USB_DEVICE(0x148f, 0x760c) },
0024     { USB_DEVICE(0x148f, 0x760d) },
0025     { USB_DEVICE(0x2001, 0x3d04) },
0026     { USB_DEVICE(0x2717, 0x4106) },
0027     { USB_DEVICE(0x2955, 0x0001) },
0028     { USB_DEVICE(0x2955, 0x1001) },
0029     { USB_DEVICE(0x2955, 0x1003) },
0030     { USB_DEVICE(0x2a5f, 0x1000) },
0031     { USB_DEVICE(0x7392, 0x7710) },
0032     { 0, }
0033 };
0034 
0035 bool mt7601u_usb_alloc_buf(struct mt7601u_dev *dev, size_t len,
0036                struct mt7601u_dma_buf *buf)
0037 {
0038     struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
0039 
0040     buf->len = len;
0041     buf->urb = usb_alloc_urb(0, GFP_KERNEL);
0042     buf->buf = usb_alloc_coherent(usb_dev, buf->len, GFP_KERNEL, &buf->dma);
0043 
0044     return !buf->urb || !buf->buf;
0045 }
0046 
0047 void mt7601u_usb_free_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf *buf)
0048 {
0049     struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
0050 
0051     usb_free_coherent(usb_dev, buf->len, buf->buf, buf->dma);
0052     usb_free_urb(buf->urb);
0053 }
0054 
0055 int mt7601u_usb_submit_buf(struct mt7601u_dev *dev, int dir, int ep_idx,
0056                struct mt7601u_dma_buf *buf, gfp_t gfp,
0057                usb_complete_t complete_fn, void *context)
0058 {
0059     struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
0060     unsigned pipe;
0061     int ret;
0062 
0063     if (dir == USB_DIR_IN)
0064         pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[ep_idx]);
0065     else
0066         pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep_idx]);
0067 
0068     usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len,
0069               complete_fn, context);
0070     buf->urb->transfer_dma = buf->dma;
0071     buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0072 
0073     trace_mt_submit_urb(dev, buf->urb);
0074     ret = usb_submit_urb(buf->urb, gfp);
0075     if (ret)
0076         dev_err(dev->dev, "Error: submit URB dir:%d ep:%d failed:%d\n",
0077             dir, ep_idx, ret);
0078     return ret;
0079 }
0080 
0081 void mt7601u_complete_urb(struct urb *urb)
0082 {
0083     struct completion *cmpl = urb->context;
0084 
0085     complete(cmpl);
0086 }
0087 
0088 int mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req,
0089                const u8 direction, const u16 val, const u16 offset,
0090                void *buf, const size_t buflen)
0091 {
0092     int i, ret;
0093     struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
0094     const u8 req_type = direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
0095     const unsigned int pipe = (direction == USB_DIR_IN) ?
0096         usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
0097 
0098     for (i = 0; i < MT_VEND_REQ_MAX_RETRY; i++) {
0099         ret = usb_control_msg(usb_dev, pipe, req, req_type,
0100                       val, offset, buf, buflen,
0101                       MT_VEND_REQ_TOUT_MS);
0102         trace_mt_vend_req(dev, pipe, req, req_type, val, offset,
0103                   buf, buflen, ret);
0104 
0105         if (ret == -ENODEV)
0106             set_bit(MT7601U_STATE_REMOVED, &dev->state);
0107         if (ret >= 0 || ret == -ENODEV)
0108             return ret;
0109 
0110         msleep(5);
0111     }
0112 
0113     dev_err(dev->dev, "Vendor request req:%02x off:%04x failed:%d\n",
0114         req, offset, ret);
0115 
0116     return ret;
0117 }
0118 
0119 void mt7601u_vendor_reset(struct mt7601u_dev *dev)
0120 {
0121     mt7601u_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT,
0122                    MT_VEND_DEV_MODE_RESET, 0, NULL, 0);
0123 }
0124 
0125 /* should be called with vendor_req_mutex held */
0126 static u32 __mt7601u_rr(struct mt7601u_dev *dev, u32 offset)
0127 {
0128     int ret;
0129     u32 val = ~0;
0130 
0131     WARN_ONCE(offset > USHRT_MAX, "read high off:%08x", offset);
0132 
0133     ret = mt7601u_vendor_request(dev, MT_VEND_MULTI_READ, USB_DIR_IN,
0134                      0, offset, dev->vend_buf, MT_VEND_BUF);
0135     if (ret == MT_VEND_BUF)
0136         val = get_unaligned_le32(dev->vend_buf);
0137     else if (ret > 0)
0138         dev_err(dev->dev, "Error: wrong size read:%d off:%08x\n",
0139             ret, offset);
0140 
0141     trace_reg_read(dev, offset, val);
0142     return val;
0143 }
0144 
0145 u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset)
0146 {
0147     u32 ret;
0148 
0149     mutex_lock(&dev->vendor_req_mutex);
0150     ret = __mt7601u_rr(dev, offset);
0151     mutex_unlock(&dev->vendor_req_mutex);
0152 
0153     return ret;
0154 }
0155 
0156 /* should be called with vendor_req_mutex held */
0157 static int __mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req,
0158                       const u16 offset, const u32 val)
0159 {
0160     int ret = mt7601u_vendor_request(dev, req, USB_DIR_OUT,
0161                      val & 0xffff, offset, NULL, 0);
0162     if (!ret)
0163         ret = mt7601u_vendor_request(dev, req, USB_DIR_OUT,
0164                          val >> 16, offset + 2, NULL, 0);
0165     trace_reg_write(dev, offset, val);
0166     return ret;
0167 }
0168 
0169 int mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req,
0170                  const u16 offset, const u32 val)
0171 {
0172     int ret;
0173 
0174     mutex_lock(&dev->vendor_req_mutex);
0175     ret = __mt7601u_vendor_single_wr(dev, req, offset, val);
0176     mutex_unlock(&dev->vendor_req_mutex);
0177 
0178     return ret;
0179 }
0180 
0181 void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val)
0182 {
0183     WARN_ONCE(offset > USHRT_MAX, "write high off:%08x", offset);
0184 
0185     mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val);
0186 }
0187 
0188 u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val)
0189 {
0190     mutex_lock(&dev->vendor_req_mutex);
0191     val |= __mt7601u_rr(dev, offset) & ~mask;
0192     __mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val);
0193     mutex_unlock(&dev->vendor_req_mutex);
0194 
0195     return val;
0196 }
0197 
0198 u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val)
0199 {
0200     u32 reg;
0201 
0202     mutex_lock(&dev->vendor_req_mutex);
0203     reg = __mt7601u_rr(dev, offset);
0204     val |= reg & ~mask;
0205     if (reg != val)
0206         __mt7601u_vendor_single_wr(dev, MT_VEND_WRITE,
0207                        offset, val);
0208     mutex_unlock(&dev->vendor_req_mutex);
0209 
0210     return val;
0211 }
0212 
0213 void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset,
0214              const void *data, int len)
0215 {
0216     WARN_ONCE(offset & 3, "unaligned write copy off:%08x", offset);
0217     WARN_ONCE(len & 3, "short write copy off:%08x", offset);
0218 
0219     mt7601u_burst_write_regs(dev, offset, data, len / 4);
0220 }
0221 
0222 void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr)
0223 {
0224     mt7601u_wr(dev, offset, get_unaligned_le32(addr));
0225     mt7601u_wr(dev, offset + 4, addr[4] | addr[5] << 8);
0226 }
0227 
0228 static int mt7601u_assign_pipes(struct usb_interface *usb_intf,
0229                 struct mt7601u_dev *dev)
0230 {
0231     struct usb_endpoint_descriptor *ep_desc;
0232     struct usb_host_interface *intf_desc = usb_intf->cur_altsetting;
0233     unsigned i, ep_i = 0, ep_o = 0;
0234 
0235     BUILD_BUG_ON(sizeof(dev->in_eps) < __MT_EP_IN_MAX);
0236     BUILD_BUG_ON(sizeof(dev->out_eps) < __MT_EP_OUT_MAX);
0237 
0238     for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
0239         ep_desc = &intf_desc->endpoint[i].desc;
0240 
0241         if (usb_endpoint_is_bulk_in(ep_desc) &&
0242             ep_i++ < __MT_EP_IN_MAX) {
0243             dev->in_eps[ep_i - 1] = usb_endpoint_num(ep_desc);
0244             dev->in_max_packet = usb_endpoint_maxp(ep_desc);
0245             /* Note: this is ignored by usb sub-system but vendor
0246              *   code does it. We can drop this at some point.
0247              */
0248             dev->in_eps[ep_i - 1] |= USB_DIR_IN;
0249         } else if (usb_endpoint_is_bulk_out(ep_desc) &&
0250                ep_o++ < __MT_EP_OUT_MAX) {
0251             dev->out_eps[ep_o - 1] = usb_endpoint_num(ep_desc);
0252             dev->out_max_packet = usb_endpoint_maxp(ep_desc);
0253         }
0254     }
0255 
0256     if (ep_i != __MT_EP_IN_MAX || ep_o != __MT_EP_OUT_MAX) {
0257         dev_err(dev->dev, "Error: wrong pipe number in:%d out:%d\n",
0258             ep_i, ep_o);
0259         return -EINVAL;
0260     }
0261 
0262     return 0;
0263 }
0264 
0265 static int mt7601u_probe(struct usb_interface *usb_intf,
0266              const struct usb_device_id *id)
0267 {
0268     struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
0269     struct mt7601u_dev *dev;
0270     u32 asic_rev, mac_rev;
0271     int ret;
0272 
0273     dev = mt7601u_alloc_device(&usb_intf->dev);
0274     if (!dev)
0275         return -ENOMEM;
0276 
0277     usb_dev = usb_get_dev(usb_dev);
0278     usb_reset_device(usb_dev);
0279 
0280     usb_set_intfdata(usb_intf, dev);
0281 
0282     dev->vend_buf = devm_kmalloc(dev->dev, MT_VEND_BUF, GFP_KERNEL);
0283     if (!dev->vend_buf) {
0284         ret = -ENOMEM;
0285         goto err;
0286     }
0287 
0288     ret = mt7601u_assign_pipes(usb_intf, dev);
0289     if (ret)
0290         goto err;
0291     ret = mt7601u_wait_asic_ready(dev);
0292     if (ret)
0293         goto err;
0294 
0295     asic_rev = mt7601u_rr(dev, MT_ASIC_VERSION);
0296     mac_rev = mt7601u_rr(dev, MT_MAC_CSR0);
0297     dev_info(dev->dev, "ASIC revision: %08x MAC revision: %08x\n",
0298          asic_rev, mac_rev);
0299     if ((asic_rev >> 16) != 0x7601) {
0300         ret = -ENODEV;
0301         goto err;
0302     }
0303 
0304     /* Note: vendor driver skips this check for MT7601U */
0305     if (!(mt7601u_rr(dev, MT_EFUSE_CTRL) & MT_EFUSE_CTRL_SEL))
0306         dev_warn(dev->dev, "Warning: eFUSE not present\n");
0307 
0308     ret = mt7601u_init_hardware(dev);
0309     if (ret)
0310         goto err;
0311     ret = mt7601u_register_device(dev);
0312     if (ret)
0313         goto err_hw;
0314 
0315     set_bit(MT7601U_STATE_INITIALIZED, &dev->state);
0316 
0317     return 0;
0318 err_hw:
0319     mt7601u_cleanup(dev);
0320 err:
0321     usb_set_intfdata(usb_intf, NULL);
0322     usb_put_dev(interface_to_usbdev(usb_intf));
0323 
0324     destroy_workqueue(dev->stat_wq);
0325     ieee80211_free_hw(dev->hw);
0326     return ret;
0327 }
0328 
0329 static void mt7601u_disconnect(struct usb_interface *usb_intf)
0330 {
0331     struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
0332 
0333     ieee80211_unregister_hw(dev->hw);
0334     mt7601u_cleanup(dev);
0335 
0336     usb_set_intfdata(usb_intf, NULL);
0337     usb_put_dev(interface_to_usbdev(usb_intf));
0338 
0339     destroy_workqueue(dev->stat_wq);
0340     ieee80211_free_hw(dev->hw);
0341 }
0342 
0343 static int mt7601u_suspend(struct usb_interface *usb_intf, pm_message_t state)
0344 {
0345     struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
0346 
0347     mt7601u_cleanup(dev);
0348 
0349     return 0;
0350 }
0351 
0352 static int mt7601u_resume(struct usb_interface *usb_intf)
0353 {
0354     struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
0355     int ret;
0356 
0357     ret = mt7601u_init_hardware(dev);
0358     if (ret)
0359         return ret;
0360 
0361     set_bit(MT7601U_STATE_INITIALIZED, &dev->state);
0362 
0363     return 0;
0364 }
0365 
0366 MODULE_DEVICE_TABLE(usb, mt7601u_device_table);
0367 MODULE_FIRMWARE(MT7601U_FIRMWARE);
0368 MODULE_LICENSE("GPL");
0369 
0370 static struct usb_driver mt7601u_driver = {
0371     .name       = KBUILD_MODNAME,
0372     .id_table   = mt7601u_device_table,
0373     .probe      = mt7601u_probe,
0374     .disconnect = mt7601u_disconnect,
0375     .suspend    = mt7601u_suspend,
0376     .resume     = mt7601u_resume,
0377     .reset_resume   = mt7601u_resume,
0378     .soft_unbind    = 1,
0379     .disable_hub_initiated_lpm = 1,
0380 };
0381 module_usb_driver(mt7601u_driver);