[Prism54-devel] implementation of sub-ioctls
David Pufer
root@seznam.cz
Sun, 30 Nov 2003 10:41:04 +0000 (Local time zone must be set--see zic manual page)
Hello all,
I have just started tweaking the driver. I would like to submit the
following patch that adds sub-ioctls support to private ioctls. As a
sample code I implemented more private ioctls (Preamble settings,
operation mode profile setting, slot setting). I also moved
getBeaconPeriod and setBeaconPeriod to the sub-ioctl handler. In addition
I added these parameters to MIB. I tested the patch against 20031129 CVS
tarball on my SMC 2802W and it seems to work withou problems.
David Pufer
Here it is:
diff -Naur ksrc/isl_ioctl.c /home/prism54-cvs20031129_modified/ksrc/isl_ioctl.c
--- ksrc/isl_ioctl.c 2003-11-29 04:51:48.000000000 +0000
+++ /home/prism54-cvs20031129_modified/ksrc/isl_ioctl.c 2003-11-30 09:08:12.000000000 +0000
@@ -163,6 +163,10 @@
static int init_dot1x = CARD_DEFAULT_DOT1X;
static int init_conformance = CARD_DEFAULT_CONFORMANCE;
static int init_mlme = CARD_DEFAULT_MLME_MODE;
+static int init_beaconperiod = CARD_DEFAULT_BEACONPERIOD;
+static int init_opmodeprofile = CARD_DEFAULT_OPMODEPROFILE;
+static int init_preamble = CARD_DEFAULT_PREAMBLE;
+static int init_slotsetting = CARD_DEFAULT_SLOTSETTING;
MODULE_PARM(init_mode, "i");
@@ -273,6 +277,10 @@
mib->dot1xenable = init_dot1x;
mib->mlmeautolevel = init_mlme;
mib->conformance = init_conformance;
+ mib->beaconperiod = init_beaconperiod;
+ mib->opmodeprofile = init_opmodeprofile;
+ mib->preamble = init_preamble;
+ mib->slotsetting = init_slotsetting;
for (idx = 0; idx < 4; ++idx) {
mib->defkey[idx].type = DOT11_PRIV_WEP;
@@ -361,6 +369,22 @@
MGT_SET_REQUEST_U32(priv, OID_INL_DOT11D_CONFORMANCE,
priv->mib.conformance);
+ /* set the beacon period */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_BEACONPERIOD,
+ priv->mib.beaconperiod);
+
+ /* set the operation mode profile */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_PROFILES,
+ priv->mib.opmodeprofile);
+
+ /* set the preamble */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_PREAMBLESETTINGS,
+ priv->mib.preamble);
+
+ /* set the slot setting */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_SLOTSETTINGS,
+ priv->mib.slotsetting);
+
/* set the mlme mode object */
MGT_SET_REQUEST_U32(priv, DOT11_OID_MLMEAUTOLEVEL,
priv->mib.mlmeautolevel);
@@ -368,6 +392,7 @@
/* set the mode again for actually starting the device */
MGT_SET_REQUEST_U32(priv, OID_INL_MODE, priv->mib.mode);
+
printk(KERN_DEBUG "%s: done with prism54_mib_init()!\n",
priv->ndev->name);
@@ -680,6 +705,24 @@
/* the 2nd set-mode request! */
MGT_SET_REQUEST_U32(priv, OID_INL_MODE, cardmode);
+
+ /* restore beacon period */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_BEACONPERIOD,
+ priv->mib.beaconperiod);
+
+ /* restore operation mode profile */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_PROFILES,
+ priv->mib.opmodeprofile);
+
+ /* restore preamble */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_PREAMBLESETTINGS,
+ priv->mib.preamble);
+
+ /* restore slot setting */
+ MGT_SET_REQUEST_U32(priv, DOT11_OID_SLOTSETTINGS,
+ priv->mib.slotsetting);
+
+
/* update MIB copy now that requests succeeded
* Note : there a small window for race here :
* if the acl code replies to some message while priv->mib.mode=master
@@ -689,6 +732,7 @@
priv->mib.config = cardconfig;
priv->mib.mlmeautolevel = mlmeautolevel;
+
/* We need to reset the ssid for non-master modes, and also
* the 802.11d conformance. Don't do it if we are in master or
* monitor mode.
@@ -699,6 +743,7 @@
MGT_SET_REQUEST(priv, DOT11_OID_SSID, &priv->mib.ssid,
sizeof (struct obj_ssid));
+
MGT_SET_REQUEST_U32(priv, OID_INL_DOT11D_CONFORMANCE,
priv->mib.conformance);
@@ -1610,24 +1655,6 @@
return 0;
}
-int
-prism54_set_beacon(struct net_device *ndev, struct iw_request_info *info,
- __u32 *uwrq, char *extra)
-{
- MGT_SET_REQUEST_U32(ndev->priv, DOT11_OID_BEACONPERIOD, *uwrq);
-
- return 0;
-}
-
-int
-prism54_get_beacon(struct net_device *ndev, struct iw_request_info *info,
- __u32 *uwrq, char *extra)
-{
- MGT_GET_REQUEST_U32(ndev->priv, DOT11_OID_BEACONPERIOD, uwrq);
-
- return 0;
-}
-
void
prism54_acl_init(struct islpci_acl *acl)
{
@@ -1875,6 +1902,123 @@
return 0;
}
+/* handlers for private sub-ioctls */
+int
+prism54_set_param(struct net_device *ndev, struct iw_request_info *info,
+ void *wrq, char *extra)
+{
+ islpci_private *priv = ndev->priv;
+ u32 *i = (u32 *) extra;
+ u32 param = *i;
+ u32 value = *(i+1);
+ int ret = -EOPNOTSUPP;
+
+/* printk(KERN_DEBUG "%s: param is %d, value is %d\n", ndev->name, param, value);
+*/
+ switch(param) {
+ case PRISM54_PARAM_OPMODEPROFILE:
+ printk(KERN_DEBUG "%s: setting up operation mode profile to %d\n", ndev->name, value);
+ if(value >= 0 && value < 8) {
+ MGT_SET_REQUEST_U32(ndev->priv, DOT11_OID_PROFILES, value);
+ /* update mib */
+ priv->mib.opmodeprofile = value;
+ ret = 0;
+ }
+ else {
+ printk(KERN_DEBUG "%s: requested mode profile %d is out of range\n", ndev->name, value);
+ ret = -ERANGE;
+ }
+ break;
+ case PRISM54_PARAM_PREAMBLE:
+ printk(KERN_DEBUG "%s: setting up preamble setting to %d\n", ndev->name, value);
+ if(value >= 0 && value < 3) {
+ MGT_SET_REQUEST_U32(ndev->priv, DOT11_OID_PREAMBLESETTINGS, value);
+ /* update mib */
+ priv->mib.preamble = value;
+ ret = 0;
+ }
+ else {
+ printk(KERN_DEBUG "%s: requested preamble %d is out of range\n", ndev->name, value);
+ ret = -ERANGE;
+ }
+ break;
+ case PRISM54_PARAM_BEACONPERIOD:
+ printk(KERN_DEBUG "%s: setting up beacon period to %d\n", ndev->name, value);
+ if(value > 0 && value < 65536) { /*tested on SMC 2802W */
+ MGT_SET_REQUEST_U32(ndev->priv, DOT11_OID_BEACONPERIOD, value);
+ /* update mib */
+ priv->mib.beaconperiod = value;
+ ret = 0;
+ }
+ else {
+ printk(KERN_DEBUG "%s: requested beacon period %d is out of range\n", ndev->name, value);
+ ret = -ERANGE;
+ }
+ break;
+ case PRISM54_PARAM_SLOTSETTING:
+ printk(KERN_DEBUG "%s: setting up slot setting to %d\n", ndev->name, value);
+ if(value >= 0 && value < 3) {
+ MGT_SET_REQUEST_U32(ndev->priv, DOT11_OID_SLOTSETTINGS, value);
+ /* update mib */
+ priv->mib.slotsetting = value;
+ ret = 0;
+ }
+ else {
+ printk(KERN_DEBUG "%s: requested slot setting %d is out of range\n", ndev->name, value);
+ ret = -ERANGE;
+ }
+ break;
+ default:
+ printk(KERN_DEBUG "%s: prism54_set_param: unknown request %d\n", ndev->name, param);
+ }
+ /* commit settings.
+ necessary e.g. for beacon period setting to take effect. */
+ if(ret == 0)
+ prism54_commit(ndev, info, (char *) wrq, extra);
+
+ return ret;
+}
+
+
+int
+prism54_get_param(struct net_device *ndev, struct iw_request_info *info,
+ void *wrq, char *extra)
+{
+ u32 *param = (u32 *) extra;
+ int ret = 0;
+
+/* printk(KERN_DEBUG "%s: *param is %d\n", ndev->name, *param);
+*/
+ switch(*param) {
+ case PRISM54_PARAM_OPMODEPROFILE:
+ printk(KERN_DEBUG "%s: reading operation mode profile\n", ndev->name);
+ MGT_GET_REQUEST_U32(ndev->priv, DOT11_OID_PROFILES, param);
+ ret = 0;
+ break;
+ case PRISM54_PARAM_PREAMBLE:
+ printk(KERN_DEBUG "%s: reading preamble setting\n", ndev->name);
+ MGT_GET_REQUEST_U32(ndev->priv, DOT11_OID_PREAMBLESETTINGS, param);
+ ret = 0;
+ break;
+ case PRISM54_PARAM_BEACONPERIOD:
+ printk(KERN_DEBUG "%s: reading beacon period setting\n", ndev->name);
+ MGT_GET_REQUEST_U32(ndev->priv, DOT11_OID_BEACONPERIOD, param);
+ ret = 0;
+ break;
+ case PRISM54_PARAM_SLOTSETTING:
+ printk(KERN_DEBUG "%s: reading slot setting\n", ndev->name);
+ MGT_GET_REQUEST_U32(ndev->priv, DOT11_OID_SLOTSETTINGS, param);
+ ret = 0;
+ break;
+ default:
+ printk(KERN_DEBUG "%s: prism54_get_param: unknown request %d\n", ndev->name, *param);
+ ret = -EOPNOTSUPP;
+ }
+ return ret;
+}
+
+
+
/* Translate a TRAP oid into a wireless event. Called in islpci_mgt_receive. */
#define STR_ADD(dest,src,length)do { \
diff -Naur ksrc/isl_ioctl.h /home/prism54-cvs20031129_modified/ksrc/isl_ioctl.h
--- ksrc/isl_ioctl.h 2003-11-28 22:18:48.000000000 +0000
+++ /home/prism54-cvs20031129_modified/ksrc/isl_ioctl.h 2003-11-30 09:08:12.000000000 +0000
@@ -93,10 +93,6 @@
int prism54_reset(struct net_device *, struct iw_request_info *,
__u32 *, char *);
-int prism54_set_beacon(struct net_device *, struct iw_request_info *,
- __u32 *, char *);
-int prism54_get_beacon(struct net_device *, struct iw_request_info *,
- __u32 *, char *);
int prism54_ioctl(struct net_device *, struct ifreq *, int);
@@ -127,6 +123,12 @@
int prism54_kick_mac(struct net_device *, struct iw_request_info *,
struct sockaddr *, char *);
+int prism54_get_param(struct net_device *, struct iw_request_info *,
+ void *, char *);
+
+int prism54_set_param(struct net_device *, struct iw_request_info *,
+ void *, char *);
+
void prism54_send_trap(islpci_private *, u32, char *);
int prism54_process_trap(islpci_private *);
@@ -197,46 +199,92 @@
/* The low order bit identify a SET (0) or a GET (1) ioctl. */
-#define PRISM54_RESET SIOCIWFIRSTPRIV
-#define PRISM54_GET_BEACON SIOCIWFIRSTPRIV+1
-#define PRISM54_SET_BEACON SIOCIWFIRSTPRIV+2
-#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+3
-#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+4
-#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+5
-#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+6
+/* sub-ioctl handlers */
+#define PRISM54_SET_PARAM SIOCIWFIRSTPRIV+0
+#define PRISM54_GET_PARAM SIOCIWFIRSTPRIV+1
+
+/* other handlers */
+#define PRISM54_RESET SIOCIWFIRSTPRIV+2
+
+#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+3
+#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+4
+#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+5
+#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+6
+
+#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+8
-#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+8
+#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+10
-#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+10
+#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+12
-#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+12
+
+/* sub-ioctl functions identifiers */
+/* isn't it better to move simple ioctls to sub-ioctl handler
+ to make fields for other e.g. more complicated handlers? */
+#define PRISM54_PARAM_OPMODEPROFILE 1
+#define PRISM54_PARAM_PREAMBLE 2
+#define PRISM54_PARAM_BEACONPERIOD 3
+#define PRISM54_PARAM_SLOTSETTING 4
static const struct iw_priv_args prism54_private_args[] = {
/*{ cmd, set_args, get_args, name } */
- {PRISM54_RESET, 0, 0, "reset"},
- {PRISM54_GET_BEACON, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "getBeaconPeriod"},
- {PRISM54_SET_BEACON, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "setBeaconPeriod"},
+/* WARNING name must be up to 15 characters long */
+ {PRISM54_RESET, 0, 0,
+ "reset"},
{PRISM54_GET_POLICY, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"getPolicy"},
{PRISM54_SET_POLICY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"setPolicy"},
- { PRISM54_GET_MAC, 0, IW_PRIV_TYPE_ADDR | 64, "getMac" },
+ { PRISM54_GET_MAC, 0, IW_PRIV_TYPE_ADDR | 64,
+ "getMac" },
{ PRISM54_ADD_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
"addMac" },
{ PRISM54_DEL_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
"delMac" },
{ PRISM54_KICK_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
"kickMac" },
- { PRISM54_KICK_ALL, 0, 0, "kickAll" }
+ { PRISM54_KICK_ALL, 0, 0,
+ "kickAll" },
+ /* sub-ioctl parameter wrappers */
+ {PRISM54_GET_PARAM,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "handleGetParam"},
+ {PRISM54_SET_PARAM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,
+ "handleSetParam"},
+ /* sub-ioctl handlers */
+ {PRISM54_GET_PARAM, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ ""},
+ {PRISM54_SET_PARAM, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ ""},
+ /* --- sub-ioctl functions --- */
+ /* operation mode profile defined by DOT11_OID_PROFILE_XXX */
+ {PRISM54_PARAM_OPMODEPROFILE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "getOpModeProf"},
+ {PRISM54_PARAM_OPMODEPROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ "setOpModeProf"},
+ /* preamble settings defined by DOT11_PREAMBLESETTING_XXX */
+ {PRISM54_PARAM_PREAMBLE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "getPreamble"},
+ {PRISM54_PARAM_PREAMBLE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ "setPreamble"},
+ /* beacon period defined by DOT11_OID_BEACONPERIOD */
+ {PRISM54_PARAM_BEACONPERIOD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "getBeaconPeriod"},
+ {PRISM54_PARAM_BEACONPERIOD, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ "setBeaconPeriod"},
+ /* slot settings defined by DOT11_SLOTSETTING_XXX */
+ {PRISM54_PARAM_SLOTSETTING, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "getSlotSetting"},
+ {PRISM54_PARAM_SLOTSETTING, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
+ "setSlotSetting"},
};
static const iw_handler prism54_private_handler[] = {
+ (iw_handler) prism54_set_param,
+ (iw_handler) prism54_get_param,
(iw_handler) prism54_reset,
- (iw_handler) prism54_get_beacon,
- (iw_handler) prism54_set_beacon,
(iw_handler) prism54_get_policy,
(iw_handler) prism54_set_policy,
(iw_handler) prism54_get_mac,
@@ -252,8 +300,7 @@
static const struct iw_handler_def prism54_handler_def = {
.num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
.num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
- .num_private_args =
- sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
+ .num_private_args = sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
diff -Naur ksrc/islpci_dev.h /home/prism54-cvs20031129_modified/ksrc/islpci_dev.h
--- ksrc/islpci_dev.h 2003-11-24 16:48:22.000000000 +0000
+++ /home/prism54-cvs20031129_modified/ksrc/islpci_dev.h 2003-11-30 09:08:12.000000000 +0000
@@ -72,6 +72,11 @@
u32 exunencrypted;
u32 conformance;
u32 dot1xenable;
+ u32 beaconperiod;
+ u32 opmodeprofile;
+ u32 preamble;
+ u32 slotsetting;
+
};
/* some states might not be superflous and may be removed when
diff -Naur ksrc/islpci_mgt.h /home/prism54-cvs20031129_modified/ksrc/islpci_mgt.h
--- ksrc/islpci_mgt.h 2003-11-24 16:48:22.000000000 +0000
+++ /home/prism54-cvs20031129_modified/ksrc/islpci_mgt.h 2003-11-30 09:08:12.000000000 +0000
@@ -48,6 +48,11 @@
#define CARD_DEFAULT_DOT1X 0
#define CARD_DEFAULT_MLME_MODE DOT11_MLME_AUTO
#define CARD_DEFAULT_CONFORMANCE OID_INL_CONFORMANCE_NONE
+#define CARD_DEFAULT_BEACONPERIOD 100
+#define CARD_DEFAULT_PREAMBLE 2 /* dynamic */
+#define CARD_DEFAULT_OPMODEPROFILE 1 /* mixed */
+#define CARD_DEFAULT_SLOTSETTING 2 /* dynamic */
+
/* PIMFOR package definitions */
#define PIMFOR_ETHERTYPE 0x8828