linux/drivers/net/wireless/mediatek/mt7601u/usb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
   4 */
   5
   6#include <linux/kernel.h>
   7#include <linux/module.h>
   8#include <linux/usb.h>
   9
  10#include "mt7601u.h"
  11#include "usb.h"
  12#include "trace.h"
  13
  14static const struct usb_device_id mt7601u_device_table[] = {
  15        { USB_DEVICE(0x0b05, 0x17d3) },
  16        { USB_DEVICE(0x0e8d, 0x760a) },
  17        { USB_DEVICE(0x0e8d, 0x760b) },
  18        { USB_DEVICE(0x13d3, 0x3431) },
  19        { USB_DEVICE(0x13d3, 0x3434) },
  20        { USB_DEVICE(0x148f, 0x7601) },
  21        { USB_DEVICE(0x148f, 0x760a) },
  22        { USB_DEVICE(0x148f, 0x760b) },
  23        { USB_DEVICE(0x148f, 0x760c) },
  24        { USB_DEVICE(0x148f, 0x760d) },
  25        { USB_DEVICE(0x2001, 0x3d04) },
  26        { USB_DEVICE(0x2717, 0x4106) },
  27        { USB_DEVICE(0x2955, 0x0001) },
  28        { USB_DEVICE(0x2955, 0x1001) },
  29        { USB_DEVICE(0x2955, 0x1003) },
  30        { USB_DEVICE(0x2a5f, 0x1000) },
  31        { USB_DEVICE(0x7392, 0x7710) },
  32        { 0, }
  33};
  34
  35bool mt7601u_usb_alloc_buf(struct mt7601u_dev *dev, size_t len,
  36                           struct mt7601u_dma_buf *buf)
  37{
  38        struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
  39
  40        buf->len = len;
  41        buf->urb = usb_alloc_urb(0, GFP_KERNEL);
  42        buf->buf = usb_alloc_coherent(usb_dev, buf->len, GFP_KERNEL, &buf->dma);
  43
  44        return !buf->urb || !buf->buf;
  45}
  46
  47void mt7601u_usb_free_buf(struct mt7601u_dev *dev, struct mt7601u_dma_buf *buf)
  48{
  49        struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
  50
  51        usb_free_coherent(usb_dev, buf->len, buf->buf, buf->dma);
  52        usb_free_urb(buf->urb);
  53}
  54
  55int mt7601u_usb_submit_buf(struct mt7601u_dev *dev, int dir, int ep_idx,
  56                           struct mt7601u_dma_buf *buf, gfp_t gfp,
  57                           usb_complete_t complete_fn, void *context)
  58{
  59        struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
  60        unsigned pipe;
  61        int ret;
  62
  63        if (dir == USB_DIR_IN)
  64                pipe = usb_rcvbulkpipe(usb_dev, dev->in_eps[ep_idx]);
  65        else
  66                pipe = usb_sndbulkpipe(usb_dev, dev->out_eps[ep_idx]);
  67
  68        usb_fill_bulk_urb(buf->urb, usb_dev, pipe, buf->buf, buf->len,
  69                          complete_fn, context);
  70        buf->urb->transfer_dma = buf->dma;
  71        buf->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  72
  73        trace_mt_submit_urb(dev, buf->urb);
  74        ret = usb_submit_urb(buf->urb, gfp);
  75        if (ret)
  76                dev_err(dev->dev, "Error: submit URB dir:%d ep:%d failed:%d\n",
  77                        dir, ep_idx, ret);
  78        return ret;
  79}
  80
  81void mt7601u_complete_urb(struct urb *urb)
  82{
  83        struct completion *cmpl = urb->context;
  84
  85        complete(cmpl);
  86}
  87
  88int mt7601u_vendor_request(struct mt7601u_dev *dev, const u8 req,
  89                           const u8 direction, const u16 val, const u16 offset,
  90                           void *buf, const size_t buflen)
  91{
  92        int i, ret;
  93        struct usb_device *usb_dev = mt7601u_to_usb_dev(dev);
  94        const u8 req_type = direction | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
  95        const unsigned int pipe = (direction == USB_DIR_IN) ?
  96                usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
  97
  98        for (i = 0; i < MT_VEND_REQ_MAX_RETRY; i++) {
  99                ret = usb_control_msg(usb_dev, pipe, req, req_type,
 100                                      val, offset, buf, buflen,
 101                                      MT_VEND_REQ_TOUT_MS);
 102                trace_mt_vend_req(dev, pipe, req, req_type, val, offset,
 103                                  buf, buflen, ret);
 104
 105                if (ret == -ENODEV)
 106                        set_bit(MT7601U_STATE_REMOVED, &dev->state);
 107                if (ret >= 0 || ret == -ENODEV)
 108                        return ret;
 109
 110                msleep(5);
 111        }
 112
 113        dev_err(dev->dev, "Vendor request req:%02x off:%04x failed:%d\n",
 114                req, offset, ret);
 115
 116        return ret;
 117}
 118
 119void mt7601u_vendor_reset(struct mt7601u_dev *dev)
 120{
 121        mt7601u_vendor_request(dev, MT_VEND_DEV_MODE, USB_DIR_OUT,
 122                               MT_VEND_DEV_MODE_RESET, 0, NULL, 0);
 123}
 124
 125/* should be called with vendor_req_mutex held */
 126static u32 __mt7601u_rr(struct mt7601u_dev *dev, u32 offset)
 127{
 128        int ret;
 129        u32 val = ~0;
 130
 131        WARN_ONCE(offset > USHRT_MAX, "read high off:%08x", offset);
 132
 133        ret = mt7601u_vendor_request(dev, MT_VEND_MULTI_READ, USB_DIR_IN,
 134                                     0, offset, dev->vend_buf, MT_VEND_BUF);
 135        if (ret == MT_VEND_BUF)
 136                val = get_unaligned_le32(dev->vend_buf);
 137        else if (ret > 0)
 138                dev_err(dev->dev, "Error: wrong size read:%d off:%08x\n",
 139                        ret, offset);
 140
 141        trace_reg_read(dev, offset, val);
 142        return val;
 143}
 144
 145u32 mt7601u_rr(struct mt7601u_dev *dev, u32 offset)
 146{
 147        u32 ret;
 148
 149        mutex_lock(&dev->vendor_req_mutex);
 150        ret = __mt7601u_rr(dev, offset);
 151        mutex_unlock(&dev->vendor_req_mutex);
 152
 153        return ret;
 154}
 155
 156/* should be called with vendor_req_mutex held */
 157static int __mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req,
 158                                      const u16 offset, const u32 val)
 159{
 160        int ret = mt7601u_vendor_request(dev, req, USB_DIR_OUT,
 161                                         val & 0xffff, offset, NULL, 0);
 162        if (!ret)
 163                ret = mt7601u_vendor_request(dev, req, USB_DIR_OUT,
 164                                             val >> 16, offset + 2, NULL, 0);
 165        trace_reg_write(dev, offset, val);
 166        return ret;
 167}
 168
 169int mt7601u_vendor_single_wr(struct mt7601u_dev *dev, const u8 req,
 170                             const u16 offset, const u32 val)
 171{
 172        int ret;
 173
 174        mutex_lock(&dev->vendor_req_mutex);
 175        ret = __mt7601u_vendor_single_wr(dev, req, offset, val);
 176        mutex_unlock(&dev->vendor_req_mutex);
 177
 178        return ret;
 179}
 180
 181void mt7601u_wr(struct mt7601u_dev *dev, u32 offset, u32 val)
 182{
 183        WARN_ONCE(offset > USHRT_MAX, "write high off:%08x", offset);
 184
 185        mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val);
 186}
 187
 188u32 mt7601u_rmw(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val)
 189{
 190        mutex_lock(&dev->vendor_req_mutex);
 191        val |= __mt7601u_rr(dev, offset) & ~mask;
 192        __mt7601u_vendor_single_wr(dev, MT_VEND_WRITE, offset, val);
 193        mutex_unlock(&dev->vendor_req_mutex);
 194
 195        return val;
 196}
 197
 198u32 mt7601u_rmc(struct mt7601u_dev *dev, u32 offset, u32 mask, u32 val)
 199{
 200        u32 reg;
 201
 202        mutex_lock(&dev->vendor_req_mutex);
 203        reg = __mt7601u_rr(dev, offset);
 204        val |= reg & ~mask;
 205        if (reg != val)
 206                __mt7601u_vendor_single_wr(dev, MT_VEND_WRITE,
 207                                           offset, val);
 208        mutex_unlock(&dev->vendor_req_mutex);
 209
 210        return val;
 211}
 212
 213void mt7601u_wr_copy(struct mt7601u_dev *dev, u32 offset,
 214                     const void *data, int len)
 215{
 216        WARN_ONCE(offset & 3, "unaligned write copy off:%08x", offset);
 217        WARN_ONCE(len & 3, "short write copy off:%08x", offset);
 218
 219        mt7601u_burst_write_regs(dev, offset, data, len / 4);
 220}
 221
 222void mt7601u_addr_wr(struct mt7601u_dev *dev, const u32 offset, const u8 *addr)
 223{
 224        mt7601u_wr(dev, offset, get_unaligned_le32(addr));
 225        mt7601u_wr(dev, offset + 4, addr[4] | addr[5] << 8);
 226}
 227
 228static int mt7601u_assign_pipes(struct usb_interface *usb_intf,
 229                                struct mt7601u_dev *dev)
 230{
 231        struct usb_endpoint_descriptor *ep_desc;
 232        struct usb_host_interface *intf_desc = usb_intf->cur_altsetting;
 233        unsigned i, ep_i = 0, ep_o = 0;
 234
 235        BUILD_BUG_ON(sizeof(dev->in_eps) < __MT_EP_IN_MAX);
 236        BUILD_BUG_ON(sizeof(dev->out_eps) < __MT_EP_OUT_MAX);
 237
 238        for (i = 0; i < intf_desc->desc.bNumEndpoints; i++) {
 239                ep_desc = &intf_desc->endpoint[i].desc;
 240
 241                if (usb_endpoint_is_bulk_in(ep_desc) &&
 242                    ep_i++ < __MT_EP_IN_MAX) {
 243                        dev->in_eps[ep_i - 1] = usb_endpoint_num(ep_desc);
 244                        dev->in_max_packet = usb_endpoint_maxp(ep_desc);
 245                        /* Note: this is ignored by usb sub-system but vendor
 246                         *       code does it. We can drop this at some point.
 247                         */
 248                        dev->in_eps[ep_i - 1] |= USB_DIR_IN;
 249                } else if (usb_endpoint_is_bulk_out(ep_desc) &&
 250                           ep_o++ < __MT_EP_OUT_MAX) {
 251                        dev->out_eps[ep_o - 1] = usb_endpoint_num(ep_desc);
 252                        dev->out_max_packet = usb_endpoint_maxp(ep_desc);
 253                }
 254        }
 255
 256        if (ep_i != __MT_EP_IN_MAX || ep_o != __MT_EP_OUT_MAX) {
 257                dev_err(dev->dev, "Error: wrong pipe number in:%d out:%d\n",
 258                        ep_i, ep_o);
 259                return -EINVAL;
 260        }
 261
 262        return 0;
 263}
 264
 265static int mt7601u_probe(struct usb_interface *usb_intf,
 266                         const struct usb_device_id *id)
 267{
 268        struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
 269        struct mt7601u_dev *dev;
 270        u32 asic_rev, mac_rev;
 271        int ret;
 272
 273        dev = mt7601u_alloc_device(&usb_intf->dev);
 274        if (!dev)
 275                return -ENOMEM;
 276
 277        usb_dev = usb_get_dev(usb_dev);
 278        usb_reset_device(usb_dev);
 279
 280        usb_set_intfdata(usb_intf, dev);
 281
 282        dev->vend_buf = devm_kmalloc(dev->dev, MT_VEND_BUF, GFP_KERNEL);
 283        if (!dev->vend_buf) {
 284                ret = -ENOMEM;
 285                goto err;
 286        }
 287
 288        ret = mt7601u_assign_pipes(usb_intf, dev);
 289        if (ret)
 290                goto err;
 291        ret = mt7601u_wait_asic_ready(dev);
 292        if (ret)
 293                goto err;
 294
 295        asic_rev = mt7601u_rr(dev, MT_ASIC_VERSION);
 296        mac_rev = mt7601u_rr(dev, MT_MAC_CSR0);
 297        dev_info(dev->dev, "ASIC revision: %08x MAC revision: %08x\n",
 298                 asic_rev, mac_rev);
 299        if ((asic_rev >> 16) != 0x7601) {
 300                ret = -ENODEV;
 301                goto err;
 302        }
 303
 304        /* Note: vendor driver skips this check for MT7601U */
 305        if (!(mt7601u_rr(dev, MT_EFUSE_CTRL) & MT_EFUSE_CTRL_SEL))
 306                dev_warn(dev->dev, "Warning: eFUSE not present\n");
 307
 308        ret = mt7601u_init_hardware(dev);
 309        if (ret)
 310                goto err;
 311        ret = mt7601u_register_device(dev);
 312        if (ret)
 313                goto err_hw;
 314
 315        set_bit(MT7601U_STATE_INITIALIZED, &dev->state);
 316
 317        return 0;
 318err_hw:
 319        mt7601u_cleanup(dev);
 320err:
 321        usb_set_intfdata(usb_intf, NULL);
 322        usb_put_dev(interface_to_usbdev(usb_intf));
 323
 324        destroy_workqueue(dev->stat_wq);
 325        ieee80211_free_hw(dev->hw);
 326        return ret;
 327}
 328
 329static void mt7601u_disconnect(struct usb_interface *usb_intf)
 330{
 331        struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
 332
 333        ieee80211_unregister_hw(dev->hw);
 334        mt7601u_cleanup(dev);
 335
 336        usb_set_intfdata(usb_intf, NULL);
 337        usb_put_dev(interface_to_usbdev(usb_intf));
 338
 339        destroy_workqueue(dev->stat_wq);
 340        ieee80211_free_hw(dev->hw);
 341}
 342
 343static int mt7601u_suspend(struct usb_interface *usb_intf, pm_message_t state)
 344{
 345        struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
 346
 347        mt7601u_cleanup(dev);
 348
 349        return 0;
 350}
 351
 352static int mt7601u_resume(struct usb_interface *usb_intf)
 353{
 354        struct mt7601u_dev *dev = usb_get_intfdata(usb_intf);
 355        int ret;
 356
 357        ret = mt7601u_init_hardware(dev);
 358        if (ret)
 359                return ret;
 360
 361        set_bit(MT7601U_STATE_INITIALIZED, &dev->state);
 362
 363        return 0;
 364}
 365
 366MODULE_DEVICE_TABLE(usb, mt7601u_device_table);
 367MODULE_FIRMWARE(MT7601U_FIRMWARE);
 368MODULE_LICENSE("GPL");
 369
 370static struct usb_driver mt7601u_driver = {
 371        .name           = KBUILD_MODNAME,
 372        .id_table       = mt7601u_device_table,
 373        .probe          = mt7601u_probe,
 374        .disconnect     = mt7601u_disconnect,
 375        .suspend        = mt7601u_suspend,
 376        .resume         = mt7601u_resume,
 377        .reset_resume   = mt7601u_resume,
 378        .soft_unbind    = 1,
 379        .disable_hub_initiated_lpm = 1,
 380};
 381module_usb_driver(mt7601u_driver);
 382