Author: wolvverine                   Date: Thu Aug 10 13:06:24 2006 GMT
Module: SOURCES                       Tag: LINUX_2_6_16
---- Log message:
-add wireless extension 
http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html#wext

---- Files affected:
SOURCES:
   linux-2.6.16-we20-6.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/linux-2.6.16-we20-6.patch
diff -u /dev/null SOURCES/linux-2.6.16-we20-6.patch:1.1.2.1
--- /dev/null   Thu Aug 10 15:06:24 2006
+++ SOURCES/linux-2.6.16-we20-6.patch   Thu Aug 10 15:06:19 2006
@@ -0,0 +1,1233 @@
+diff -u -p linux/include/linux/wireless.19.h linux/include/linux/wireless.h
+--- linux/include/linux/wireless.19.h  2006-02-17 10:49:04.000000000 -0800
++++ linux/include/linux/wireless.h     2006-02-17 17:58:10.000000000 -0800
+@@ -1,10 +1,10 @@
+ /*
+  * This file define a set of standard wireless extensions
+  *
+- * Version :  19      18.3.05
++ * Version :  20      17.2.06
+  *
+  * Authors :  Jean Tourrilhes - HPL - <[EMAIL PROTECTED]>
+- * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
++ * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+  */
+ 
+ #ifndef _LINUX_WIRELESS_H
+@@ -80,7 +80,7 @@
+  * (there is some stuff that will be added in the future...)
+  * I just plan to increment with each new version.
+  */
+-#define WIRELESS_EXT  19
++#define WIRELESS_EXT  20
+ 
+ /*
+  * Changes :
+@@ -204,6 +204,10 @@
+  *    - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
+  *    - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
+  *    - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
++ *
++ * V19 to V20
++ * ----------
++ *    - RtNetlink requests support (SET/GET)
+  */
+ 
+ /**************************** CONSTANTS ****************************/
+diff -u -p linux/include/net/iw_handler.19.h linux/include/net/iw_handler.h
+--- linux/include/net/iw_handler.19.h  2006-02-17 10:49:15.000000000 -0800
++++ linux/include/net/iw_handler.h     2006-02-17 18:01:36.000000000 -0800
+@@ -4,7 +4,7 @@
+  * Version :  7       18.3.05
+  *
+  * Authors :  Jean Tourrilhes - HPL - <[EMAIL PROTECTED]>
+- * Copyright (c) 2001-2005 Jean Tourrilhes, All Rights Reserved.
++ * Copyright (c) 2001-2006 Jean Tourrilhes, All Rights Reserved.
+  */
+ 
+ #ifndef _IW_HANDLER_H
+@@ -436,6 +436,16 @@ extern int dev_get_wireless_info(char * 
+ /* Handle IOCTLs, called in net/core/dev.c */
+ extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
+ 
++/* Handle RtNetlink requests, called in net/core/rtnetlink.c */
++extern int wireless_rtnetlink_set(struct net_device * dev,
++                                char *                data,
++                                int                   len);
++extern int wireless_rtnetlink_get(struct net_device * dev,
++                                char *                data,
++                                int                   len,
++                                char **               p_buf,
++                                int *                 p_len);
++
+ /* Second : functions that may be called by driver modules */
+ 
+ /* Send a single event to user space */
+diff -u -p linux/drivers/net/wireless/Kconfig.19 
linux/drivers/net/wireless/Kconfig
+--- linux/drivers/net/wireless/Kconfig.19      2006-02-21 13:11:34.000000000 
-0800
++++ linux/drivers/net/wireless/Kconfig 2006-02-22 11:48:27.000000000 -0800
+@@ -24,6 +24,15 @@ config NET_RADIO
+         the tools from
+         <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+ 
++config NET_WIRELESS_RTNETLINK
++      bool "Wireless Extension API over RtNetlink"
++      ---help---
++        Support the Wireless Extension API over the RtNetlink socket
++        in addition to the traditional ioctl interface (selected above).
++
++        For now, few tools use this facility, but it might grow in the
++        future. The only downside is that it adds 4.5 kB to your kernel.
++
+ # Note : the cards are obsolete (can't buy them anymore), but the drivers
+ # are not, as people are still using them...
+ comment "Obsolete Wireless cards support (pre-802.11)"
+diff -u -p linux/net/core/rtnetlink.19.c linux/net/core/rtnetlink.c
+--- linux/net/core/rtnetlink.19.c      2006-02-17 10:49:26.000000000 -0800
++++ linux/net/core/rtnetlink.c 2006-02-21 12:57:07.000000000 -0800
+@@ -50,6 +50,10 @@
+ #include <net/sock.h>
+ #include <net/pkt_sched.h>
+ #include <net/netlink.h>
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++#include <linux/wireless.h>
++#include <net/iw_handler.h>
++#endif        /* CONFIG_NET_WIRELESS_RTNETLINK */
+ 
+ DECLARE_MUTEX(rtnl_sem);
+ 
+@@ -410,6 +414,17 @@ static int do_setlink(struct sk_buff *sk
+                       goto out;
+       }
+ 
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++      if (ida[IFLA_WIRELESS - 1]) {
++
++              /* Call Wireless Extensions.
++               * Various stuff checked in there... */
++              err = wireless_rtnetlink_set(dev, RTA_DATA(ida[IFLA_WIRELESS - 
1]), ida[IFLA_WIRELESS - 1]->rta_len);
++              if (err)
++                      goto out;
++      }
++#endif        /* CONFIG_NET_WIRELESS_RTNETLINK */
++
+       err = 0;
+ 
+ out:
+@@ -420,6 +435,83 @@ out:
+       return err;
+ }
+ 
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++static int do_getlink(struct sk_buff *in_skb, struct nlmsghdr* in_nlh, void 
*arg)
++{
++      struct ifinfomsg  *ifm = NLMSG_DATA(in_nlh);
++      struct rtattr    **ida = arg;
++      struct net_device *dev;
++      struct ifinfomsg *r;
++      struct nlmsghdr  *nlh;
++      int err = -ENOBUFS;
++      struct sk_buff *skb;
++      unsigned char    *b;
++      char *iw_buf = NULL;
++      int iw_buf_len = 0;
++
++      if (ifm->ifi_index >= 0)
++              dev = dev_get_by_index(ifm->ifi_index);
++      else
++              return -EINVAL;
++      if (!dev)
++              return -ENODEV;
++
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++      if (ida[IFLA_WIRELESS - 1]) {
++
++              /* Call Wireless Extensions. We need to know the size before
++               * we can alloc. Various stuff checked in there... */
++              err = wireless_rtnetlink_get(dev, RTA_DATA(ida[IFLA_WIRELESS - 
1]), ida[IFLA_WIRELESS - 1]->rta_len, &iw_buf, &iw_buf_len);
++              if (err)
++                      goto out;
++      }
++#endif        /* CONFIG_NET_WIRELESS_RTNETLINK */
++
++      /* Create a skb big enough to include all the data.
++       * Some requests are way bigger than 4k... Jean II */
++      skb = alloc_skb((NLMSG_LENGTH(sizeof(*r))) + (RTA_SPACE(iw_buf_len)),
++                      GFP_KERNEL);
++      if (!skb)
++              goto out;
++      b = skb->tail;
++
++      /* Put in the message the usual good stuff */
++      nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid, in_nlh->nlmsg_seq,
++                      RTM_NEWLINK, sizeof(*r));
++      r = NLMSG_DATA(nlh);
++      r->ifi_family = AF_UNSPEC;
++      r->__ifi_pad = 0;
++      r->ifi_type = dev->type;
++      r->ifi_index = dev->ifindex;
++      r->ifi_flags = dev->flags;
++      r->ifi_change = 0;
++
++      /* Put the wireless payload if it exist */
++      if(iw_buf != NULL)
++              RTA_PUT(skb, IFLA_WIRELESS, iw_buf_len,
++                      iw_buf + IW_EV_POINT_OFF);
++
++      nlh->nlmsg_len = skb->tail - b;
++
++      /* Needed ? */
++      NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
++
++      err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
++      if (err > 0)
++              err = 0;
++out:
++      if(iw_buf != NULL)
++              kfree(iw_buf);
++      dev_put(dev);
++      return err;
++
++rtattr_failure:
++nlmsg_failure:
++      kfree_skb(skb);
++      goto out;
++}
++#endif        /* CONFIG_NET_WIRELESS_RTNETLINK */
++
+ static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback 
*cb)
+ {
+       int idx;
+@@ -585,7 +677,11 @@ static void rtnetlink_rcv(struct sock *s
+ 
+ static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
+ {
+-      [RTM_GETLINK     - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
++      [RTM_GETLINK     - RTM_BASE] = {
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++                                       .doit   = do_getlink,
++#endif        /* CONFIG_NET_WIRELESS_RTNETLINK */
++                                       .dumpit = rtnetlink_dump_ifinfo },
+       [RTM_SETLINK     - RTM_BASE] = { .doit   = do_setlink            },
+       [RTM_GETADDR     - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
+       [RTM_GETROUTE    - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
+diff -u -p linux/net/core/wireless.19.c linux/net/core/wireless.c
+--- linux/net/core/wireless.19.c       2006-02-17 10:49:37.000000000 -0800
++++ linux/net/core/wireless.c  2006-02-22 11:46:52.000000000 -0800
+@@ -2,7 +2,7 @@
+  * This file implement the Wireless Extensions APIs.
+  *
+  * Authors :  Jean Tourrilhes - HPL - <[EMAIL PROTECTED]>
+- * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
++ * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
+  *
+  * (As all part of the Linux kernel, this file is GPL)
+  */
+@@ -65,6 +65,9 @@
+  *    o Start deprecating dev->get_wireless_stats, output a warning
+  *    o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
+  *    o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats)
++ *
++ * v8 - 17.02.06 - Jean II
++ *    o RtNetlink requests support (SET/GET)
+  */
+ 
+ /***************************** INCLUDES *****************************/
+@@ -89,11 +92,13 @@
+ 
+ /* Debugging stuff */
+ #undef WE_IOCTL_DEBUG         /* Debug IOCTL API */
++#undef WE_RTNETLINK_DEBUG     /* Debug RtNetlink API */
+ #undef WE_EVENT_DEBUG         /* Debug Event dispatcher */
+ #undef WE_SPY_DEBUG           /* Debug enhanced spy support */
+ 
+ /* Options */
+-#define WE_EVENT_NETLINK      /* Propagate events using rtnetlink */
++//CONFIG_NET_WIRELESS_RTNETLINK       /* Wireless requests over RtNetlink */
++#define WE_EVENT_RTNETLINK    /* Propagate events using RtNetlink */
+ #define WE_SET_EVENT          /* Generate an event on some set commands */
+ 
+ /************************* GLOBAL VARIABLES *************************/
+@@ -156,13 +161,18 @@ static const struct iw_ioctl_description
+               .header_type    = IW_HEADER_TYPE_NULL,
+       },
+       [SIOCGIWPRIV    - SIOCIWFIRST] = { /* (handled directly by us) */
+-              .header_type    = IW_HEADER_TYPE_NULL,
++              .header_type    = IW_HEADER_TYPE_POINT,
++              .token_size     = sizeof(struct iw_priv_args),
++              .max_tokens     = 16,
++              .flags          = IW_DESCR_FLAG_NOMAX,
+       },
+       [SIOCSIWSTATS   - SIOCIWFIRST] = {
+               .header_type    = IW_HEADER_TYPE_NULL,
+       },
+       [SIOCGIWSTATS   - SIOCIWFIRST] = { /* (handled directly by us) */
+-              .header_type    = IW_HEADER_TYPE_NULL,
++              .header_type    = IW_HEADER_TYPE_POINT,
++              .token_size     = 1,
++              .max_tokens     = sizeof(struct iw_statistics),
+               .flags          = IW_DESCR_FLAG_DUMP,
+       },
+       [SIOCSIWSPY     - SIOCIWFIRST] = {
+@@ -529,6 +539,70 @@ static inline int adjust_priv_size(__u16
+       return num * iw_priv_type_size[type];
+ }
+ 
++/* ---------------------------------------------------------------- */
++/*
++ * Standard Wireless Handler : get wireless stats
++ *    Allow programatic access to /proc/net/wireless even if /proc
++ *    doesn't exist... Also more efficient...
++ */
++static int iw_handler_get_iwstats(struct net_device *         dev,
++                                struct iw_request_info *      info,
++                                union iwreq_data *            wrqu,
++                                char *                        extra)
++{
++      /* Get stats from the driver */
++      struct iw_statistics *stats;
++
++      stats = get_wireless_stats(dev);
++      if (stats != (struct iw_statistics *) NULL) {
++
++              /* Copy statistics to extra */
++              memcpy(extra, stats, sizeof(struct iw_statistics));
++              wrqu->data.length = sizeof(struct iw_statistics);
++
++              /* Check if we need to clear the updated flag */
++              if(wrqu->data.flags != 0)
++                      stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
++              return 0;
++      } else
++              return -EOPNOTSUPP;
++}
++
++/* ---------------------------------------------------------------- */
++/*
++ * Standard Wireless Handler : get iwpriv definitions
++ * Export the driver private handler definition
++ * They will be picked up by tools like iwpriv...
++ */
++static int iw_handler_get_private(struct net_device *         dev,
++                                struct iw_request_info *      info,
++                                union iwreq_data *            wrqu,
++                                char *                        extra)
++{
++      /* Check if the driver has something to export */
++      if((dev->wireless_handlers->num_private_args == 0) ||
++         (dev->wireless_handlers->private_args == NULL))
++              return -EOPNOTSUPP;
++
++      /* Check if there is enough buffer up there */
++      if(wrqu->data.length < dev->wireless_handlers->num_private_args) {
++              /* User space can't know in advance how large the buffer
++               * needs to be. Give it a hint, so that we can support
++               * any size buffer we want somewhat efficiently... */
++              wrqu->data.length = dev->wireless_handlers->num_private_args;
++              return -E2BIG;
++      }
++
++      /* Set the number of available ioctls. */
++      wrqu->data.length = dev->wireless_handlers->num_private_args;
++
++      /* Copy structure to the user buffer. */
++      memcpy(extra, dev->wireless_handlers->private_args,
++             sizeof(struct iw_priv_args) * wrqu->data.length);
++
++      return 0;
++}
++
+ 
+ /******************** /proc/net/wireless SUPPORT ********************/
+ /*
+@@ -630,81 +704,14 @@ int __init wireless_proc_init(void)
+ 
+ /* ---------------------------------------------------------------- */
+ /*
+- *    Allow programatic access to /proc/net/wireless even if /proc
+- *    doesn't exist... Also more efficient...
+- */
+-static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
+-{
+-      /* Get stats from the driver */
+-      struct iw_statistics *stats;
+-
+-      stats = get_wireless_stats(dev);
+-      if (stats != (struct iw_statistics *) NULL) {
+-              struct iwreq *  wrq = (struct iwreq *)ifr;
+-
+-              /* Copy statistics to the user buffer */
+-              if(copy_to_user(wrq->u.data.pointer, stats,
+-                              sizeof(struct iw_statistics)))
+-                      return -EFAULT;
+-
+-              /* Check if we need to clear the updated flag */
+-              if(wrq->u.data.flags != 0)
+-                      stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
+-              return 0;
+-      } else
+-              return -EOPNOTSUPP;
+-}
+-
+-/* ---------------------------------------------------------------- */
+-/*
+- * Export the driver private handler definition
+- * They will be picked up by tools like iwpriv...
+- */
+-static inline int ioctl_export_private(struct net_device *    dev,
+-                                     struct ifreq *           ifr)
+-{
+-      struct iwreq *                          iwr = (struct iwreq *) ifr;
+-
+-      /* Check if the driver has something to export */
+-      if((dev->wireless_handlers->num_private_args == 0) ||
+-         (dev->wireless_handlers->private_args == NULL))
+-              return -EOPNOTSUPP;
+-
+-      /* Check NULL pointer */
+-      if(iwr->u.data.pointer == NULL)
+-              return -EFAULT;
+-
+-      /* Check if there is enough buffer up there */
+-      if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
+-              /* User space can't know in advance how large the buffer
+-               * needs to be. Give it a hint, so that we can support
+-               * any size buffer we want somewhat efficiently... */
+-              iwr->u.data.length = dev->wireless_handlers->num_private_args;
+-              return -E2BIG;
+-      }
+-
+-      /* Set the number of available ioctls. */
+-      iwr->u.data.length = dev->wireless_handlers->num_private_args;
+-
+-      /* Copy structure to the user buffer. */
+-      if (copy_to_user(iwr->u.data.pointer,
+-                       dev->wireless_handlers->private_args,
+-                       sizeof(struct iw_priv_args) * iwr->u.data.length))
+-              return -EFAULT;
+-
+-      return 0;
+-}
+-
+-/* ---------------------------------------------------------------- */
+-/*
+  * Wrapper to call a standard Wireless Extension handler.
+  * We do various checks and also take care of moving data between
+  * user space and kernel space.
+  */
+-static inline int ioctl_standard_call(struct net_device *     dev,
+-                                    struct ifreq *            ifr,
+-                                    unsigned int              cmd,
+-                                    iw_handler                handler)
++static int ioctl_standard_call(struct net_device *    dev,
++                             struct ifreq *           ifr,
++                             unsigned int             cmd,
++                             iw_handler               handler)
+ {
+       struct iwreq *                          iwr = (struct iwreq *) ifr;
+       const struct iw_ioctl_description *     descr;
+@@ -1048,14 +1055,20 @@ int wireless_process_ioctl(struct ifreq 
+       {
+               case SIOCGIWSTATS:
+                       /* Get Wireless Stats */
+-                      return dev_iwstats(dev, ifr);
++                      return ioctl_standard_call(dev,
++                                                 ifr,
++                                                 cmd,
++                                                 &iw_handler_get_iwstats);
+ 
+               case SIOCGIWPRIV:
+                       /* Check if we have some wireless handlers defined */
+                       if(dev->wireless_handlers != NULL) {
+                               /* We export to user space the definition of
+                                * the private handler ourselves */
+-                              return ioctl_export_private(dev, ifr);
++                              return ioctl_standard_call(dev,
++                                                         ifr,
++                                                         cmd,
++                                                         
&iw_handler_get_private);
+                       }
+                       // ## Fall-through for old API ##
+               default:
+@@ -1088,16 +1101,739 @@ int wireless_process_ioctl(struct ifreq 
+       return -EINVAL;
+ }
+ 
++/********************** RTNETLINK REQUEST API **********************/
++/*
++ * The alternate user space API to configure all those Wireless Extensions
++ * is through RtNetlink.
++ * This API support only the new driver API (iw_handler).
++ *
++ * This RtNetlink API use the same query/reply model as the ioctl API.
++ * Maximum effort has been done to fit in the RtNetlink model, and
++ * we support both RtNetlink Set and RtNelink Get operations.
++ * On the other hand, we don't offer Dump operations because of the
++ * following reasons :
++ *    o Large number of parameters, most optional
++ *    o Large size of some parameters (> 100 bytes)
++ *    o Each parameters need to be extracted from hardware
++ *    o Scan requests can take seconds and disable network activity.
++ * Because of this high cost/overhead, we want to return only the
++ * parameters the user application is really interested in.
++ * We could offer partial Dump using the IW_DESCR_FLAG_DUMP flag.
++ *
++ * The API uses the standard RtNetlink socket. When the RtNetlink code
++ * find a IFLA_WIRELESS field in a RtNetlink SET_LINK request,
++ * it calls here.
++ */
++
++#ifdef CONFIG_NET_WIRELESS_RTNETLINK
++/* ---------------------------------------------------------------- */
++/*
++ * Wrapper to call a standard Wireless Extension GET handler.
++ * We do various checks and call the handler with the proper args.
++ */
++static int rtnetlink_standard_get(struct net_device * dev,
++                                struct iw_event *     request,
++                                int                   request_len,
++                                iw_handler            handler,
++                                char **               p_buf,
++                                int *                 p_len)
++{
++      const struct iw_ioctl_description *     descr = NULL;
++      unsigned int                            cmd;
++      union iwreq_data *                      wrqu;
++      int                                     hdr_len;
++      struct iw_request_info                  info;
++      char *                                  buffer = NULL;
++      int                                     buffer_size = 0;
++      int                                     ret = -EINVAL;
++
++      /* Get the description of the Request */
++      cmd = request->cmd;
++      if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
++              return -EOPNOTSUPP;
++      descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
++
++#ifdef WE_RTNETLINK_DEBUG
++      printk(KERN_DEBUG "%s (WE.r) : Found standard handler for 0x%04X\n",
++             dev->name, cmd);
++      printk(KERN_DEBUG "%s (WE.r) : Header type : %d, Token type : %d, size 
: %d, token : %d\n", dev->name, descr->header_type, descr->token_type, 
descr->token_size, descr->max_tokens);
++#endif        /* WE_RTNETLINK_DEBUG */
++
++      /* Check if wrqu is complete */
++      hdr_len = event_type_size[descr->header_type];
++      if(request_len < hdr_len) {
++#ifdef WE_RTNETLINK_DEBUG
++              printk(KERN_DEBUG
++                     "%s (WE.r) : Wireless request too short (%d)\n",
++                     dev->name, request_len);
++#endif        /* WE_RTNETLINK_DEBUG */
++              return -EINVAL;
++      }
++
++      /* Prepare the call */
++      info.cmd = cmd;
++      info.flags = 0;
++
++      /* Check if we have extra data in the reply or not */
++      if(descr->header_type != IW_HEADER_TYPE_POINT) {
++
++              /* Create the kernel buffer that we will return.
++               * It's at an offset to match the TYPE_POINT case... */
++              buffer_size = request_len + IW_EV_POINT_OFF;
++              buffer = kmalloc(buffer_size, GFP_KERNEL);
++              if (buffer == NULL) {
++                      return -ENOMEM;
++              }
++              /* Copy event data */
++              memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
++              /* Use our own copy of wrqu */
++              wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
++                                           + IW_EV_LCP_LEN);
++
++              /* No extra arguments. Trivial to handle */
++              ret = handler(dev, &info, wrqu, NULL);
++
++      } else {
++              union iwreq_data        wrqu_point;
++              char *                  extra = NULL;
++              int                     extra_size = 0;
++
++              /* Get a temp copy of wrqu (skip pointer) */
++              memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
++                     ((char *) request) + IW_EV_LCP_LEN,
++                     IW_EV_POINT_LEN - IW_EV_LCP_LEN);
++
++              /* Calculate space needed by arguments. Always allocate
++               * for max space. Easier, and won't last long... */
++              extra_size = descr->max_tokens * descr->token_size;
++              /* Support for very large requests */
++              if((descr->flags & IW_DESCR_FLAG_NOMAX) &&
++                 (wrqu_point.data.length > descr->max_tokens))
++                      extra_size = (wrqu_point.data.length
++                                    * descr->token_size);
++              buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
++#ifdef WE_RTNETLINK_DEBUG
++              printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
++                     dev->name, extra_size, buffer_size);
++#endif        /* WE_RTNETLINK_DEBUG */
++
++              /* Create the kernel buffer that we will return */
++              buffer = kmalloc(buffer_size, GFP_KERNEL);
++              if (buffer == NULL) {
++                      return -ENOMEM;
++              }
++
++              /* Put wrqu in the right place (just before extra).
++               * Leave space for IWE header and dummy pointer...
++               * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
++               */
++              memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
++                     ((char *) &wrqu_point) + IW_EV_POINT_OFF,
++                     IW_EV_POINT_LEN - IW_EV_LCP_LEN);
++              wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
++
++              /* Extra comes logically after that. Offset +12 bytes. */
++              extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
++
++              /* Call the handler */
++              ret = handler(dev, &info, wrqu, extra);
<<Diff was trimmed, longer than 597 lines>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to