+ * BASIC PRINCIPLE
+ * ---------------
+ * Wireless Extension recognise that each wireless device has some
+ * specific features not covered by the standard wireless extensions.
+ * Private wireless ioctls/requests allow a device to export the control
+ * of those device specific features, and allow users to directly interact
+ * with your driver.
+ * There are many other ways you can implement such functionality :
+ * o module parameters
+ * o netlink socket
+ * o file system (/proc/ or /sysfs/)
+ * o extra character device (/dev/)
+ * Private wireless ioctls is one of the simplest implementation,
+ * however it is limited, so you may want to check the alternatives.
+ *
+ * Like for standard Wireless Extensions, each private wireless
+ * request is identified by an IOCTL NUMBER and carry a certain number
+ * of arguments (SET or GET).
+ * The driver exports a description of those requests (ioctl number,
+ * request name, set and get arguments). Then, iwpriv uses those request
+ * descriptions to call the appropriate request and handle the
+ * arguments.
+ *
+ * IOCTL RANGES :
+ * ------------
+ * The initial implementation of iwpriv was using the SIOCDEVPRIVATE
+ * ioctl range (up to 16 ioctls - driver specific). However, this was
+ * causing some compatibility problems with other usages of those
+ * ioctls, and those ioctls are supposed to be removed.
+ * Therefore, I created a new ioctl range, at SIOCIWFIRSTPRIV. Those
+ * ioctls are specific to Wireless Extensions, so you don't have to
+ * worry about collisions with other usages. On the other hand, in the
+ * new range, the SET convention is enforced (see below).
+ * The differences are : SIOCDEVPRIVATE SIOCIWFIRSTPRIV
+ * o availability <= 2.5.X WE > 11 (>= 2.4.13)
+ * o collisions yes no
+ * o SET convention optional enforced
+ * o number 16 32
+ *
+ * NEW DRIVER API :
+ * --------------
+ * Wireless Extension 13 introduces a new driver API. Wireless
+ * Extensions requests can be handled via a iw_handler table instead
+ * of through the regular ioctl handler.
+ * The new driver API can be handled only with the new ioctl range
+ * and enforces the GET convention (see below).
+ * The differences are : old API new API
+ * o handler do_ioctl() struct iw_handler_def
+ * o SIOCIWFIRSTPRIV WE > 11 yes
+ * o SIOCDEVPRIVATE yes no
+ * o GET convention optional enforced
+ * Note that the new API before Wireless Extension 15 contains bugs
+ * when handling sub-ioctls and addr/float data types.
+ *
+ * INLINING vs. POINTER :
+ * --------------------
+ * One of the tricky aspect of the old driver API is how the data
+ * is handled, which is how the driver is supposed to extract the data
+ * passed to it by iwpriv.
+ * 1) If the data has a fixed size (private ioctl definition
+ * has the flag IW_PRIV_SIZE_FIXED) and the byte size of the data is
+ * lower than 16 bytes, the data will be inlined. The driver can extract
+ * data in the field 'u.name' of the struct iwreq.
+ * 2) If the if the data doesn't have a fixed size or is larger than
+ * 16 bytes, the data is passed by pointer. struct iwreq contains a
+ * struct iwpoint with a user space pointer to the data. Appropriate
+ * copy_from/to_user() function should be used.
+ *
+ * With the new API, this is handled transparently, the data is
+ * always available as the fourth argument of the request handler
+ * (usually called 'extra').
+ *
+ * SET/GET CONVENTION :
+ * ------------------
+ * Simplistic summary :
+ * o even numbered ioctls are SET, restricted to root, and should not
+ * return arguments (get_args = 0).
+ * o odd numbered ioctls are GET, authorised to anybody, and should
+ * not expect any arguments (set_args = 0).
+ *
+ * The regular Wireless Extensions use the SET/GET convention, where
+ * the low order bit identify a SET (0) or a GET (1) request. The private
+ * Wireless Extension is not as restrictive, but still has some
+ * limitations.
+ * The new ioctl range enforces the SET convention : SET request will
+ * be available to root only and can't return any arguments. If you don't
+ * like that, just use every other two ioctl.
+ * The new driver API enforce the GET convention : GET request won't
+ * be able to accept any arguments (except if its fits within (union
+ * iwreq_data)). If you don't like that, you can either use the Token Index
+ * support or the old API (aka the ioctl handler).
+ * In any case, it's a good idea to not have ioctl with both SET
+ * and GET arguments. If the GET arguments doesn't fit within
+ * (union iwreq_data) and SET do, or vice versa, the current code in iwpriv
+ * won't work. One exception is if both SET and GET arguments fit within
+ * (union iwreq_data), this case should be handled safely in a GET
+ * request.
+ * If you don't fully understand those limitations, just follow the
+ * rules of the simplistic summary ;-)
+ *
+ * SUB-IOCTLS :
+ * ----------
+ * Wireless Extension 15 introduces sub-ioctls. For some applications,
+ * 32 ioctls is not enough, and this simple mechanism allows to increase
+ * the number of ioctls by adding a sub-ioctl index to some of the ioctls
+ * (so basically it's a two level addressing).
+ * One might argue that at the point, some other mechanisms might be
+ * better, like using a real filesystem abstraction (/proc, driverfs, ...),
+ * but sub-ioctls are simple enough and don't have much drawbacks (which
+ * means that it's a quick and dirty hack ;-).
+ *
+ * There are two slightly different variations of the sub-ioctl scheme :
+ * 1) If the payload fits within (union iwreq_data), the first int
+ * (4 bytes) is reserved as the sub-ioctl number and the regular payload
+ * shifted by 4 bytes. The handler must extract the sub-ioctl number,
+ * increment the data pointer and then use it in the usual way.
+ * 2) If the ioctl uses (struct iw_point), the sub-ioctl number is
+ * set in the flags member of the structure. In this case, the handler
+ * should simply get the sub-ioctl number from the flags and process the
+ * data in the usual way.
+ *
+ * Sub-ioctls are declared normally in the private definition table,
+ * with cmd (first arg) being the sub-ioctl number. Then, you should
+ * declare the real ioctl, which will process the sub-ioctls, with
+ * the SAME ARGUMENTS and a EMPTY NAME.
+ * Here's an example of how it could look like :
+ * --------------------------------------------
+ // --- sub-ioctls handlers ---
+ { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "" },
+ { 0x8BE1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "" },
+ // --- sub-ioctls definitions ---
+ { 1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_param1" },
+ { 1, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param1" },
+ { 2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_param2" },
+ { 2, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param2" },
+ // --- Raw access to sub-ioctl handlers ---
+ { 0x8BE0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_paramN" },
+ { 0x8BE1, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_paramN" },
+ * --------------------------------------------
+ * And iwpriv should do the rest for you ;-)
+ *
+ * Note that versions of iwpriv up to v24 (included) expect at most
+ * 16 ioctls definitions and will likely crash when given more.
+ * There is no fix that I can see, apart from recommending your users
+ * to upgrade their Wireless Tools. Wireless Extensions 15 will check this
+ * condition, so another workaround is restricting those extra definitions
+ * to WE-15.
+ *
+ * Another problem is that the new API before Wireless Extension 15
+ * has a bug when passing fixed arguments of 12-15 bytes. It will
+ * try to get them inline instead of by pointer. You can fool the new API
+ * to do the right thing using fake ioctl definitions (but remember that
+ * you will be more likely to hit the limit of 16 ioctl definitions).
+ * To play safe, use the old-style ioctl handler before v15.
+ *
+ * NEW DATA TYPES (ADDR/FLOAT) :
+ * ---------------------------
+ * Wireless Tools 25 introduce two new data types, addr and float,
+ * corresponding to struct sockaddr and struct iwfreq.
+ * Those types are properly handled with Wireless Extensions 15.
+ * However, the new API before v15 won't handle them properly.
+ *
+ * The first problem is that the new API won't know their size, so
+ * it won't copy them. This can be workaround with a fake ioctl definition.
+ * The second problem is that a fixed single addr won't be inlined
+ * in struct iwreq and will be passed as a pointer. This is due to an
+ * off-by-one error, where all fixed data of 16 bytes is considered too
+ * big to fit in struct iwreq.
+ *
+ * For those reasons, I would recommend to use the ioctl handler
+ * before v15 when manipulating those data.
+ *
+ * TOKEN INDEX :
+ * -----------
+ * Token index is very similar to sub-ioctl. It allows the user
+ * to specify an integer index in front of a bunch of other arguments
+ * (addresses, strings, ...). It's specified in square brackets on the
+ * iwpriv command line before other arguments.
+ * > iwpriv eth0 [index] args...
+ * Token index works only when the data is passed as pointer, and
+ * is otherwise ignored. If your data would fit within struct iwreq, you
+ * should declare the command *without* IW_PRIV_SIZE_FIXED to force
+ * this to happen (and check arg number yourself).
+ * --------------------------------------------
+ // --- Commands that would fit in struct iwreq ---
+ { 0x8BE0, IW_PRIV_TYPE_ADDR | 1, 0, "set_param_with_token" },
+ // --- No problem here (bigger than struct iwreq) ---
+ { 0x8BE1, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 2, 0, "again" },
+ * --------------------------------------------
+ * The token index feature is pretty transparent, the token index
+ * will just be in the flags member of (struct iw_point). Default value
+ * (if the user doesn't specify it) will be 0. Token index itself will
+ * work with any version of Wireless Extensions.
+ * Token index is not compatible with sub-ioctl (both use the same
+ * field of struct iw_point). However, the token index can be used to offer
+ * raw access to the sub-ioctl handlers (if it uses struct iw_point) :
+ * --------------------------------------------
+ // --- sub-ioctls handler ---
+ { 0x8BE0, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "" },
+ // --- sub-ioctls definitions ---
+ { 0, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "setaddr" },
+ { 1, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "deladdr" },
+ // --- raw access with token index (+ iwreq workaround) ---
+ { 0x8BE0, IW_PRIV_TYPE_ADDR | 1, 0, "rawaddr" },
+ * --------------------------------------------
+ *
+ * Jean II