linux/drivers/net/irda/mcs7780.c
<<
>>
Prefs
   1/*****************************************************************************
   2*
   3* Filename:      mcs7780.c
   4* Version:       0.4-alpha
   5* Description:   Irda MosChip USB Dongle Driver
   6* Authors:       Lukasz Stelmach <stlman@poczta.fm>
   7*                Brian Pugh <bpugh@cs.pdx.edu>
   8*                Judy Fischbach <jfisch@cs.pdx.edu>
   9*
  10*       Based on stir4200 driver, but some things done differently.
  11*       Based on earlier driver by Paul Stewart <stewart@parc.com>
  12*
  13*       Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
  14*       Copyright (C) 2001, Dag Brattli <dag@brattli.net>
  15*       Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
  16*       Copyright (C) 2004, Stephen Hemminger <shemminger@osdl.org>
  17*       Copyright (C) 2005, Lukasz Stelmach <stlman@poczta.fm>
  18*       Copyright (C) 2005, Brian Pugh <bpugh@cs.pdx.edu>
  19*       Copyright (C) 2005, Judy Fischbach <jfisch@cs.pdx.edu>
  20*
  21*       This program is free software; you can redistribute it and/or modify
  22*       it under the terms of the GNU General Public License as published by
  23*       the Free Software Foundation; either version 2 of the License, or
  24*       (at your option) any later version.
  25*
  26*       This program is distributed in the hope that it will be useful,
  27*       but WITHOUT ANY WARRANTY; without even the implied warranty of
  28*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  29*       GNU General Public License for more details.
  30*
  31*       You should have received a copy of the GNU General Public License
  32*       along with this program; if not, write to the Free Software
  33*       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  34*
  35*****************************************************************************/
  36
  37/*
  38 * MCS7780 is a simple USB to IrDA bridge by MosChip. It is neither
  39 * compatibile with irda-usb nor with stir4200. Although it is quite
  40 * similar to the later as far as general idea of operation is concerned.
  41 * That is it requires the software to do all the framing job at SIR speeds.
  42 * The hardware does take care of the framing at MIR and FIR speeds.
  43 * It supports all speeds from 2400 through 4Mbps
  44 */
  45
  46#include <linux/module.h>
  47#include <linux/moduleparam.h>
  48#include <linux/kernel.h>
  49#include <linux/types.h>
  50#include <linux/errno.h>
  51#include <linux/init.h>
  52#include <linux/slab.h>
  53#include <linux/kref.h>
  54#include <linux/usb.h>
  55#include <linux/device.h>
  56#include <linux/crc32.h>
  57
  58#include <asm/unaligned.h>
  59#include <asm/byteorder.h>
  60#include <asm/uaccess.h>
  61
  62#include <net/irda/irda.h>
  63#include <net/irda/wrapper.h>
  64#include <net/irda/crc.h>
  65
  66#include "mcs7780.h"
  67
  68#define MCS_VENDOR_ID 0x9710
  69#define MCS_PRODUCT_ID 0x7780
  70
  71static struct usb_device_id mcs_table[] = {
  72        /* MosChip Corp.,  MCS7780 FIR-USB Adapter */
  73        {USB_DEVICE(MCS_VENDOR_ID, MCS_PRODUCT_ID)},
  74        {},
  75};
  76
  77MODULE_AUTHOR("Brian Pugh <bpugh@cs.pdx.edu>");
  78MODULE_DESCRIPTION("IrDA-USB Dongle Driver for MosChip MCS7780");
  79MODULE_VERSION("0.3alpha");
  80MODULE_LICENSE("GPL");
  81
  82MODULE_DEVICE_TABLE(usb, mcs_table);
  83
  84static int qos_mtt_bits = 0x07 /* > 1ms */ ;
  85module_param(qos_mtt_bits, int, 0);
  86MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
  87
  88static int receive_mode = 0x1;
  89module_param(receive_mode, int, 0);
  90MODULE_PARM_DESC(receive_mode,
  91                 "Receive mode of the device (1:fast, 0:slow, default:1)");
  92
  93static int sir_tweak = 1;
  94module_param(sir_tweak, int, 0444);
  95MODULE_PARM_DESC(sir_tweak,
  96                 "Default pulse width (1:1.6us, 0:3/16 bit, default:1).");
  97
  98static int transceiver_type = MCS_TSC_VISHAY;
  99module_param(transceiver_type, int, 0444);
 100MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h.");
 101
 102static struct usb_driver mcs_driver = {
 103        .name = "mcs7780",
 104        .probe = mcs_probe,
 105        .disconnect = mcs_disconnect,
 106        .id_table = mcs_table,
 107};
 108
 109/* speed flag selection by direct addressing.
 110addr = (speed >> 8) & 0x0f
 111
 1120x1   57600      0x2  115200     0x4 1152000     0x5    9600
 1130x6   38400      0x9    2400     0xa  576000     0xb   19200
 114
 1154Mbps (or 2400) must be checked separately. Since it also has
 116to be programmed in a different manner that is not a big problem.
 117*/
 118static __u16 mcs_speed_set[16] = { 0,
 119        MCS_SPEED_57600,
 120        MCS_SPEED_115200,
 121        0,
 122        MCS_SPEED_1152000,
 123        MCS_SPEED_9600,
 124        MCS_SPEED_38400,
 125        0, 0,
 126        MCS_SPEED_2400,
 127        MCS_SPEED_576000,
 128        MCS_SPEED_19200,
 129        0, 0, 0,
 130};
 131
 132/* Set given 16 bit register with a 16 bit value. Send control message
 133 * to set dongle register. */
 134static int mcs_set_reg(struct mcs_cb *mcs, __u16 reg, __u16 val)
 135{
 136        struct usb_device *dev = mcs->usbdev;
 137        return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), MCS_WRREQ,
 138                               MCS_WR_RTYPE, val, reg, NULL, 0,
 139                               msecs_to_jiffies(MCS_CTRL_TIMEOUT));
 140}
 141
 142/* Get 16 bit register value. Send contol message to read dongle register. */
 143static int mcs_get_reg(struct mcs_cb *mcs, __u16 reg, __u16 * val)
 144{
 145        struct usb_device *dev = mcs->usbdev;
 146        int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
 147                                  MCS_RD_RTYPE, 0, reg, val, 2,
 148                                  msecs_to_jiffies(MCS_CTRL_TIMEOUT));
 149
 150        return ret;
 151}
 152
 153/* Setup a communication between mcs7780 and TFDU chips.  It is described
 154 * in more detail in the data sheet.  The setup sequence puts the the
 155 * vishay tranceiver into high speed mode.  It will also receive SIR speed
 156 * packets but at reduced sensitivity.
 157 */
 158
 159/* 0: OK 1:ERROR */
 160static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs)
 161{
 162        int ret = 0;
 163        __u16 rval;
 164
 165        /* mcs_get_reg should read exactly two bytes from the dongle */
 166        ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval);
 167        if (unlikely(ret != 2)) {
 168                ret = -EIO;
 169                goto error;
 170        }
 171
 172        /* The MCS_XCVR_CONF bit puts the transceiver into configuration
 173         * mode.  The MCS_MODE0 bit must start out high (1) and then
 174         * transition to low and the MCS_STFIR and MCS_MODE1 bits must
 175         * be low.
 176         */
 177        rval |= (MCS_MODE0 | MCS_XCVR_CONF);
 178        rval &= ~MCS_STFIR;
 179        rval &= ~MCS_MODE1;
 180        ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
 181        if (unlikely(ret))
 182                goto error;
 183
 184        rval &= ~MCS_MODE0;
 185        ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
 186        if (unlikely(ret))
 187                goto error;
 188
 189        rval &= ~MCS_XCVR_CONF;
 190        ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
 191        if (unlikely(ret))
 192                goto error;
 193
 194        ret = 0;
 195        error:
 196                return ret;
 197}
 198
 199/* Setup a communication between mcs7780 and agilent chip. */
 200static inline int mcs_setup_transceiver_agilent(struct mcs_cb *mcs)
 201{
 202        IRDA_WARNING("This transceiver type is not supported yet.\n");
 203        return 1;
 204}
 205
 206/* Setup a communication between mcs7780 and sharp chip. */
 207static inline int mcs_setup_transceiver_sharp(struct mcs_cb *mcs)
 208{
 209        IRDA_WARNING("This transceiver type is not supported yet.\n");
 210        return 1;
 211}
 212
 213/* Common setup for all transceivers */
 214static inline int mcs_setup_transceiver(struct mcs_cb *mcs)
 215{
 216        int ret = 0;
 217        __u16 rval;
 218        char *msg;
 219
 220        msg = "Basic transceiver setup error.";
 221
 222        /* read value of MODE Register, set the DRIVER and RESET bits
 223        * and write value back out to MODE Register
 224        */
 225        ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
 226        if(unlikely(ret != 2))
 227                goto error;
 228        rval |= MCS_DRIVER;     /* put the mcs7780 into configuration mode. */
 229        ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
 230        if(unlikely(ret))
 231                goto error;
 232
 233        rval = 0;               /* set min pulse width to 0 initially. */
 234        ret = mcs_set_reg(mcs, MCS_MINRXPW_REG, rval);
 235        if(unlikely(ret))
 236                goto error;
 237
 238        ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
 239        if(unlikely(ret != 2))
 240                goto error;
 241
 242        rval &= ~MCS_FIR;       /* turn off fir mode. */
 243        if(mcs->sir_tweak)
 244                rval |= MCS_SIR16US;    /* 1.6us pulse width */
 245        else
 246                rval &= ~MCS_SIR16US;   /* 3/16 bit time pulse width */
 247
 248        /* make sure ask mode and back to back packets are off. */
 249        rval &= ~(MCS_BBTG | MCS_ASK);
 250
 251        rval &= ~MCS_SPEED_MASK;
 252        rval |= MCS_SPEED_9600;         /* make sure initial speed is 9600. */
 253        mcs->speed = 9600;
 254        mcs->new_speed = 0;             /* new_speed is set to 0 */
 255        rval &= ~MCS_PLLPWDN;           /* disable power down. */
 256
 257        /* make sure device determines direction and that the auto send sip
 258         * pulse are on.
 259         */
 260        rval |= MCS_DTD | MCS_SIPEN;
 261
 262        ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
 263        if(unlikely(ret))
 264                goto error;
 265
 266        msg = "transceiver model specific setup error.";
 267        switch (mcs->transceiver_type) {
 268        case MCS_TSC_VISHAY:
 269                ret = mcs_setup_transceiver_vishay(mcs);
 270                break;
 271
 272        case MCS_TSC_SHARP:
 273                ret = mcs_setup_transceiver_sharp(mcs);
 274                break;
 275
 276        case MCS_TSC_AGILENT:
 277                ret = mcs_setup_transceiver_agilent(mcs);
 278                break;
 279
 280        default:
 281                IRDA_WARNING("Unknown transceiver type: %d\n",
 282                             mcs->transceiver_type);
 283                ret = 1;
 284        }
 285        if (unlikely(ret))
 286                goto error;
 287
 288        /* If transceiver is not SHARP, then if receive mode set
 289        * on the RXFAST bit in the XCVR Register otherwise unset it
 290        */
 291        if (mcs->transceiver_type != MCS_TSC_SHARP) {
 292
 293                ret = mcs_get_reg(mcs, MCS_XCVR_REG, &rval);
 294                if (unlikely(ret != 2))
 295                        goto error;
 296                if (mcs->receive_mode)
 297                        rval |= MCS_RXFAST;
 298                else
 299                        rval &= ~MCS_RXFAST;
 300                ret = mcs_set_reg(mcs, MCS_XCVR_REG, rval);
 301                if (unlikely(ret))
 302                        goto error;
 303        }
 304
 305        msg = "transceiver reset.";
 306
 307        ret = mcs_get_reg(mcs, MCS_MODE_REG, &rval);
 308        if (unlikely(ret != 2))
 309                goto error;
 310
 311        /* reset the mcs7780 so all changes take effect. */
 312        rval &= ~MCS_RESET;
 313        ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
 314        if (unlikely(ret))
 315                goto error;
 316        else
 317                return ret;
 318
 319error:
 320        IRDA_ERROR("%s\n", msg);
 321        return ret;
 322}
 323
 324/* Wraps the data in format for SIR */
 325static inline int mcs_wrap_sir_skb(struct sk_buff *skb, __u8 * buf)
 326{
 327        int wraplen;
 328
 329        /* 2: full frame length, including "the length" */
 330        wraplen = async_wrap_skb(skb, buf + 2, 4094);
 331
 332        wraplen += 2;
 333        buf[0] = wraplen & 0xff;
 334        buf[1] = (wraplen >> 8) & 0xff;
 335
 336        return wraplen;
 337}
 338
 339/* Wraps the data in format for FIR */
 340static unsigned mcs_wrap_fir_skb(const struct sk_buff *skb, __u8 *buf)
 341{
 342        unsigned int len = 0;
 343        __u32 fcs = ~(crc32_le(~0, skb->data, skb->len));
 344
 345        /* add 2 bytes for length value and 4 bytes for fcs. */
 346        len = skb->len + 6;
 347
 348        /* The mcs7780 requires that the first two bytes are the packet
 349         * length in little endian order.  Note: the length value includes
 350         * the two bytes for the length value itself.
 351         */
 352        buf[0] = len & 0xff;
 353        buf[1] = (len >> 8) & 0xff;
 354        /* copy the data into the tx buffer. */
 355        skb_copy_from_linear_data(skb, buf + 2, skb->len);
 356        /* put the fcs in the last four bytes in little endian order. */
 357        buf[len - 4] = fcs & 0xff;
 358        buf[len - 3] = (fcs >> 8) & 0xff;
 359        buf[len - 2] = (fcs >> 16) & 0xff;
 360        buf[len - 1] = (fcs >> 24) & 0xff;
 361
 362        return len;
 363}
 364
 365/* Wraps the data in format for MIR */
 366static unsigned mcs_wrap_mir_skb(const struct sk_buff *skb, __u8 *buf)
 367{
 368        __u16 fcs = 0;
 369        int len = skb->len + 4;
 370
 371        fcs = ~(irda_calc_crc16(~fcs, skb->data, skb->len));
 372        /* put the total packet length in first.  Note: packet length
 373         * value includes the two bytes that hold the packet length
 374         * itself.
 375         */
 376        buf[0] = len & 0xff;
 377        buf[1] = (len >> 8) & 0xff;
 378        /* copy the data */
 379        skb_copy_from_linear_data(skb, buf + 2, skb->len);
 380        /* put the fcs in last two bytes in little endian order. */
 381        buf[len - 2] = fcs & 0xff;
 382        buf[len - 1] = (fcs >> 8) & 0xff;
 383
 384        return len;
 385}
 386
 387/* Unwrap received packets at MIR speed.  A 16 bit crc_ccitt checksum is
 388 * used for the fcs.  When performed over the entire packet the result
 389 * should be GOOD_FCS = 0xf0b8.  Hands the unwrapped data off to the IrDA
 390 * layer via a sk_buff.
 391 */
 392static void mcs_unwrap_mir(struct mcs_cb *mcs, __u8 *buf, int len)
 393{
 394        __u16 fcs;
 395        int new_len;
 396        struct sk_buff *skb;
 397
 398        /* Assume that the frames are going to fill a single packet
 399         * rather than span multiple packets.
 400         */
 401
 402        new_len = len - 2;
 403        if(unlikely(new_len <= 0)) {
 404                IRDA_ERROR("%s short frame length %d\n",
 405                             mcs->netdev->name, new_len);
 406                ++mcs->netdev->stats.rx_errors;
 407                ++mcs->netdev->stats.rx_length_errors;
 408                return;
 409        }
 410        fcs = 0;
 411        fcs = irda_calc_crc16(~fcs, buf, len);
 412
 413        if(fcs != GOOD_FCS) {
 414                IRDA_ERROR("crc error calc 0x%x len %d\n",
 415                           fcs, new_len);
 416                mcs->netdev->stats.rx_errors++;
 417                mcs->netdev->stats.rx_crc_errors++;
 418                return;
 419        }
 420
 421        skb = dev_alloc_skb(new_len + 1);
 422        if(unlikely(!skb)) {
 423                ++mcs->netdev->stats.rx_dropped;
 424                return;
 425        }
 426
 427        skb_reserve(skb, 1);
 428        skb_copy_to_linear_data(skb, buf, new_len);
 429        skb_put(skb, new_len);
 430        skb_reset_mac_header(skb);
 431        skb->protocol = htons(ETH_P_IRDA);
 432        skb->dev = mcs->netdev;
 433
 434        netif_rx(skb);
 435
 436        mcs->netdev->stats.rx_packets++;
 437        mcs->netdev->stats.rx_bytes += new_len;
 438
 439        return;
 440}
 441
 442/* Unwrap received packets at FIR speed.  A 32 bit crc_ccitt checksum is
 443 * used for the fcs.  Hands the unwrapped data off to the IrDA
 444 * layer via a sk_buff.
 445 */
 446static void mcs_unwrap_fir(struct mcs_cb *mcs, __u8 *buf, int len)
 447{
 448        __u32 fcs;
 449        int new_len;
 450        struct sk_buff *skb;
 451
 452        /* Assume that the frames are going to fill a single packet
 453         * rather than span multiple packets.  This is most likely a false
 454         * assumption.
 455         */
 456
 457        new_len = len - 4;
 458        if(unlikely(new_len <= 0)) {
 459                IRDA_ERROR("%s short frame length %d\n",
 460                           mcs->netdev->name, new_len);
 461                ++mcs->netdev->stats.rx_errors;
 462                ++mcs->netdev->stats.rx_length_errors;
 463                return;
 464        }
 465
 466        fcs = ~(crc32_le(~0, buf, new_len));
 467        if(fcs != get_unaligned_le32(buf + new_len)) {
 468                IRDA_ERROR("crc error calc 0x%x len %d\n", fcs, new_len);
 469                mcs->netdev->stats.rx_errors++;
 470                mcs->netdev->stats.rx_crc_errors++;
 471                return;
 472        }
 473
 474        skb = dev_alloc_skb(new_len + 1);
 475        if(unlikely(!skb)) {
 476                ++mcs->netdev->stats.rx_dropped;
 477                return;
 478        }
 479
 480        skb_reserve(skb, 1);
 481        skb_copy_to_linear_data(skb, buf, new_len);
 482        skb_put(skb, new_len);
 483        skb_reset_mac_header(skb);
 484        skb->protocol = htons(ETH_P_IRDA);
 485        skb->dev = mcs->netdev;
 486
 487        netif_rx(skb);
 488
 489        mcs->netdev->stats.rx_packets++;
 490        mcs->netdev->stats.rx_bytes += new_len;
 491
 492        return;
 493}
 494
 495
 496/* Allocates urbs for both receive and transmit.
 497 * If alloc fails return error code 0 (fail) otherwise
 498 * return error code 1 (success).
 499 */
 500static inline int mcs_setup_urbs(struct mcs_cb *mcs)
 501{
 502        mcs->rx_urb = NULL;
 503
 504        mcs->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 505        if (!mcs->tx_urb)
 506                return 0;
 507
 508        mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
 509        if (!mcs->rx_urb)
 510                return 0;
 511
 512        return 1;
 513}
 514
 515/* Sets up state to be initially outside frame, gets receive urb,
 516 * sets status to successful and then submits the urb to start
 517 * receiving the data.
 518 */
 519static inline int mcs_receive_start(struct mcs_cb *mcs)
 520{
 521        mcs->rx_buff.in_frame = FALSE;
 522        mcs->rx_buff.state = OUTSIDE_FRAME;
 523
 524        usb_fill_bulk_urb(mcs->rx_urb, mcs->usbdev,
 525                          usb_rcvbulkpipe(mcs->usbdev, mcs->ep_in),
 526                          mcs->in_buf, 4096, mcs_receive_irq, mcs);
 527
 528        mcs->rx_urb->status = 0;
 529        return usb_submit_urb(mcs->rx_urb, GFP_KERNEL);
 530}
 531
 532/* Finds the in and out endpoints for the mcs control block */
 533static inline int mcs_find_endpoints(struct mcs_cb *mcs,
 534                                     struct usb_host_endpoint *ep, int epnum)
 535{
 536        int i;
 537        int ret = 0;
 538
 539        /* If no place to store the endpoints just return */
 540        if (!ep)
 541                return ret;
 542
 543        /* cycle through all endpoints, find the first two that are DIR_IN */
 544        for (i = 0; i < epnum; i++) {
 545                if (ep[i].desc.bEndpointAddress & USB_DIR_IN)
 546                        mcs->ep_in = ep[i].desc.bEndpointAddress;
 547                else
 548                        mcs->ep_out = ep[i].desc.bEndpointAddress;
 549
 550                /* MosChip says that the chip has only two bulk
 551                 * endpoints. Find one for each direction and move on.
 552                 */
 553                if ((mcs->ep_in != 0) && (mcs->ep_out != 0)) {
 554                        ret = 1;
 555                        break;
 556                }
 557        }
 558
 559        return ret;
 560}
 561
 562static void mcs_speed_work(struct work_struct *work)
 563{
 564        struct mcs_cb *mcs = container_of(work, struct mcs_cb, work);
 565        struct net_device *netdev = mcs->netdev;
 566
 567        mcs_speed_change(mcs);
 568        netif_wake_queue(netdev);
 569}
 570
 571/* Function to change the speed of the mcs7780.  Fully supports SIR,
 572 * MIR, and FIR speeds.
 573 */
 574static int mcs_speed_change(struct mcs_cb *mcs)
 575{
 576        int ret = 0;
 577        int rst = 0;
 578        int cnt = 0;
 579        __u16 nspeed;
 580        __u16 rval;
 581
 582        nspeed = mcs_speed_set[(mcs->new_speed >> 8) & 0x0f];
 583
 584        do {
 585                mcs_get_reg(mcs, MCS_RESV_REG, &rval);
 586        } while(cnt++ < 100 && (rval & MCS_IRINTX));
 587
 588        if (cnt > 100) {
 589                IRDA_ERROR("unable to change speed\n");
 590                ret = -EIO;
 591                goto error;
 592        }
 593
 594        mcs_get_reg(mcs, MCS_MODE_REG, &rval);
 595
 596        /* MINRXPW values recomended by MosChip */
 597        if (mcs->new_speed <= 115200) {
 598                rval &= ~MCS_FIR;
 599
 600                if ((rst = (mcs->speed > 115200)))
 601                        mcs_set_reg(mcs, MCS_MINRXPW_REG, 0);
 602
 603        } else if (mcs->new_speed <= 1152000) {
 604                rval &= ~MCS_FIR;
 605
 606                if ((rst = !(mcs->speed == 576000 || mcs->speed == 1152000)))
 607                        mcs_set_reg(mcs, MCS_MINRXPW_REG, 5);
 608
 609        } else {
 610                rval |= MCS_FIR;
 611
 612                if ((rst = (mcs->speed != 4000000)))
 613                        mcs_set_reg(mcs, MCS_MINRXPW_REG, 5);
 614
 615        }
 616
 617        rval &= ~MCS_SPEED_MASK;
 618        rval |= nspeed;
 619
 620        ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
 621        if (unlikely(ret))
 622                goto error;
 623
 624        if (rst)
 625                switch (mcs->transceiver_type) {
 626                case MCS_TSC_VISHAY:
 627                        ret = mcs_setup_transceiver_vishay(mcs);
 628                        break;
 629
 630                case MCS_TSC_SHARP:
 631                        ret = mcs_setup_transceiver_sharp(mcs);
 632                        break;
 633
 634                case MCS_TSC_AGILENT:
 635                        ret = mcs_setup_transceiver_agilent(mcs);
 636                        break;
 637
 638                default:
 639                        ret = 1;
 640                        IRDA_WARNING("Unknown transceiver type: %d\n",
 641                                     mcs->transceiver_type);
 642                }
 643        if (unlikely(ret))
 644                goto error;
 645
 646        mcs_get_reg(mcs, MCS_MODE_REG, &rval);
 647        rval &= ~MCS_RESET;
 648        ret = mcs_set_reg(mcs, MCS_MODE_REG, rval);
 649
 650        mcs->speed = mcs->new_speed;
 651        error:
 652                mcs->new_speed = 0;
 653                return ret;
 654}
 655
 656/* Ioctl calls not supported at this time.  Can be an area of future work. */
 657static int mcs_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
 658{
 659        /* struct if_irda_req *irq = (struct if_irda_req *)rq; */
 660        /* struct mcs_cb *mcs = netdev_priv(netdev); */
 661        int ret = 0;
 662
 663        switch (cmd) {
 664        default:
 665                ret = -EOPNOTSUPP;
 666        }
 667
 668        return ret;
 669}
 670
 671/* Network device is taken down, done by "ifconfig irda0 down" */
 672static int mcs_net_close(struct net_device *netdev)
 673{
 674        int ret = 0;
 675        struct mcs_cb *mcs = netdev_priv(netdev);
 676
 677        /* Stop transmit processing */
 678        netif_stop_queue(netdev);
 679
 680        kfree_skb(mcs->rx_buff.skb);
 681
 682        /* kill and free the receive and transmit URBs */
 683        usb_kill_urb(mcs->rx_urb);
 684        usb_free_urb(mcs->rx_urb);
 685        usb_kill_urb(mcs->tx_urb);
 686        usb_free_urb(mcs->tx_urb);
 687
 688        /* Stop and remove instance of IrLAP */
 689        if (mcs->irlap)
 690                irlap_close(mcs->irlap);
 691
 692        mcs->irlap = NULL;
 693        return ret;
 694}
 695
 696/* Network device is taken up, done by "ifconfig irda0 up" */
 697static int mcs_net_open(struct net_device *netdev)
 698{
 699        struct mcs_cb *mcs = netdev_priv(netdev);
 700        char hwname[16];
 701        int ret = 0;
 702
 703        ret = usb_clear_halt(mcs->usbdev,
 704                             usb_sndbulkpipe(mcs->usbdev, mcs->ep_in));
 705        if (ret)
 706                goto error1;
 707        ret = usb_clear_halt(mcs->usbdev,
 708                             usb_rcvbulkpipe(mcs->usbdev, mcs->ep_out));
 709        if (ret)
 710                goto error1;
 711
 712        ret = mcs_setup_transceiver(mcs);
 713        if (ret)
 714                goto error1;
 715
 716        ret = -ENOMEM;
 717
 718        /* Initialize for SIR/FIR to copy data directly into skb.  */
 719        mcs->receiving = 0;
 720        mcs->rx_buff.truesize = IRDA_SKB_MAX_MTU;
 721        mcs->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
 722        if (!mcs->rx_buff.skb)
 723                goto error1;
 724
 725        skb_reserve(mcs->rx_buff.skb, 1);
 726        mcs->rx_buff.head = mcs->rx_buff.skb->data;
 727        do_gettimeofday(&mcs->rx_time);
 728
 729        /*
 730         * Now that everything should be initialized properly,
 731         * Open new IrLAP layer instance to take care of us...
 732         * Note : will send immediately a speed change...
 733         */
 734        sprintf(hwname, "usb#%d", mcs->usbdev->devnum);
 735        mcs->irlap = irlap_open(netdev, &mcs->qos, hwname);
 736        if (!mcs->irlap) {
 737                IRDA_ERROR("mcs7780: irlap_open failed\n");
 738                goto error2;
 739        }
 740
 741        if (!mcs_setup_urbs(mcs))
 742        goto error3;
 743
 744        ret = mcs_receive_start(mcs);
 745        if (ret)
 746                goto error3;
 747
 748        netif_start_queue(netdev);
 749        return 0;
 750
 751        error3:
 752                irlap_close(mcs->irlap);
 753        error2:
 754                kfree_skb(mcs->rx_buff.skb);
 755        error1:
 756                return ret;
 757}
 758
 759/* Receive callback function.  */
 760static void mcs_receive_irq(struct urb *urb)
 761{
 762        __u8 *bytes;
 763        struct mcs_cb *mcs = urb->context;
 764        int i;
 765        int ret;
 766
 767        if (!netif_running(mcs->netdev))
 768                return;
 769
 770        if (urb->status)
 771                return;
 772
 773        if (urb->actual_length > 0) {
 774                bytes = urb->transfer_buffer;
 775
 776                /* MCS returns frames without BOF and EOF
 777                 * I assume it returns whole frames.
 778                 */
 779                /* SIR speed */
 780                if(mcs->speed < 576000) {
 781                        async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
 782                                  &mcs->rx_buff, 0xc0);
 783
 784                        for (i = 0; i < urb->actual_length; i++)
 785                                async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
 786                                          &mcs->rx_buff, bytes[i]);
 787
 788                        async_unwrap_char(mcs->netdev, &mcs->netdev->stats,
 789                                  &mcs->rx_buff, 0xc1);
 790                }
 791                /* MIR speed */
 792                else if(mcs->speed == 576000 || mcs->speed == 1152000) {
 793                        mcs_unwrap_mir(mcs, urb->transfer_buffer,
 794                                urb->actual_length);
 795                }
 796                /* FIR speed */
 797                else {
 798                        mcs_unwrap_fir(mcs, urb->transfer_buffer,
 799                                urb->actual_length);
 800                }
 801                do_gettimeofday(&mcs->rx_time);
 802        }
 803
 804        ret = usb_submit_urb(urb, GFP_ATOMIC);
 805}
 806
 807/* Transmit callback funtion.  */
 808static void mcs_send_irq(struct urb *urb)
 809{
 810        struct mcs_cb *mcs = urb->context;
 811        struct net_device *ndev = mcs->netdev;
 812
 813        if (unlikely(mcs->new_speed))
 814                schedule_work(&mcs->work);
 815        else
 816                netif_wake_queue(ndev);
 817}
 818
 819/* Transmit callback funtion.  */
 820static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 821{
 822        unsigned long flags;
 823        struct mcs_cb *mcs;
 824        int wraplen;
 825        int ret = 0;
 826
 827        netif_stop_queue(ndev);
 828        mcs = netdev_priv(ndev);
 829
 830        spin_lock_irqsave(&mcs->lock, flags);
 831
 832        mcs->new_speed = irda_get_next_speed(skb);
 833        if (likely(mcs->new_speed == mcs->speed))
 834                mcs->new_speed = 0;
 835
 836        /* SIR speed */
 837        if(mcs->speed < 576000) {
 838                wraplen = mcs_wrap_sir_skb(skb, mcs->out_buf);
 839        }
 840        /* MIR speed */
 841        else if(mcs->speed == 576000 || mcs->speed == 1152000) {
 842                wraplen = mcs_wrap_mir_skb(skb, mcs->out_buf);
 843        }
 844        /* FIR speed */
 845        else {
 846                wraplen = mcs_wrap_fir_skb(skb, mcs->out_buf);
 847        }
 848        usb_fill_bulk_urb(mcs->tx_urb, mcs->usbdev,
 849                          usb_sndbulkpipe(mcs->usbdev, mcs->ep_out),
 850                          mcs->out_buf, wraplen, mcs_send_irq, mcs);
 851
 852        if ((ret = usb_submit_urb(mcs->tx_urb, GFP_ATOMIC))) {
 853                IRDA_ERROR("failed tx_urb: %d\n", ret);
 854                switch (ret) {
 855                case -ENODEV:
 856                case -EPIPE:
 857                        break;
 858                default:
 859                        mcs->netdev->stats.tx_errors++;
 860                        netif_start_queue(ndev);
 861                }
 862        } else {
 863                mcs->netdev->stats.tx_packets++;
 864                mcs->netdev->stats.tx_bytes += skb->len;
 865        }
 866
 867        dev_kfree_skb(skb);
 868        spin_unlock_irqrestore(&mcs->lock, flags);
 869        return NETDEV_TX_OK;
 870}
 871
 872static const struct net_device_ops mcs_netdev_ops = {
 873        .ndo_open = mcs_net_open,
 874        .ndo_stop = mcs_net_close,
 875        .ndo_start_xmit = mcs_hard_xmit,
 876        .ndo_do_ioctl = mcs_net_ioctl,
 877};
 878
 879/*
 880 * This function is called by the USB subsystem for each new device in the
 881 * system.  Need to verify the device and if it is, then start handling it.
 882 */
 883static int mcs_probe(struct usb_interface *intf,
 884                     const struct usb_device_id *id)
 885{
 886        struct usb_device *udev = interface_to_usbdev(intf);
 887        struct net_device *ndev = NULL;
 888        struct mcs_cb *mcs;
 889        int ret = -ENOMEM;
 890
 891        ndev = alloc_irdadev(sizeof(*mcs));
 892        if (!ndev)
 893                goto error1;
 894
 895        IRDA_DEBUG(1, "MCS7780 USB-IrDA bridge found at %d.\n", udev->devnum);
 896
 897        SET_NETDEV_DEV(ndev, &intf->dev);
 898
 899        ret = usb_reset_configuration(udev);
 900        if (ret != 0) {
 901                IRDA_ERROR("mcs7780: usb reset configuration failed\n");
 902                goto error2;
 903        }
 904
 905        mcs = netdev_priv(ndev);
 906        mcs->usbdev = udev;
 907        mcs->netdev = ndev;
 908        spin_lock_init(&mcs->lock);
 909
 910        /* Initialize QoS for this device */
 911        irda_init_max_qos_capabilies(&mcs->qos);
 912
 913        /* That's the Rx capability. */
 914        mcs->qos.baud_rate.bits &=
 915            IR_2400 | IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200
 916                | IR_576000 | IR_1152000 | (IR_4000000 << 8);
 917
 918
 919        mcs->qos.min_turn_time.bits &= qos_mtt_bits;
 920        irda_qos_bits_to_value(&mcs->qos);
 921
 922        /* Speed change work initialisation*/
 923        INIT_WORK(&mcs->work, mcs_speed_work);
 924
 925        ndev->netdev_ops = &mcs_netdev_ops;
 926
 927        if (!intf->cur_altsetting)
 928                goto error2;
 929
 930        ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint,
 931                                 intf->cur_altsetting->desc.bNumEndpoints);
 932        if (!ret) {
 933                ret = -ENODEV;
 934                goto error2;
 935        }
 936
 937        ret = register_netdev(ndev);
 938        if (ret != 0)
 939                goto error2;
 940
 941        IRDA_DEBUG(1, "IrDA: Registered MosChip MCS7780 device as %s\n",
 942                   ndev->name);
 943
 944        mcs->transceiver_type = transceiver_type;
 945        mcs->sir_tweak = sir_tweak;
 946        mcs->receive_mode = receive_mode;
 947
 948        usb_set_intfdata(intf, mcs);
 949        return 0;
 950
 951        error2:
 952                free_netdev(ndev);
 953
 954        error1:
 955                return ret;
 956}
 957
 958/* The current device is removed, the USB layer tells us to shut down. */
 959static void mcs_disconnect(struct usb_interface *intf)
 960{
 961        struct mcs_cb *mcs = usb_get_intfdata(intf);
 962
 963        if (!mcs)
 964                return;
 965
 966        flush_scheduled_work();
 967
 968        unregister_netdev(mcs->netdev);
 969        free_netdev(mcs->netdev);
 970
 971        usb_set_intfdata(intf, NULL);
 972        IRDA_DEBUG(0, "MCS7780 now disconnected.\n");
 973}
 974
 975/* Module insertion */
 976static int __init mcs_init(void)
 977{
 978        int result;
 979
 980        /* register this driver with the USB subsystem */
 981        result = usb_register(&mcs_driver);
 982        if (result)
 983                IRDA_ERROR("usb_register failed. Error number %d\n", result);
 984
 985        return result;
 986}
 987module_init(mcs_init);
 988
 989/* Module removal */
 990static void __exit mcs_exit(void)
 991{
 992        /* deregister this driver with the USB subsystem */
 993        usb_deregister(&mcs_driver);
 994}
 995module_exit(mcs_exit);
 996
 997
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.