SOURCES: linux-2.6-we20-6.patch (NEW) -add wireless extension http...
wolvverine
wolvverine at pld-linux.org
Thu Aug 10 14:11:15 CEST 2006
Author: wolvverine Date: Thu Aug 10 12:11:15 2006 GMT
Module: SOURCES Tag: HEAD
---- Log message:
-add wireless extension http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html#wext
---- Files affected:
SOURCES:
linux-2.6-we20-6.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/linux-2.6-we20-6.patch
diff -u /dev/null SOURCES/linux-2.6-we20-6.patch:1.1
--- /dev/null Thu Aug 10 14:11:15 2006
+++ SOURCES/linux-2.6-we20-6.patch Thu Aug 10 14:11:10 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 - <jt at hpl.hp.com>
+- * 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 - <jt at hpl.hp.com>
+- * 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 - <jt at hpl.hp.com>
+- * 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>>
More information about the pld-cvs-commit
mailing list