[Linux-ATM-General] OAM not support [SOLVED]

Dario Lesca d.lesca at solinos.it
Wed Aug 2 09:36:23 UTC 2006


Il giorno mer, 02/08/2006 alle 10.51 +0200, Dario Lesca ha scritto:

> produced this structure (see attach):

Makefile:

> 
> obj-m += usbatm.o
> obj-m += cxacru.o
> 
> PWD   := $(shell pwd)
> MDIR  := /lib/modules/$(shell uname -r)
> KDIR  := $(MDIR)/build
> SUDO  := sudo -p 'Sudo Password: '
> 
> default:
>         @echo "make {patch|build|install|uninstall|clean|cleanall}"
> 
> #Patch
> patch: usbatm.c.orig usbatm.h.orig
>         patch < usbatm-oam-support.patch
> usbatm.c.orig:
>         test -f usbatm.c.orig && exit 1
>         cp -a usbatm.c usbatm.c.orig
> usbatm.h.orig:
>         test -f usbatm.h.orig && exit 1
>         cp -a usbatm.h usbatm.h.orig
> 
> #Build
> build: usbatm.ko cxacru.ko
> 
> usbatm.ko: usbatm.c
>         $(MAKE) -C $(KDIR) M=$(PWD) modules
> cxacru.ko: cxacru.c
>         $(MAKE) -C $(KDIR) M=$(PWD) modules
> 
> #Install
> install: usbatm.ko cxacru.ko uninstall
>         $(SUDO) sh -x -c '/sbin/modprobe -rv cxacru;\
>                 /sbin/modprobe -rv usbatm;\
>                 cp -a usbatm.ko $(MDIR)/updates/.;\
>                 cp -a cxacru.ko $(MDIR)/updates/.;\
>                 /sbin/depmod -a;\
>                 /sbin/modprobe -v cxacru;\
>                 /sbin/modprobe -v usbatm'
> 
> uninstall:
>         $(SUDO) sh -x -c '/sbin/modprobe -rv cxacru;\
>                 /sbin/modprobe -rv usbatm;\
>                 /sbin/modprobe -rv cxacru;\
>                 rm -f $(MDIR)/updates/usbatm.ko;\
>                 rm -f $(MDIR)/updates/cxacru.ko;\
>                 /sbin/depmod -a;\
>                 /sbin/modprobe -v cxacru;\
>                 /sbin/modprobe -v usbatm'
> #Clear files
> clear: clean
> clean:
>         rm -fr \
>                 usbatm.ko usbatm.mod.c usbatm.mod.o usbatm.o \
>                 .usbatm.ko.cmd .usbatm.mod.o.cmd .usbatm.o.cmd \
>                 cxacru.ko cxacru.mod.c cxacru.mod.o cxacru.o \
>                 .cxacru.ko.cmd .cxacru.mod.o.cmd .cxacru.o.cmd \
>                 Modules.symvers .tmp_versions
> 
> cleanall: clean uninstall
> 

usbatm-oam-support.patch:

> diff -u atm.orig/usbatm.c atm/usbatm.c
> --- atm.orig/usbatm.c   2006-06-18 03:49:35.000000000 +0200
> +++ atm/usbatm.c        2006-07-25 12:07:28.000000000 +0200
> @@ -92,18 +92,18 @@
>  #endif
> 
>  #define DRIVER_AUTHOR  "Johan Verrept, Duncan Sands <duncan.sands at free.fr>"
> -#define DRIVER_VERSION "1.10"
> +#define DRIVER_VERSION "1.10-OAM"
>  #define DRIVER_DESC    "Generic USB ATM/DSL I/O, version " DRIVER_VERSION
> 
>  static const char usbatm_driver_name[] = "usbatm";
> 
>  #define UDSL_MAX_RCV_URBS              16
>  #define UDSL_MAX_SND_URBS              16
> -#define UDSL_MAX_BUF_SIZE              65536
> +#define UDSL_MAX_BUF_SIZE              64 * 1024       /* bytes */
>  #define UDSL_DEFAULT_RCV_URBS          4
>  #define UDSL_DEFAULT_SND_URBS          4
> -#define UDSL_DEFAULT_RCV_BUF_SIZE      3392    /* 64 * ATM_CELL_SIZE */
> -#define UDSL_DEFAULT_SND_BUF_SIZE      3392    /* 64 * ATM_CELL_SIZE */
> +#define UDSL_DEFAULT_RCV_BUF_SIZE      64 * ATM_CELL_SIZE      /* bytes */
> +#define UDSL_DEFAULT_SND_BUF_SIZE      64 * ATM_CELL_SIZE      /* bytes */
> 
>  #define ATM_CELL_HEADER                        (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
> 
> @@ -135,7 +135,7 @@
>  module_param(snd_buf_bytes, uint, S_IRUGO);
>  MODULE_PARM_DESC(snd_buf_bytes,
>                  "Size of the buffers used for transmission, in bytes (range: 1-"
> -                __MODULE_STRING(UDSL_MAX_BUF_SIZE) ", default: "
> +                __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
>                  __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
> 
> 
> @@ -183,7 +183,6 @@
>         .owner          = THIS_MODULE,
>  };
> 
> -
>  /***********
>  **  misc  **
>  ***********/
> @@ -202,12 +201,37 @@
>                 dev_kfree_skb_any(skb);
>  }
> 
> +static u16 crc10_table[256] = {
> +       0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
> +       0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
> +       0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
> +       0x053, 0x260, 0x206, 0x035, 0x2ca, 0x0f9, 0x09f, 0x2ac, 0x352, 0x161, 0x107, 0x334, 0x1cb, 0x3f8, 0x39e, 0x1ad,
> +       0x0c4, 0x2f7, 0x291, 0x0a2, 0x25d, 0x06e, 0x008, 0x23b, 0x3c5, 0x1f6, 0x190, 0x3a3, 0x15c, 0x36f, 0x309, 0x13a,
> +       0x0f5, 0x2c6, 0x2a0, 0x093, 0x26c, 0x05f, 0x039, 0x20a, 0x3f4, 0x1c7, 0x1a1, 0x392, 0x16d, 0x35e, 0x338, 0x10b,
> +       0x0a6, 0x295, 0x2f3, 0x0c0, 0x23f, 0x00c, 0x06a, 0x259, 0x3a7, 0x194, 0x1f2, 0x3c1, 0x13e, 0x30d, 0x36b, 0x158,
> +       0x097, 0x2a4, 0x2c2, 0x0f1, 0x20e, 0x03d, 0x05b, 0x268, 0x396, 0x1a5, 0x1c3, 0x3f0, 0x10f, 0x33c, 0x35a, 0x169,
> +       0x188, 0x3bb, 0x3dd, 0x1ee, 0x311, 0x122, 0x144, 0x377, 0x289, 0x0ba, 0x0dc, 0x2ef, 0x010, 0x223, 0x245, 0x076,
> +       0x1b9, 0x38a, 0x3ec, 0x1df, 0x320, 0x113, 0x175, 0x346, 0x2b8, 0x08b, 0x0ed, 0x2de, 0x021, 0x212, 0x274, 0x047,
> +       0x1ea, 0x3d9, 0x3bf, 0x18c, 0x373, 0x140, 0x126, 0x315, 0x2eb, 0x0d8, 0x0be, 0x28d, 0x072, 0x241, 0x227, 0x014,
> +       0x1db, 0x3e8, 0x38e, 0x1bd, 0x342, 0x171, 0x117, 0x324, 0x2da, 0x0e9, 0x08f, 0x2bc, 0x043, 0x270, 0x216, 0x025,
> +       0x14c, 0x37f, 0x319, 0x12a, 0x3d5, 0x1e6, 0x180, 0x3b3, 0x24d, 0x07e, 0x018, 0x22b, 0x0d4, 0x2e7, 0x281, 0x0b2,
> +       0x17d, 0x34e, 0x328, 0x11b, 0x3e4, 0x1d7, 0x1b1, 0x382, 0x27c, 0x04f, 0x029, 0x21a, 0x0e5, 0x2d6, 0x2b0, 0x083,
> +       0x12e, 0x31d, 0x37b, 0x148, 0x3b7, 0x184, 0x1e2, 0x3d1, 0x22f, 0x01c, 0x07a, 0x249, 0x0b6, 0x285, 0x2e3, 0x0d0,
> +       0x11f, 0x32c, 0x34a, 0x179, 0x386, 0x1b5, 0x1d3, 0x3e0, 0x21e, 0x02d, 0x04b, 0x278, 0x087, 0x2b4, 0x2d2, 0x0e1,
> +};
> +
> +static u16 inline crc10(u16 init, u8 *data, int len)
> +{
> +       while (len--)
> +               init = ((init << 8) & 0x3ff) ^ crc10_table[(init >> 2) & 0xff] ^ *data++;
> +       return init;
> +}
> 
>  /***********
>  **  urbs  **
>  ************/
> 
> -static struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
> +static inline struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
>  {
>         struct urb *urb;
> 
> @@ -224,7 +248,7 @@
>         return urb;
>  }
> 
> -static int usbatm_submit_urb(struct urb *urb)
> +static inline int usbatm_submit_urb(struct urb *urb)
>  {
>         struct usbatm_channel *channel = urb->context;
>         int ret;
> @@ -283,6 +307,42 @@
>                 tasklet_schedule(&channel->tasklet);
>  }
> 
> +/* OAM loopback reply (fire-and-forget) */
> +static int usbatm_oam_reply(struct usbatm_data *instance, u8 *source)
> +{
> +       struct urb *urb;
> +       u16 crc;
> +       u8 *buffer;
> +
> +       if (source[ATM_CELL_HEADER] != 0x18 || source[ATM_CELL_HEADER + 1] != 0x01) {
> +               atm_dbg(instance, "%s: unexpected OAM type/function %x direction %x!\n",
> +                       __func__, source[ATM_CELL_HEADER], source[ATM_CELL_HEADER + 1]);
> +               return -EPROTO;
> +       }
> +
> +       if (crc10(0, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD)) {
> +               atm_dbg(instance, "%s: OAM CRC10 error!\n", __func__);
> +               return -EIO;
> +       }
> +
> +       urb = usbatm_pop_urb(&instance->tx_channel);
> +       if (!urb)
> +               return -ENOMEM;
> +
> +       buffer = urb->transfer_buffer;
> +       memcpy(buffer, source, ATM_CELL_SIZE);
> +
> +       buffer[ATM_CELL_HEADER + 1] = 0;        /* update the direction field */
> +
> +       memset(buffer + ATM_CELL_SIZE - 2, 0, 2);
> +
> +       crc = crc10(0, buffer + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
> +       buffer[ATM_CELL_SIZE - 2] = (crc >> 8) & 0x3;
> +       buffer[ATM_CELL_SIZE - 1] = crc & 0xff;
> +
> +       urb->transfer_buffer_length = instance->tx_channel.stride;
> +       return usbatm_submit_urb(urb);
> +}
> 
>  /*************
>  **  decode  **
> @@ -324,12 +384,24 @@
> 
>         vcc = instance->cached_vcc->vcc;
> 
> +//     /* OAM F5 end-to-end */
> +//     if (pti == ATM_PTI_E2EF5) {
> +//             if (printk_ratelimit())
> +//                     atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
> +//                             __func__, vpi, vci);
> +//             atomic_inc(&vcc->stats->rx_err);
> +//             return;
> +//     }
> +
>         /* OAM F5 end-to-end */
>         if (pti == ATM_PTI_E2EF5) {
>                 if (printk_ratelimit())
> -                       atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n",
> +                       atm_warn(instance, "%s: Trying to support OAM (vpi %d, vci %d)!\n",
>                                 __func__, vpi, vci);
> -               atomic_inc(&vcc->stats->rx_err);
> +               if (usbatm_oam_reply(instance, source)) {
> +                       atm_dbg(instance, "%s: OAM reply failed (vpi %d, vci %d)!\n", __func__, vpi, vci);
> +                       atomic_inc(&vcc->stats->rx_err);
> +               }
>                 return;
>         }
> 
> @@ -823,7 +895,7 @@
>                 return -EINVAL;
>         }
> 
> -       mutex_lock(&instance->serialize);       /* vs self, usbatm_atm_close, usbatm_usb_disconnect */+       down(&instance->serialize);     /* vs self, usbatm_atm_close, usbatm_usb_disconnect */
> 
>         if (instance->disconnected) {
>                 atm_dbg(instance, "%s: disconnected!\n", __func__);
> @@ -837,7 +909,7 @@
>                 goto fail;
>         }
> 
> -       if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
> +       if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
>                 atm_err(instance, "%s: no memory for vcc_data!\n", __func__);
>                 ret = -ENOMEM;
>                 goto fail;
> @@ -867,7 +939,7 @@
>         set_bit(ATM_VF_PARTIAL, &vcc->flags);
>         set_bit(ATM_VF_READY, &vcc->flags);
> 
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new);
> 
> @@ -875,7 +947,7 @@
> 
>  fail:
>         kfree(new);
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
>         return ret;
>  }
> 
> @@ -896,7 +968,7 @@
> 
>         usbatm_cancel_send(instance, vcc);
> 
> -       mutex_lock(&instance->serialize);       /* vs self, usbatm_atm_open, usbatm_usb_disconnect */
> +       down(&instance->serialize);     /* vs self, usbatm_atm_open, usbatm_usb_disconnect */
> 
>         tasklet_disable(&instance->rx_channel.tasklet);
>         if (instance->cached_vcc == vcc_data) {
> @@ -919,7 +991,7 @@
>         clear_bit(ATM_VF_PARTIAL, &vcc->flags);
>         clear_bit(ATM_VF_ADDR, &vcc->flags);
> 
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         atm_dbg(instance, "%s successful\n", __func__);
>  }
> @@ -1009,9 +1081,9 @@
>         if (!ret)
>                 ret = usbatm_atm_init(instance);
> 
> -       mutex_lock(&instance->serialize);
> +       down(&instance->serialize);
>         instance->thread_pid = -1;
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         complete_and_exit(&instance->thread_exited, ret);
>  }
> @@ -1025,9 +1097,9 @@
>                 return ret;
>         }
> 
> -       mutex_lock(&instance->serialize);
> +       down(&instance->serialize);
>         instance->thread_pid = ret;
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         wait_for_completion(&instance->thread_started);
> 
> @@ -1066,7 +1138,7 @@
>                         intf->altsetting->desc.bInterfaceNumber);
> 
>         /* instance init */
> -       instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
> +       instance = kmalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
>         if (!instance) {
>                 dev_err(dev, "%s: no memory for instance data!\n", __func__);
>                 return -ENOMEM;
> @@ -1110,7 +1182,7 @@
>         /* private fields */
> 
>         kref_init(&instance->refcount);         /* dropped in usbatm_usb_disconnect */
> -       mutex_init(&instance->serialize);
> +       init_MUTEX(&instance->serialize);
> 
>         instance->thread_pid = -1;
>         init_completion(&instance->thread_started);
> @@ -1186,7 +1258,7 @@
>                 instance->urbs[i] = urb;
> 
>                 /* zero the tx padding to avoid leaking information */
> -               buffer = kzalloc(channel->buf_size, GFP_KERNEL);
> +               buffer = kmalloc(channel->buf_size, GFP_KERNEL);
>                 if (!buffer) {
>                         dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i);
>                         error = -ENOMEM;
> @@ -1273,18 +1345,18 @@
> 
>         usb_set_intfdata(intf, NULL);
> 
> -       mutex_lock(&instance->serialize);
> +       down(&instance->serialize);
>         instance->disconnected = 1;
>         if (instance->thread_pid >= 0)
>                 kill_proc(instance->thread_pid, SIGTERM, 1);
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         wait_for_completion(&instance->thread_exited);
> 
> -       mutex_lock(&instance->serialize);
> +       down(&instance->serialize);
>         list_for_each_entry(vcc_data, &instance->vcc_list, list)
>                 vcc_release_async(vcc_data->vcc, -EPIPE);
> -       mutex_unlock(&instance->serialize);
> +       up(&instance->serialize);
> 
>         tasklet_disable(&instance->rx_channel.tasklet);
>         tasklet_disable(&instance->tx_channel.tasklet);
> diff -u atm.orig/usbatm.h atm/usbatm.h
> --- atm.orig/usbatm.h   2006-06-18 03:49:35.000000000 +0200
> +++ atm/usbatm.h        2006-07-25 12:11:53.000000000 +0200
> @@ -34,7 +34,6 @@
>  #include <linux/list.h>
>  #include <linux/stringify.h>
>  #include <linux/usb.h>
> -#include <linux/mutex.h>
> 
>  /*
>  #define VERBOSE_DEBUG
> @@ -172,7 +171,7 @@
>          ********************************/
> 
>         struct kref refcount;
> -       struct mutex serialize;
> +       struct semaphore serialize;
>         int disconnected;
> 
>         /* heavy init */
-- 
Dario Lesca <d.lesca at solinos.it>




More information about the fedora-devel-list mailing list