Commit af39cd4d authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/spare/repo/netdev-2.6/prism54

into redhat.com:/spare/repo/net-drivers-2.6
parents 2424dc63 b15b9151
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.c,v 1.22 2004/02/28 03:06:07 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_38xx.h,v 1.22 2004/02/28 03:06:07 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
*
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.c,v 1.140 2004/02/28 03:06:07 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
* (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
* (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
*
......@@ -87,9 +87,9 @@ prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
/* For now, just catch early the Repeater and Secondary modes here */
if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) {
printk(KERN_DEBUG "%s(): Sorry, Repeater mode and Secondary mode "
"are not yet supported by this driver.\n",
__FUNCTION__);
printk(KERN_DEBUG
"%s(): Sorry, Repeater mode and Secondary mode "
"are not yet supported by this driver.\n", __FUNCTION__);
return -EINVAL;
}
......@@ -143,8 +143,8 @@ prism54_mib_init(islpci_private *priv)
{
u32 t;
struct obj_buffer psm_buffer = {
.size = cpu_to_le32(PSM_BUFFER_SIZE),
.addr = cpu_to_le32(priv->device_psm_buffer)
.size = PSM_BUFFER_SIZE,
.addr = priv->device_psm_buffer
};
mgt_set(priv, DOT11_OID_CHANNEL, &init_channel);
......@@ -285,7 +285,7 @@ prism54_commit(struct net_device *ndev, struct iw_request_info *info,
/* Commit in Monitor mode is not necessary, also setting essid
* in Monitor mode does not make sense and isn't allowed for this
* device's firmware */
if(priv->iw_mode != IW_MODE_MONITOR)
if (priv->iw_mode != IW_MODE_MONITOR)
return mgt_set_request(priv, DOT11_OID_SSID, 0, NULL);
return 0;
}
......@@ -327,34 +327,15 @@ prism54_set_freq(struct net_device *ndev, struct iw_request_info *info,
{
islpci_private *priv = netdev_priv(ndev);
int rvalue;
u32 c = 0;
u32 c;
/* prepare the structure for the set object */
if (fwrq->m < 1000)
/* structure value contains a channel indication */
/* we have a channel number */
c = fwrq->m;
else {
/* structure contains a frequency indication and fwrq->e = 1 */
int f = fwrq->m / 100000;
if (fwrq->e != 1)
return -EINVAL;
if ((f >= 2412) && (f <= 2484)) {
while ((c < 14) && (f != frequency_list_bg[c]))
c++;
if (c >= 14)
return -EINVAL;
} else if ((f >= (int) 5170) && (f <= (int) 5320)) {
while ((c < 12) && (f != frequency_list_a[c]))
c++;
if (c >= 12)
return -EINVAL;
} else
return -EINVAL;
c++;
}
else
c = (fwrq->e == 1) ? channel_of_freq(fwrq->m / 100000) : 0;
rvalue = mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c);
rvalue = c ? mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c) : -EINVAL;
/* Call commit handler */
return (rvalue ? rvalue : -EINPROGRESS);
......@@ -410,7 +391,7 @@ prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
mgt_commit(priv);
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR)
? ARPHRD_IEEE80211 : ARPHRD_ETHER;
? priv->monitor_type : ARPHRD_ETHER;
up_write(&priv->mib_sem);
return 0;
......@@ -531,20 +512,20 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
mgt_get_request(priv, DOT11_OID_SUPPORTEDFREQUENCIES, 0, NULL, &r);
freq = r.ptr;
range->num_channels = le16_to_cpu(freq->nr);
range->num_frequency = le16_to_cpu(freq->nr);
range->num_channels = freq->nr;
range->num_frequency = freq->nr;
/* Frequencies are not listed in the right order. The reordering is probably
* firmware dependant and thus should work for everyone.
*/
m = min(IW_MAX_FREQUENCIES, (int) le16_to_cpu(freq->nr));
m = min(IW_MAX_FREQUENCIES, (int) freq->nr);
for (i = 0; i < m - 12; i++) {
range->freq[i].m = le16_to_cpu(freq->mhz[12 + i]);
range->freq[i].m = freq->mhz[12 + i];
range->freq[i].e = 6;
range->freq[i].i = i + 1;
}
for (i = m - 12; i < m; i++) {
range->freq[i].m = le16_to_cpu(freq->mhz[i - m + 12]);
range->freq[i].m = freq->mhz[i - m + 12];
range->freq[i].e = 6;
range->freq[i].i = i + 23;
}
......@@ -655,7 +636,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
#define CAP_CRYPT 0x10
/* Mode */
cap = le16_to_cpu(bss->capinfo);
cap = bss->capinfo;
iwe.u.mode = 0;
if (cap & CAP_ESS)
iwe.u.mode = IW_MODE_MASTER;
......@@ -747,7 +728,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
bsslist = r.ptr;
/* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) le32_to_cpu(bsslist->nr)); i++)
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
current_ev = prism54_translate_bss(ndev, current_ev,
extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]),
......@@ -869,25 +850,26 @@ prism54_set_rate(struct net_device *ndev,
return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
}
if((ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r)))
if ((ret =
mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r)))
return ret;
rate = (u32) (vwrq->value / 500000);
data = r.ptr;
i = 0;
while(data[i]) {
if(rate && (data[i] == rate)) {
while (data[i]) {
if (rate && (data[i] == rate)) {
break;
}
if(vwrq->value == i) {
if (vwrq->value == i) {
break;
}
data[i] |= 0x80;
i++;
}
if(!data[i]) {
if (!data[i]) {
return -EINVAL;
}
......@@ -931,12 +913,12 @@ prism54_get_rate(struct net_device *ndev,
union oid_res_t r;
/* Get the current bit rate */
if((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r)))
if ((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r)))
return rvalue;
vwrq->value = r.u * 500000;
/* request the device for the enabled rates */
if((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r)))
if ((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r)))
return rvalue;
data = r.ptr;
vwrq->fixed = (data[0] != 0) && (data[1] == 0);
......@@ -1225,7 +1207,7 @@ prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,
rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r);
/* intersil firmware operates in 0.25 dBm (1/4 dBm) */
vwrq->value = (s32)r.u / 4;
vwrq->value = (s32) r.u / 4;
vwrq->fixed = 1;
/* radio is not turned of
* btw: how is possible to turn off only the radio
......@@ -1271,28 +1253,41 @@ prism54_reset(struct net_device *ndev, struct iw_request_info *info,
}
static int
prism54_set_beacon(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
int rvalue = mgt_set_request((islpci_private *) netdev_priv(ndev),
DOT11_OID_BEACONPERIOD, 0, uwrq);
union oid_res_t r;
int rvalue;
enum oid_num_t n = dwrq->flags;
return (rvalue ? rvalue : -EINPROGRESS);
rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r);
dwrq->length = mgt_response_to_str(n, &r, extra);
if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32)
kfree(r.ptr);
return rvalue;
}
static int
prism54_get_beacon(struct net_device *ndev, struct iw_request_info *info,
prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
union oid_res_t r;
int rvalue;
/*
u32 *i = (int *) extra;
int param = *i;
int u = *(i + 1);
*/
u32 oid = uwrq[0], u = uwrq[1];
rvalue =
mgt_get_request((islpci_private *) netdev_priv(ndev),
DOT11_OID_BEACONPERIOD, 0, NULL, &r);
*uwrq = r.u;
return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
}
return rvalue;
static int
prism54_set_raw(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
u32 oid = dwrq->flags;
return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra);
}
void
......@@ -1511,8 +1506,9 @@ prism54_kick_all(struct net_device *ndev, struct iw_request_info *info,
return -ENOMEM;
/* Tell the card to kick every client */
mlme->id = cpu_to_le16(0);
rvalue = mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
mlme->id = 0;
rvalue =
mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
kfree(mlme);
return rvalue;
......@@ -1535,8 +1531,9 @@ prism54_kick_mac(struct net_device *ndev, struct iw_request_info *info,
/* Tell the card to only kick the corresponding bastard */
memcpy(mlme->address, addr->sa_data, ETH_ALEN);
mlme->id = cpu_to_le16(-1);
rvalue = mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
mlme->id = -1;
rvalue =
mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
kfree(mlme);
......@@ -1551,12 +1548,12 @@ format_event(islpci_private *priv, char *dest, const char *str,
{
const u8 *a = mlme->address;
int n = snprintf(dest, IW_CUSTOM_MAX,
"%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s",
"%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",
str,
((priv->iw_mode == IW_MODE_MASTER) ? "to" : "from"),
((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
a[0], a[1], a[2], a[3], a[4], a[5],
(error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
: ""));
: ""), mlme->code);
BUG_ON(n > IW_CUSTOM_MAX);
*length = n;
}
......@@ -1598,14 +1595,15 @@ link_changed(struct net_device *ndev, u32 bitrate)
{
islpci_private *priv = netdev_priv(ndev);
if (le32_to_cpu(bitrate)) {
if (bitrate) {
if (priv->iw_mode == IW_MODE_INFRA) {
union iwreq_data uwrq;
prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq,
NULL);
wireless_send_event(ndev, SIOCGIWAP, &uwrq, NULL);
} else
send_simple_event(netdev_priv(ndev), "Link established");
send_simple_event(netdev_priv(ndev),
"Link established");
} else
send_simple_event(netdev_priv(ndev), "Link lost");
}
......@@ -1765,15 +1763,14 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
static void
handle_request(islpci_private *priv, struct obj_mlme *mlme, enum oid_num_t oid)
{
if (((le16_to_cpu(mlme->state) == DOT11_STATE_AUTHING) ||
(le16_to_cpu(mlme->state) == DOT11_STATE_ASSOCING))
if (((mlme->state == DOT11_STATE_AUTHING) ||
(mlme->state == DOT11_STATE_ASSOCING))
&& mgt_mlme_answer(priv)) {
/* Someone is requesting auth and we must respond. Just send back
* the trap with error code set accordingly.
*/
mlme->code = cpu_to_le16(prism54_mac_accept(&priv->acl,
mlme->
address) ? 0 : 1);
mlme->code = prism54_mac_accept(&priv->acl,
mlme->address) ? 0 : 1;
mgt_set_request(priv, oid, 0, mlme);
}
}
......@@ -1797,6 +1794,13 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
* suited. We use the more flexible custom event facility.
*/
/* I fear prism54_process_bss_data won't work with big endian data */
if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
prism54_process_bss_data(priv, oid, mlme->address,
payload, len);
mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
switch (oid) {
case GEN_OID_LINKSTATE:
......@@ -1831,8 +1835,6 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
break;
case DOT11_OID_BEACON:
prism54_process_bss_data(priv, oid, mlme->address,
payload, len);
send_formatted_event(priv,
"Received a beacon from an unkown AP",
mlme, 0);
......@@ -1840,8 +1842,6 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
case DOT11_OID_PROBE:
/* we received a probe from a client. */
prism54_process_bss_data(priv, oid, mlme->address,
payload, len);
send_formatted_event(priv, "Received a probe from client", mlme,
0);
break;
......@@ -1914,13 +1914,6 @@ prism54_set_mac_address(struct net_device *ndev, void *addr)
return ret;
}
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
/* should we really support this old stuff ? */
return -EOPNOTSUPP;
}
int
prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
......@@ -1950,9 +1943,31 @@ prism54_get_wpa(struct net_device *ndev, struct iw_request_info *info,
return 0;
}
int
prism54_set_prismhdr(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
priv->monitor_type =
(*uwrq ? ARPHRD_IEEE80211_PRISM : ARPHRD_IEEE80211);
if (priv->iw_mode == IW_MODE_MONITOR)
priv->ndev->type = priv->monitor_type;
return 0;
}
int
prism54_get_prismhdr(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
*uwrq = (priv->monitor_type == ARPHRD_IEEE80211_PRISM);
return 0;
}
int
prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
__u32 *uwrq, char *extra)
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
u32 max_burst;
......@@ -1965,7 +1980,7 @@ prism54_set_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
int
prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
__u32 *uwrq, char *extra)
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
union oid_res_t r;
......@@ -1979,7 +1994,7 @@ prism54_get_maxframeburst(struct net_device *ndev, struct iw_request_info *info,
int
prism54_set_profile(struct net_device *ndev, struct iw_request_info *info,
__u32 *uwrq, char *extra)
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
u32 profile;
......@@ -1992,7 +2007,7 @@ prism54_set_profile(struct net_device *ndev, struct iw_request_info *info,
int
prism54_get_profile(struct net_device *ndev, struct iw_request_info *info,
__u32 *uwrq, char *extra)
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
union oid_res_t r;
......@@ -2005,8 +2020,8 @@ prism54_get_profile(struct net_device *ndev, struct iw_request_info *info,
}
int
prism54_oid(struct net_device *ndev, struct iw_request_info *info,
__u32 *uwrq, char *extra)
prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info,
__u32 * uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
......@@ -2017,7 +2032,7 @@ prism54_oid(struct net_device *ndev, struct iw_request_info *info,
}
int
prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
......@@ -2028,11 +2043,15 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
data->length = 0;
if (islpci_get_state(priv) >= PRV_STATE_INIT) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET, priv->priv_oid, extra, 256, &response);
ret =
islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
priv->priv_oid, extra, 256,
&response);
response_op = response->header->operation;
printk("%s: ret: %i\n", ndev->name, ret);
printk("%s: response_op: %i\n", ndev->name, response_op);
if (ret || !response || response->header->operation == PIMFOR_OP_ERROR) {
if (ret || !response
|| response->header->operation == PIMFOR_OP_ERROR) {
if (response) {
islpci_mgt_release(response);
}
......@@ -2051,21 +2070,26 @@ prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
}
int
prism54_set_oid(struct net_device *ndev, struct iw_request_info *info,
prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *data, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
struct islpci_mgmtframe *response = NULL;
int ret = 0, response_op = PIMFOR_OP_ERROR;
printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid, data->length);
printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid,
data->length);
if (islpci_get_state(priv) >= PRV_STATE_INIT) {
ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, priv->priv_oid, extra, data->length, &response);
ret =
islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
priv->priv_oid, extra, data->length,
&response);
printk("%s: ret: %i\n", ndev->name, ret);
if (!ret) {
response_op = response->header->operation;
printk("%s: response_op: %i\n", ndev->name, response_op);
printk("%s: response_op: %i\n", ndev->name,
response_op);
islpci_mgt_release(response);
}
if (ret || response_op == PIMFOR_OP_ERROR) {
......@@ -2077,6 +2101,31 @@ prism54_set_oid(struct net_device *ndev, struct iw_request_info *info,
return ret;
}
static int
prism54_set_spy(struct net_device *ndev,
struct iw_request_info *info,
union iwreq_data *uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
u32 u, oid = OID_INL_CONFIG;
down_write(&priv->mib_sem);
mgt_get(priv, OID_INL_CONFIG, &u);
if ((uwrq->data.length == 0) && (priv->spy_data.spy_number > 0))
/* disable spy */
u &= ~INL_CONFIG_RXANNEX;
else if ((uwrq->data.length > 0) && (priv->spy_data.spy_number == 0))
/* enable spy */
u |= INL_CONFIG_RXANNEX;
mgt_set(priv, OID_INL_CONFIG, &u);
mgt_commit_list(priv, &oid, 1);
up_write(&priv->mib_sem);
return iw_handler_set_spy(ndev, info, uwrq, extra);
}
static const iw_handler prism54_handler[] = {
(iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
(iw_handler) prism54_get_name, /* SIOCGIWNAME */
......@@ -2094,7 +2143,7 @@ static const iw_handler prism54_handler[] = {
(iw_handler) NULL, /* SIOCGIWPRIV */
(iw_handler) NULL, /* SIOCSIWSTATS */
(iw_handler) NULL, /* SIOCGIWSTATS */
iw_handler_set_spy, /* SIOCSIWSPY */
prism54_set_spy, /* SIOCSIWSPY */
iw_handler_get_spy, /* SIOCGIWSPY */
iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
......@@ -2129,33 +2178,50 @@ static const iw_handler prism54_handler[] = {
/* 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
#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+1
#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+2
#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+3
#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+4
#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+6
#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+8
#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+8
#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+10
#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+10
#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+12
#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+11
#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+13
#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+14
#define PRISM54_DBG_OID SIOCIWFIRSTPRIV+14
#define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15
#define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16
#define PRISM54_OID SIOCIWFIRSTPRIV+16
#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17
#define PRISM54_SET_OID SIOCIWFIRSTPRIV+18
#define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18
#define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20
#define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22
#define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23
#define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24
#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "set_"x }
#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "get_"x }
#define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x)
#define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
#define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)
/* Note : limited to 128 private ioctls */
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"},
{PRISM54_GET_PRISMHDR, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
"get_prismhdr"},
{PRISM54_SET_PRISMHDR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"set_prismhdr"},
{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,
......@@ -2172,15 +2238,77 @@ static const struct iw_priv_args prism54_private_args[] = {
"get_wpa"},
{PRISM54_SET_WPA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"set_wpa"},
{PRISM54_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "oid"},
{PRISM54_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "get_oid"},
{PRISM54_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "set_oid"},
{PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
"dbg_oid"},
{PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"},
{PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_get_oid"},
/* --- sub-ioctls handlers --- */
{PRISM54_GET_OID,
0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""},
{PRISM54_SET_OID_U32,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""},
{PRISM54_SET_OID_STR,
IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, ""},
{PRISM54_SET_OID_ADDR,
IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, ""},
/* --- sub-ioctls definitions --- */
IWPRIV_ADDR(GEN_OID_MACADDRESS, "addr"),
IWPRIV_GET(GEN_OID_LINKSTATE, "linkstate"),
IWPRIV_U32(DOT11_OID_BSSTYPE, "bsstype"),
IWPRIV_ADDR(DOT11_OID_BSSID, "bssid"),
IWPRIV_U32(DOT11_OID_STATE, "state"),
IWPRIV_U32(DOT11_OID_AID, "aid"),
IWPRIV_SSID(DOT11_OID_SSIDOVERRIDE, "ssidoverride"),
IWPRIV_U32(DOT11_OID_MEDIUMLIMIT, "medlimit"),
IWPRIV_U32(DOT11_OID_BEACONPERIOD, "beacon"),
IWPRIV_U32(DOT11_OID_DTIMPERIOD, "dtimperiod"),
IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"),
IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"),
IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"),
IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"),
IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"),
IWPRIV_U32(DOT11_OID_MAXRXLIFETIME, "maxrxlife"),
IWPRIV_U32(DOT11_OID_ALOFT_FIXEDRATE, "fixedrate"),
IWPRIV_U32(DOT11_OID_MAXFRAMEBURST, "frameburst"),
IWPRIV_U32(DOT11_OID_PSM, "psm"),
IWPRIV_U32(DOT11_OID_BRIDGELOCAL, "bridge"),
IWPRIV_U32(DOT11_OID_CLIENTS, "clients"),
IWPRIV_U32(DOT11_OID_CLIENTSASSOCIATED, "clientassoc"),
IWPRIV_U32(DOT11_OID_DOT1XENABLE, "dot1xenable"),
IWPRIV_U32(DOT11_OID_ANTENNARX, "rxant"),
IWPRIV_U32(DOT11_OID_ANTENNATX, "txant"),
IWPRIV_U32(DOT11_OID_ANTENNADIVERSITY, "antdivers"),
IWPRIV_U32(DOT11_OID_EDTHRESHOLD, "edthresh"),
IWPRIV_U32(DOT11_OID_PREAMBLESETTINGS, "preamble"),
IWPRIV_GET(DOT11_OID_RATES, "rates"),
IWPRIV_U32(DOT11_OID_OUTPUTPOWER, ".11outpower"),
IWPRIV_GET(DOT11_OID_SUPPORTEDRATES, "supprates"),
IWPRIV_GET(DOT11_OID_SUPPORTEDFREQUENCIES, "suppfreq"),
IWPRIV_U32(DOT11_OID_NOISEFLOOR, "noisefloor"),
IWPRIV_GET(DOT11_OID_FREQUENCYACTIVITY, "freqactivity"),
IWPRIV_U32(DOT11_OID_NONERPPROTECTION, "nonerpprotec"),
IWPRIV_U32(DOT11_OID_PROFILES, "profile"),
IWPRIV_GET(DOT11_OID_EXTENDEDRATES, "extrates"),
IWPRIV_U32(DOT11_OID_MLMEAUTOLEVEL, "mlmelevel"),
IWPRIV_GET(DOT11_OID_BSSS, "bsss"),
IWPRIV_GET(DOT11_OID_BSSLIST, "bsslist"),
IWPRIV_U32(OID_INL_MODE, "mode"),
IWPRIV_U32(OID_INL_CONFIG, "config"),
IWPRIV_U32(OID_INL_DOT11D_CONFORMANCE, ".11dconform"),
IWPRIV_GET(OID_INL_PHYCAPABILITIES, "phycapa"),
IWPRIV_U32(OID_INL_OUTPUTPOWER, "outpower"),
};
static const iw_handler prism54_private_handler[] = {
(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,
......@@ -2194,9 +2322,17 @@ static const iw_handler prism54_private_handler[] = {
(iw_handler) prism54_get_wpa,
(iw_handler) prism54_set_wpa,
(iw_handler) NULL,
(iw_handler) prism54_oid,
(iw_handler) prism54_debug_oid,
(iw_handler) prism54_debug_get_oid,
(iw_handler) prism54_debug_set_oid,
(iw_handler) prism54_get_oid,
(iw_handler) prism54_set_oid,
(iw_handler) prism54_set_u32,
(iw_handler) NULL,
(iw_handler) prism54_set_raw,
(iw_handler) NULL,
(iw_handler) prism54_set_raw,
(iw_handler) prism54_get_prismhdr,
(iw_handler) prism54_set_prismhdr,
};
const struct iw_handler_def prism54_handler_def = {
......@@ -2207,5 +2343,13 @@ const struct iw_handler_def prism54_handler_def = {
.standard = (iw_handler *) prism54_handler,
.private = (iw_handler *) prism54_private_handler,
.private_args = (struct iw_priv_args *) prism54_private_args,
.spy_offset = offsetof(islpci_private, spy_data),
};
/* For ioctls that don't work with the new API */
int
prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
return -EOPNOTSUPP;
}
/* $Header: /var/lib/cvs/prism54-ng/ksrc/isl_ioctl.h,v 1.30 2004/01/30 16:24:00 ajfa Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* (C) 2003 Aurelien Alleaume <slts@free.fr>
......
/*
* $Id: isl_oid.h,v 1.3 2004/03/09 09:05:27 mcgrof Exp $
*
*
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -457,16 +458,29 @@ enum oid_num_t {
OID_NUM_LAST
};
/* We could add more flags. eg: in which mode are they allowed, ro, rw, ...*/
#define OID_FLAG_CACHED 0x01
#define OID_FLAG_U32 0x02
#define OID_FLAG_MLMEEX 0x04 /* this type is special because of a variable
size field when sending. Not yet implemented (not used in driver). */
#define OID_FLAG_CACHED 0x80
#define OID_FLAG_TYPE 0x7f
#define OID_TYPE_U32 0x01
#define OID_TYPE_SSID 0x02
#define OID_TYPE_KEY 0x03
#define OID_TYPE_BUFFER 0x04
#define OID_TYPE_BSS 0x05
#define OID_TYPE_BSSLIST 0x06
#define OID_TYPE_FREQUENCIES 0x07
#define OID_TYPE_MLME 0x08
#define OID_TYPE_MLMEEX 0x09
#define OID_TYPE_ADDR 0x0A
#define OID_TYPE_RAW 0x0B
/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
* Not yet implemented (not used in driver anyway).
*/
struct oid_t {
enum oid_num_t oid;
short range; /* to define a range of oid */
short size; /* size of the associated data */
short size; /* max size of the associated data */
char flags;
};
......@@ -478,6 +492,7 @@ union oid_res_t {
#define IWMAX_BITRATES 20
#define IWMAX_BSS 24
#define IWMAX_FREQ 30
#define PRIV_STR_SIZE 1024
#endif /* !defined(_ISL_OID_H) */
/* EOF */
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.c,v 1.68 2004/02/28 03:06:07 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
......@@ -715,9 +715,9 @@ islpci_setup(struct pci_dev *pdev)
priv = netdev_priv(ndev);
priv->ndev = ndev;
priv->pdev = pdev;
priv->monitor_type = ARPHRD_IEEE80211;
priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
ARPHRD_IEEE80211: ARPHRD_ETHER;
priv->monitor_type : ARPHRD_ETHER;
/* save the start and end address of the PCI memory area */
ndev->mem_start = (unsigned long) priv->device_base;
......@@ -743,9 +743,11 @@ islpci_setup(struct pci_dev *pdev)
/* initialize workqueue's */
INIT_WORK(&priv->stats_work,
(void (*)(void *)) prism54_update_stats, priv);
priv->stats_timestamp = 0;
INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
priv->reset_task_pending = 0;
/* allocate various memory areas */
if (islpci_alloc_memory(priv))
goto do_free_netdev;
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_dev.h,v 1.53 2004/02/28 03:06:07 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
* Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -25,6 +26,7 @@
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <linux/list.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
......@@ -110,6 +112,10 @@ typedef struct {
struct iw_statistics local_iwstatistics;
struct iw_statistics iwstatistics;
struct iw_spy_data spy_data; /* iwspy support */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
struct islpci_acl acl;
/* PCI bus allocation & configuration members */
......@@ -187,6 +193,9 @@ typedef struct {
struct list_head bss_wpa_list;
int num_bss_wpa;
struct semaphore wpa_sem;
struct work_struct reset_task;
int reset_task_pending;
} islpci_private;
static inline islpci_state_t
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.c,v 1.27 2004/01/30 16:24:00 ajfa Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
*
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License
......@@ -24,10 +24,12 @@
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include "isl_38xx.h"
#include "islpci_eth.h"
#include "islpci_mgt.h"
#include "oid_mgt.h"
/******************************************************************************
Network Interface functions
......@@ -246,6 +248,69 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
return err;
}
static inline int
islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
{
/* The card reports full 802.11 packets but with a 20 bytes
* header and without the FCS. But there a is a bit that
* indicates if the packet is corrupted :-) */
struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data;
if (hdr->flags & 0x01)
/* This one is bad. Drop it ! */
return -1;
if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) {
struct avs_80211_1_header *avs;
/* extract the relevant data from the header */
u32 clock = hdr->clock;
u8 rate = hdr->rate;
u16 freq = be16_to_cpu(hdr->freq);
u8 rssi = hdr->rssi;
skb_pull(*skb, sizeof (struct rfmon_header));
if (skb_headroom(*skb) < sizeof (struct avs_80211_1_header)) {
struct sk_buff *newskb = skb_copy_expand(*skb,
sizeof (struct
avs_80211_1_header),
0, GFP_ATOMIC);
if (newskb) {
kfree_skb(*skb);
*skb = newskb;
} else
return -1;
/* This behavior is not very subtile... */
}
/* make room for the new header and fill it. */
avs =
(struct avs_80211_1_header *) skb_push(*skb,
sizeof (struct
avs_80211_1_header));
avs->version = htonl(P80211CAPTURE_VERSION);
avs->length = htonl(sizeof (struct avs_80211_1_header));
avs->mactime = __cpu_to_be64(clock);
avs->hosttime = __cpu_to_be64(jiffies);
avs->phytype = htonl(6); /*OFDM: 6 for (g), 8 for (a) */
avs->channel = htonl(channel_of_freq(freq));
avs->datarate = htonl(rate * 5);
avs->antenna = htonl(0); /*unknown */
avs->priority = htonl(0); /*unknown */
avs->ssi_type = htonl(2); /*2: dBm, 3: raw RSSI */
avs->ssi_signal = htonl(rssi);
avs->ssi_noise = htonl(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */
avs->preamble = htonl(0); /*unknown */
avs->encoding = htonl(0); /*unknown */
} else
skb_pull(*skb, sizeof (struct rfmon_header));
(*skb)->protocol = htons(ETH_P_802_2);
(*skb)->mac.raw = (*skb)->data;
(*skb)->pkt_type = PACKET_OTHERHOST;
return 0;
}
int
islpci_eth_receive(islpci_private *priv)
{
......@@ -266,7 +331,8 @@ islpci_eth_receive(islpci_private *priv)
index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
size = le16_to_cpu(control_block->rx_data_low[index].size);
skb = priv->data_low_rx[index];
offset = ((unsigned long) le32_to_cpu(control_block->rx_data_low[index].address) -
offset = ((unsigned long)
le32_to_cpu(control_block->rx_data_low[index].address) -
(unsigned long) skb->data) & 3;
#if VERBOSE > SHOW_ERROR_MESSAGES
......@@ -314,29 +380,32 @@ islpci_eth_receive(islpci_private *priv)
/* do some additional sk_buff and network layer parameters */
skb->dev = ndev;
/* take care of monitor mode */
if (priv->iw_mode == IW_MODE_MONITOR) {
/* The card reports full 802.11 packets but with a 20 bytes
* header and without the FCS. But there a is a bit that
* indicates if the packet is corrupted :-) */
/* int i; */
if (skb->data[8] & 0x01){
/* This one is bad. Drop it !*/
discard = 1;
/* printk("BAD\n");*/
}
/*
for(i=0;i<50;i++)
printk("%2.2X:",skb->data[i]);
printk("\n");
/* take care of monitor mode and spy monitoring. */
if (priv->iw_mode == IW_MODE_MONITOR)
discard = islpci_monitor_rx(priv, &skb);
else {
if (skb->data[2 * ETH_ALEN] == 0) {
/* The packet has a rx_annex. Read it for spy monitoring, Then
* remove it, while keeping the 2 leading MAC addr.
*/
skb_pull(skb, 20);
skb->protocol = htons(ETH_P_802_2);
skb->mac.raw = skb->data;
skb->pkt_type = PACKET_OTHERHOST;
} else
struct iw_quality wstats;
struct rx_annex_header *annex =
(struct rx_annex_header *) skb->data;
wstats.level = annex->rfmon.rssi;
/* The noise value can be a bit outdated if nobody's
* reading wireless stats... */
wstats.noise = priv->local_iwstatistics.qual.noise;
wstats.qual = wstats.level - wstats.noise;
wstats.updated = 0x07;
/* Update spy records */
wireless_spy_update(ndev, annex->addr2, &wstats);
memcpy(skb->data + sizeof (struct rfmon_header),
skb->data, 2 * ETH_ALEN);
skb_pull(skb, sizeof (struct rfmon_header));
}
skb->protocol = eth_type_trans(skb, ndev);
}
skb->ip_summed = CHECKSUM_NONE;
priv->statistics.rx_packets++;
priv->statistics.rx_bytes += size;
......@@ -351,8 +420,7 @@ islpci_eth_receive(islpci_private *priv)
if (discard) {
dev_kfree_skb(skb);
skb = NULL;
}
else
} else
netif_rx(skb);
/* increment the read index for the rx data low queue */
......@@ -403,7 +471,7 @@ islpci_eth_receive(islpci_private *priv)
wmb();
/* increment the driver read pointer */
add_le32p((u32 *) & control_block->
add_le32p((u32 *) &control_block->
driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
}
......@@ -413,6 +481,15 @@ islpci_eth_receive(islpci_private *priv)
return 0;
}
void
islpci_do_reset_and_wake(void *data)
{
islpci_private *priv = (islpci_private *) data;
islpci_reset(priv, 1);
netif_wake_queue(priv->ndev);
priv->reset_task_pending = 0;
}
void
islpci_eth_tx_timeout(struct net_device *ndev)
{
......@@ -422,13 +499,11 @@ islpci_eth_tx_timeout(struct net_device *ndev)
/* increment the transmit error counter */
statistics->tx_errors++;
#if 0
/* don't do this here! we are not allowed to sleep since we are in interrupt context */
if (islpci_reset(priv))
printk(KERN_ERR "%s: error on TX timeout card reset!\n",
ndev->name);
#endif
if (!priv->reset_task_pending) {
priv->reset_task_pending = 1;
netif_stop_queue(ndev);
schedule_work(&priv->reset_task);
}
/* netif_wake_queue(ndev); */
return;
}
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_eth.h,v 1.5 2004/01/12 22:16:32 jmaurer Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
*
......@@ -23,9 +23,51 @@
#include "isl_38xx.h"
#include "islpci_dev.h"
struct rfmon_header {
u16 unk0; /* = 0x0000 */
u16 length; /* = 0x1400 */
u32 clock; /* 1MHz clock */
u8 flags;
u8 unk1;
u8 rate;
u8 unk2;
u16 freq;
u16 unk3;
u8 rssi;
u8 padding[3];
} __attribute__ ((packed));
struct rx_annex_header {
u8 addr1[ETH_ALEN];
u8 addr2[ETH_ALEN];
struct rfmon_header rfmon;
} __attribute__ ((packed));
/* wlan-ng (and hopefully others) AVS header, version one. Fields in
* network byte order. */
#define P80211CAPTURE_VERSION 0x80211001
struct avs_80211_1_header {
uint32_t version;
uint32_t length;
uint64_t mactime;
uint64_t hosttime;
uint32_t phytype;
uint32_t channel;
uint32_t datarate;
uint32_t antenna;
uint32_t priority;
uint32_t ssi_type;
int32_t ssi_signal;
int32_t ssi_noise;
uint32_t preamble;
uint32_t encoding;
};
void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
int islpci_eth_transmit(struct sk_buff *, struct net_device *);
int islpci_eth_receive(islpci_private *);
void islpci_eth_tx_timeout(struct net_device *);
void islpci_do_reset_and_wake(void *data);
#endif /* _ISL_GEN_H */
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_hotplug.c,v 1.56 2004/02/26 23:33:02 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.c,v 1.40 2004/02/01 10:57:23 mcgrof Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
......
/* $Header: /var/lib/cvs/prism54-ng/ksrc/islpci_mgt.h,v 1.22 2004/01/30 16:24:00 ajfa Exp $
/*
*
* Copyright (C) 2002 Intersil Americas Inc.
* Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
......
/*
* Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
* Copyright (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -31,182 +31,210 @@ const int frequency_list_a[] = { 5170, 5180, 5190, 5200, 5210, 5220, 5230,
5240, 5260, 5280, 5300, 5320
};
#define OID_U32(x) {x, 0, sizeof(u32), OID_FLAG_U32}
#define OID_U32_C(x) {x, 0, sizeof(u32), OID_FLAG_U32 | OID_FLAG_CACHED}
#define OID_STRUCT(x,s) {x, 0, sizeof(s), 0}
#define OID_STRUCT_C(x,s) {x, 0, sizeof(s), OID_FLAG_CACHED}
#define OID_STRUCT_MLME(x){x, 0, sizeof(struct obj_mlme), 0}
#define OID_STRUCT_MLMEEX(x){x, 0, sizeof(struct obj_mlmeex), OID_FLAG_MLMEEX}
int
channel_of_freq(int f)
{
int c = 0;
if ((f >= 2412) && (f <= 2484)) {
while ((c < 14) && (f != frequency_list_bg[c]))
c++;
if (c >= 14)
return 0;
} else if ((f >= (int) 5170) && (f <= (int) 5320)) {
while ((c < 12) && (f != frequency_list_a[c]))
c++;
if (c >= 12)
return 0;
} else
return 0;
return ++c;
}
#define OID_UNKNOWN(x) {x, 0, 0, 0}
#define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t}
#define OID_STRUCT_C(name,oid,s,t) OID_STRUCT(name,oid,s,t | OID_FLAG_CACHED)
#define OID_U32(name,oid) OID_STRUCT(name,oid,u32,OID_TYPE_U32)
#define OID_U32_C(name,oid) OID_STRUCT_C(name,oid,u32,OID_TYPE_U32)
#define OID_STRUCT_MLME(name,oid) OID_STRUCT(name,oid,struct obj_mlme,OID_TYPE_MLME)
#define OID_STRUCT_MLMEEX(name,oid) OID_STRUCT(name,oid,struct obj_mlmeex,OID_TYPE_MLMEEX)
#define OID_UNKNOWN(name,oid) OID_STRUCT(name,oid,0,0)
struct oid_t isl_oid[] = {
[GEN_OID_MACADDRESS] = OID_STRUCT(0x00000000, u8[6]),
[GEN_OID_LINKSTATE] = OID_U32(0x00000001),
[GEN_OID_WATCHDOG] = OID_UNKNOWN(0x00000002),
[GEN_OID_MIBOP] = OID_UNKNOWN(0x00000003),
[GEN_OID_OPTIONS] = OID_UNKNOWN(0x00000004),
[GEN_OID_LEDCONFIG] = OID_UNKNOWN(0x00000005),
OID_STRUCT(GEN_OID_MACADDRESS, 0x00000000, u8[6], OID_TYPE_ADDR),
OID_U32(GEN_OID_LINKSTATE, 0x00000001),
OID_UNKNOWN(GEN_OID_WATCHDOG, 0x00000002),
OID_UNKNOWN(GEN_OID_MIBOP, 0x00000003),
OID_UNKNOWN(GEN_OID_OPTIONS, 0x00000004),
OID_UNKNOWN(GEN_OID_LEDCONFIG, 0x00000005),
/* 802.11 */
[DOT11_OID_BSSTYPE] = OID_U32_C(0x10000000),
[DOT11_OID_BSSID] = OID_STRUCT_C(0x10000001, u8[6]),
[DOT11_OID_SSID] = OID_STRUCT_C(0x10000002, struct obj_ssid),
[DOT11_OID_STATE] = OID_U32(0x10000003),
[DOT11_OID_AID] = OID_U32(0x10000004),
[DOT11_OID_COUNTRYSTRING] = OID_STRUCT(0x10000005, u8[4]),
[DOT11_OID_SSIDOVERRIDE] = OID_STRUCT_C(0x10000006, struct obj_ssid),
[DOT11_OID_MEDIUMLIMIT] = OID_U32(0x11000000),
[DOT11_OID_BEACONPERIOD] = OID_U32_C(0x11000001),
[DOT11_OID_DTIMPERIOD] = OID_U32(0x11000002),
[DOT11_OID_ATIMWINDOW] = OID_U32(0x11000003),
[DOT11_OID_LISTENINTERVAL] = OID_U32(0x11000004),
[DOT11_OID_CFPPERIOD] = OID_U32(0x11000005),
[DOT11_OID_CFPDURATION] = OID_U32(0x11000006),
[DOT11_OID_AUTHENABLE] = OID_U32_C(0x12000000),
[DOT11_OID_PRIVACYINVOKED] = OID_U32_C(0x12000001),
[DOT11_OID_EXUNENCRYPTED] = OID_U32_C(0x12000002),
[DOT11_OID_DEFKEYID] = OID_U32_C(0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key), OID_FLAG_CACHED}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
[DOT11_OID_STAKEY] = OID_UNKNOWN(0x12000008),
[DOT11_OID_REKEYTHRESHOLD] = OID_U32(0x12000009),
[DOT11_OID_STASC] = OID_UNKNOWN(0x1200000a),
[DOT11_OID_PRIVTXREJECTED] = OID_U32(0x1a000000),
[DOT11_OID_PRIVRXPLAIN] = OID_U32(0x1a000001),
[DOT11_OID_PRIVRXFAILED] = OID_U32(0x1a000002),
[DOT11_OID_PRIVRXNOKEY] = OID_U32(0x1a000003),
[DOT11_OID_RTSTHRESH] = OID_U32_C(0x13000000),
[DOT11_OID_FRAGTHRESH] = OID_U32_C(0x13000001),
[DOT11_OID_SHORTRETRIES] = OID_U32_C(0x13000002),
[DOT11_OID_LONGRETRIES] = OID_U32_C(0x13000003),
[DOT11_OID_MAXTXLIFETIME] = OID_U32_C(0x13000004),
[DOT11_OID_MAXRXLIFETIME] = OID_U32(0x13000005),
[DOT11_OID_AUTHRESPTIMEOUT] = OID_U32(0x13000006),
[DOT11_OID_ASSOCRESPTIMEOUT] = OID_U32(0x13000007),
[DOT11_OID_ALOFT_TABLE] = OID_UNKNOWN(0x1d000000),
[DOT11_OID_ALOFT_CTRL_TABLE] = OID_UNKNOWN(0x1d000001),
[DOT11_OID_ALOFT_RETREAT] = OID_UNKNOWN(0x1d000002),
[DOT11_OID_ALOFT_PROGRESS] = OID_UNKNOWN(0x1d000003),
[DOT11_OID_ALOFT_FIXEDRATE] = OID_U32(0x1d000004),
[DOT11_OID_ALOFT_RSSIGRAPH] = OID_UNKNOWN(0x1d000005),
[DOT11_OID_ALOFT_CONFIG] = OID_UNKNOWN(0x1d000006),
OID_U32_C(DOT11_OID_BSSTYPE, 0x10000000),
OID_STRUCT_C(DOT11_OID_BSSID, 0x10000001, u8[6], OID_TYPE_SSID),
OID_STRUCT_C(DOT11_OID_SSID, 0x10000002, struct obj_ssid,
OID_TYPE_SSID),
OID_U32(DOT11_OID_STATE, 0x10000003),
OID_U32(DOT11_OID_AID, 0x10000004),
OID_STRUCT(DOT11_OID_COUNTRYSTRING, 0x10000005, u8[4], OID_TYPE_RAW),
OID_STRUCT_C(DOT11_OID_SSIDOVERRIDE, 0x10000006, struct obj_ssid,
OID_TYPE_SSID),
OID_U32(DOT11_OID_MEDIUMLIMIT, 0x11000000),
OID_U32_C(DOT11_OID_BEACONPERIOD, 0x11000001),
OID_U32(DOT11_OID_DTIMPERIOD, 0x11000002),
OID_U32(DOT11_OID_ATIMWINDOW, 0x11000003),
OID_U32(DOT11_OID_LISTENINTERVAL, 0x11000004),
OID_U32(DOT11_OID_CFPPERIOD, 0x11000005),
OID_U32(DOT11_OID_CFPDURATION, 0x11000006),
OID_U32_C(DOT11_OID_AUTHENABLE, 0x12000000),
OID_U32_C(DOT11_OID_PRIVACYINVOKED, 0x12000001),
OID_U32_C(DOT11_OID_EXUNENCRYPTED, 0x12000002),
OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
[DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
OID_U32(DOT11_OID_PRIVRXFAILED, 0x1a000002),
OID_U32(DOT11_OID_PRIVRXNOKEY, 0x1a000003),
OID_U32_C(DOT11_OID_RTSTHRESH, 0x13000000),
OID_U32_C(DOT11_OID_FRAGTHRESH, 0x13000001),
OID_U32_C(DOT11_OID_SHORTRETRIES, 0x13000002),
OID_U32_C(DOT11_OID_LONGRETRIES, 0x13000003),
OID_U32_C(DOT11_OID_MAXTXLIFETIME, 0x13000004),
OID_U32(DOT11_OID_MAXRXLIFETIME, 0x13000005),
OID_U32(DOT11_OID_AUTHRESPTIMEOUT, 0x13000006),
OID_U32(DOT11_OID_ASSOCRESPTIMEOUT, 0x13000007),
OID_UNKNOWN(DOT11_OID_ALOFT_TABLE, 0x1d000000),
OID_UNKNOWN(DOT11_OID_ALOFT_CTRL_TABLE, 0x1d000001),
OID_UNKNOWN(DOT11_OID_ALOFT_RETREAT, 0x1d000002),
OID_UNKNOWN(DOT11_OID_ALOFT_PROGRESS, 0x1d000003),
OID_U32(DOT11_OID_ALOFT_FIXEDRATE, 0x1d000004),
OID_UNKNOWN(DOT11_OID_ALOFT_RSSIGRAPH, 0x1d000005),
OID_UNKNOWN(DOT11_OID_ALOFT_CONFIG, 0x1d000006),
[DOT11_OID_VDCFX] = {0x1b000000, 7, 0, 0},
[DOT11_OID_MAXFRAMEBURST] = OID_U32(0x1b000008), /* in microseconds */
OID_U32(DOT11_OID_MAXFRAMEBURST, 0x1b000008),
[DOT11_OID_PSM] = OID_U32(0x14000000),
[DOT11_OID_CAMTIMEOUT] = OID_U32(0x14000001),
[DOT11_OID_RECEIVEDTIMS] = OID_U32(0x14000002),
[DOT11_OID_ROAMPREFERENCE] = OID_U32(0x14000003),
OID_U32(DOT11_OID_PSM, 0x14000000),
OID_U32(DOT11_OID_CAMTIMEOUT, 0x14000001),
OID_U32(DOT11_OID_RECEIVEDTIMS, 0x14000002),
OID_U32(DOT11_OID_ROAMPREFERENCE, 0x14000003),
[DOT11_OID_BRIDGELOCAL] = OID_U32(0x15000000),
[DOT11_OID_CLIENTS] = OID_U32(0x15000001),
[DOT11_OID_CLIENTSASSOCIATED] = OID_U32(0x15000002),
OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
OID_U32(DOT11_OID_CLIENTS, 0x15000001),
OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
[DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
[DOT11_OID_CLIENTFIND] = OID_STRUCT(0x150007DB, u8[6]),
[DOT11_OID_WDSLINKADD] = OID_STRUCT(0x150007DC, u8[6]),
[DOT11_OID_WDSLINKREMOVE] = OID_STRUCT(0x150007DD, u8[6]),
[DOT11_OID_EAPAUTHSTA] = OID_STRUCT(0x150007DE, u8[6]),
[DOT11_OID_EAPUNAUTHSTA] = OID_STRUCT(0x150007DF, u8[6]),
[DOT11_OID_DOT1XENABLE] = OID_U32_C(0x150007E0),
[DOT11_OID_MICFAILURE] = OID_UNKNOWN(0x150007E1),
[DOT11_OID_REKEYINDICATE] = OID_UNKNOWN(0x150007E2),
[DOT11_OID_MPDUTXSUCCESSFUL] = OID_U32(0x16000000),
[DOT11_OID_MPDUTXONERETRY] = OID_U32(0x16000001),
[DOT11_OID_MPDUTXMULTIPLERETRIES] = OID_U32(0x16000002),
[DOT11_OID_MPDUTXFAILED] = OID_U32(0x16000003),
[DOT11_OID_MPDURXSUCCESSFUL] = OID_U32(0x16000004),
[DOT11_OID_MPDURXDUPS] = OID_U32(0x16000005),
[DOT11_OID_RTSSUCCESSFUL] = OID_U32(0x16000006),
[DOT11_OID_RTSFAILED] = OID_U32(0x16000007),
[DOT11_OID_ACKFAILED] = OID_U32(0x16000008),
[DOT11_OID_FRAMERECEIVES] = OID_U32(0x16000009),
[DOT11_OID_FRAMEERRORS] = OID_U32(0x1600000A),
[DOT11_OID_FRAMEABORTS] = OID_U32(0x1600000B),
[DOT11_OID_FRAMEABORTSPHY] = OID_U32(0x1600000C),
[DOT11_OID_SLOTTIME] = OID_U32(0x17000000),
[DOT11_OID_CWMIN] = OID_U32(0x17000001),
[DOT11_OID_CWMAX] = OID_U32(0x17000002),
[DOT11_OID_ACKWINDOW] = OID_U32(0x17000003),
[DOT11_OID_ANTENNARX] = OID_U32(0x17000004),
[DOT11_OID_ANTENNATX] = OID_U32(0x17000005),
[DOT11_OID_ANTENNADIVERSITY] = OID_U32(0x17000006),
[DOT11_OID_CHANNEL] = OID_U32_C(0x17000007),
[DOT11_OID_EDTHRESHOLD] = OID_U32_C(0x17000008),
[DOT11_OID_PREAMBLESETTINGS] = OID_U32(0x17000009),
[DOT11_OID_RATES] = OID_STRUCT(0x1700000A, u8[IWMAX_BITRATES + 1]),
[DOT11_OID_CCAMODESUPPORTED] = OID_U32(0x1700000B),
[DOT11_OID_CCAMODE] = OID_U32(0x1700000C),
[DOT11_OID_RSSIVECTOR] = OID_U32(0x1700000D),
[DOT11_OID_OUTPUTPOWERTABLE] = OID_U32(0x1700000E),
[DOT11_OID_OUTPUTPOWER] = OID_U32_C(0x1700000F),
[DOT11_OID_SUPPORTEDRATES] =
OID_STRUCT(0x17000010, u8[IWMAX_BITRATES + 1]),
[DOT11_OID_FREQUENCY] = OID_U32_C(0x17000011),
[DOT11_OID_SUPPORTEDFREQUENCIES] = {0x17000012, 0, sizeof (struct
obj_frequencies)
+ sizeof (u16) * IWMAX_FREQ, 0},
[DOT11_OID_NOISEFLOOR] = OID_U32(0x17000013),
[DOT11_OID_FREQUENCYACTIVITY] =
OID_STRUCT(0x17000014, u8[IWMAX_FREQ + 1]),
[DOT11_OID_IQCALIBRATIONTABLE] = OID_UNKNOWN(0x17000015),
[DOT11_OID_NONERPPROTECTION] = OID_U32(0x17000016),
[DOT11_OID_SLOTSETTINGS] = OID_U32(0x17000017),
[DOT11_OID_NONERPTIMEOUT] = OID_U32(0x17000018),
[DOT11_OID_PROFILES] = OID_U32(0x17000019),
[DOT11_OID_EXTENDEDRATES] =
OID_STRUCT(0x17000020, u8[IWMAX_BITRATES + 1]),
[DOT11_OID_DEAUTHENTICATE] = OID_STRUCT_MLME(0x18000000),
[DOT11_OID_AUTHENTICATE] = OID_STRUCT_MLME(0x18000001),
[DOT11_OID_DISASSOCIATE] = OID_STRUCT_MLME(0x18000002),
[DOT11_OID_ASSOCIATE] = OID_STRUCT_MLME(0x18000003),
[DOT11_OID_SCAN] = OID_UNKNOWN(0x18000004),
[DOT11_OID_BEACON] = OID_STRUCT_MLMEEX(0x18000005),
[DOT11_OID_PROBE] = OID_STRUCT_MLMEEX(0x18000006),
[DOT11_OID_DEAUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000007),
[DOT11_OID_AUTHENTICATEEX] = OID_STRUCT_MLMEEX(0x18000008),
[DOT11_OID_DISASSOCIATEEX] = OID_STRUCT_MLMEEX(0x18000009),
[DOT11_OID_ASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000A),
[DOT11_OID_REASSOCIATE] = OID_STRUCT_MLMEEX(0x1800000B),
[DOT11_OID_REASSOCIATEEX] = OID_STRUCT_MLMEEX(0x1800000C),
[DOT11_OID_NONERPSTATUS] = OID_U32(0x1E000000),
[DOT11_OID_STATIMEOUT] = OID_U32(0x19000000),
[DOT11_OID_MLMEAUTOLEVEL] = OID_U32_C(0x19000001),
[DOT11_OID_BSSTIMEOUT] = OID_U32(0x19000002),
[DOT11_OID_ATTACHMENT] = OID_UNKNOWN(0x19000003),
[DOT11_OID_PSMBUFFER] = OID_STRUCT_C(0x19000004, struct obj_buffer),
[DOT11_OID_BSSS] = OID_U32(0x1C000000),
[DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss), 0}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */
[DOT11_OID_BSSFIND] = OID_STRUCT(0x1C000042, struct obj_bss),
OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
OID_STRUCT(DOT11_OID_EAPUNAUTHSTA, 0x150007DF, u8[6], OID_TYPE_ADDR),
OID_U32_C(DOT11_OID_DOT1XENABLE, 0x150007E0),
OID_UNKNOWN(DOT11_OID_MICFAILURE, 0x150007E1),
OID_UNKNOWN(DOT11_OID_REKEYINDICATE, 0x150007E2),
OID_U32(DOT11_OID_MPDUTXSUCCESSFUL, 0x16000000),
OID_U32(DOT11_OID_MPDUTXONERETRY, 0x16000001),
OID_U32(DOT11_OID_MPDUTXMULTIPLERETRIES, 0x16000002),
OID_U32(DOT11_OID_MPDUTXFAILED, 0x16000003),
OID_U32(DOT11_OID_MPDURXSUCCESSFUL, 0x16000004),
OID_U32(DOT11_OID_MPDURXDUPS, 0x16000005),
OID_U32(DOT11_OID_RTSSUCCESSFUL, 0x16000006),
OID_U32(DOT11_OID_RTSFAILED, 0x16000007),
OID_U32(DOT11_OID_ACKFAILED, 0x16000008),
OID_U32(DOT11_OID_FRAMERECEIVES, 0x16000009),
OID_U32(DOT11_OID_FRAMEERRORS, 0x1600000A),
OID_U32(DOT11_OID_FRAMEABORTS, 0x1600000B),
OID_U32(DOT11_OID_FRAMEABORTSPHY, 0x1600000C),
OID_U32(DOT11_OID_SLOTTIME, 0x17000000),
OID_U32(DOT11_OID_CWMIN, 0x17000001),
OID_U32(DOT11_OID_CWMAX, 0x17000002),
OID_U32(DOT11_OID_ACKWINDOW, 0x17000003),
OID_U32(DOT11_OID_ANTENNARX, 0x17000004),
OID_U32(DOT11_OID_ANTENNATX, 0x17000005),
OID_U32(DOT11_OID_ANTENNADIVERSITY, 0x17000006),
OID_U32_C(DOT11_OID_CHANNEL, 0x17000007),
OID_U32_C(DOT11_OID_EDTHRESHOLD, 0x17000008),
OID_U32(DOT11_OID_PREAMBLESETTINGS, 0x17000009),
OID_STRUCT(DOT11_OID_RATES, 0x1700000A, u8[IWMAX_BITRATES + 1],
OID_TYPE_RAW),
OID_U32(DOT11_OID_CCAMODESUPPORTED, 0x1700000B),
OID_U32(DOT11_OID_CCAMODE, 0x1700000C),
OID_UNKNOWN(DOT11_OID_RSSIVECTOR, 0x1700000D),
OID_UNKNOWN(DOT11_OID_OUTPUTPOWERTABLE, 0x1700000E),
OID_U32(DOT11_OID_OUTPUTPOWER, 0x1700000F),
OID_STRUCT(DOT11_OID_SUPPORTEDRATES, 0x17000010,
u8[IWMAX_BITRATES + 1], OID_TYPE_RAW),
OID_U32_C(DOT11_OID_FREQUENCY, 0x17000011),
[DOT11_OID_SUPPORTEDFREQUENCIES] =
{0x17000012, 0, sizeof (struct obj_frequencies)
+ sizeof (u16) * IWMAX_FREQ, OID_TYPE_FREQUENCIES},
OID_U32(DOT11_OID_NOISEFLOOR, 0x17000013),
OID_STRUCT(DOT11_OID_FREQUENCYACTIVITY, 0x17000014, u8[IWMAX_FREQ + 1],
OID_TYPE_RAW),
OID_UNKNOWN(DOT11_OID_IQCALIBRATIONTABLE, 0x17000015),
OID_U32(DOT11_OID_NONERPPROTECTION, 0x17000016),
OID_U32(DOT11_OID_SLOTSETTINGS, 0x17000017),
OID_U32(DOT11_OID_NONERPTIMEOUT, 0x17000018),
OID_U32(DOT11_OID_PROFILES, 0x17000019),
OID_STRUCT(DOT11_OID_EXTENDEDRATES, 0x17000020,
u8[IWMAX_BITRATES + 1], OID_TYPE_RAW),
OID_STRUCT_MLME(DOT11_OID_DEAUTHENTICATE, 0x18000000),
OID_STRUCT_MLME(DOT11_OID_AUTHENTICATE, 0x18000001),
OID_STRUCT_MLME(DOT11_OID_DISASSOCIATE, 0x18000002),
OID_STRUCT_MLME(DOT11_OID_ASSOCIATE, 0x18000003),
OID_UNKNOWN(DOT11_OID_SCAN, 0x18000004),
OID_STRUCT_MLMEEX(DOT11_OID_BEACON, 0x18000005),
OID_STRUCT_MLMEEX(DOT11_OID_PROBE, 0x18000006),
OID_STRUCT_MLMEEX(DOT11_OID_DEAUTHENTICATEEX, 0x18000007),
OID_STRUCT_MLMEEX(DOT11_OID_AUTHENTICATEEX, 0x18000008),
OID_STRUCT_MLMEEX(DOT11_OID_DISASSOCIATEEX, 0x18000009),
OID_STRUCT_MLMEEX(DOT11_OID_ASSOCIATEEX, 0x1800000A),
OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATE, 0x1800000B),
OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATEEX, 0x1800000C),
OID_U32(DOT11_OID_NONERPSTATUS, 0x1E000000),
OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
OID_UNKNOWN(DOT11_OID_ATTACHMENT, 0x19000003),
OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
OID_TYPE_BUFFER),
OID_U32(DOT11_OID_BSSS, 0x1C000000),
[DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss),
OID_TYPE_BSS}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */
OID_STRUCT(DOT11_OID_BSSFIND, 0x1C000042, struct obj_bss, OID_TYPE_BSS),
[DOT11_OID_BSSLIST] = {0x1C000043, 0, sizeof (struct
obj_bsslist) +
sizeof (struct obj_bss[IWMAX_BSS]), 0},
[OID_INL_TUNNEL] = OID_UNKNOWN(0xFF020000),
[OID_INL_MEMADDR] = OID_UNKNOWN(0xFF020001),
[OID_INL_MEMORY] = OID_UNKNOWN(0xFF020002),
[OID_INL_MODE] = OID_U32_C(0xFF020003),
[OID_INL_COMPONENT_NR] = OID_UNKNOWN(0xFF020004),
[OID_INL_VERSION] = OID_UNKNOWN(0xFF020005),
[OID_INL_INTERFACE_ID] = OID_UNKNOWN(0xFF020006),
[OID_INL_COMPONENT_ID] = OID_UNKNOWN(0xFF020007),
[OID_INL_CONFIG] = OID_U32_C(0xFF020008),
[OID_INL_DOT11D_CONFORMANCE] = OID_U32_C(0xFF02000C),
[OID_INL_PHYCAPABILITIES] = OID_U32(0xFF02000D),
[OID_INL_OUTPUTPOWER] = OID_U32_C(0xFF02000F),
sizeof (struct obj_bss[IWMAX_BSS]),
OID_TYPE_BSSLIST},
OID_UNKNOWN(OID_INL_TUNNEL, 0xFF020000),
OID_UNKNOWN(OID_INL_MEMADDR, 0xFF020001),
OID_UNKNOWN(OID_INL_MEMORY, 0xFF020002),
OID_U32_C(OID_INL_MODE, 0xFF020003),
OID_UNKNOWN(OID_INL_COMPONENT_NR, 0xFF020004),
OID_UNKNOWN(OID_INL_VERSION, 0xFF020005),
OID_UNKNOWN(OID_INL_INTERFACE_ID, 0xFF020006),
OID_UNKNOWN(OID_INL_COMPONENT_ID, 0xFF020007),
OID_U32_C(OID_INL_CONFIG, 0xFF020008),
OID_U32_C(OID_INL_DOT11D_CONFORMANCE, 0xFF02000C),
OID_U32(OID_INL_PHYCAPABILITIES, 0xFF02000D),
OID_U32_C(OID_INL_OUTPUTPOWER, 0xFF02000F),
};
......@@ -257,6 +285,134 @@ mgt_clean(islpci_private *priv)
priv->mib = NULL;
}
void
mgt_le_to_cpu(int type, void *data)
{
switch (type) {
case OID_TYPE_U32:
*(u32 *) data = le32_to_cpu(*(u32 *) data);
break;
case OID_TYPE_BUFFER:{
struct obj_buffer *buff = data;
buff->size = le32_to_cpu(buff->size);
buff->addr = le32_to_cpu(buff->addr);
break;
}
case OID_TYPE_BSS:{
struct obj_bss *bss = data;
bss->age = le16_to_cpu(bss->age);
bss->channel = le16_to_cpu(bss->channel);
bss->capinfo = le16_to_cpu(bss->capinfo);
bss->rates = le16_to_cpu(bss->rates);
bss->basic_rates = le16_to_cpu(bss->basic_rates);
break;
}
case OID_TYPE_BSSLIST:{
struct obj_bsslist *list = data;
int i;
list->nr = le32_to_cpu(list->nr);
for (i = 0; i < list->nr; i++)
mgt_le_to_cpu(OID_TYPE_BSS, &list->bsslist[i]);
break;
}
case OID_TYPE_FREQUENCIES:{
struct obj_frequencies *freq = data;
int i;
freq->nr = le16_to_cpu(freq->nr);
for (i = 0; i < freq->nr; i++)
freq->mhz[i] = le16_to_cpu(freq->mhz[i]);
break;
}
case OID_TYPE_MLME:{
struct obj_mlme *mlme = data;
mlme->id = le16_to_cpu(mlme->id);
mlme->state = le16_to_cpu(mlme->state);
mlme->code = le16_to_cpu(mlme->code);
break;
}
case OID_TYPE_MLMEEX:{
struct obj_mlmeex *mlme = data;
mlme->id = le16_to_cpu(mlme->id);
mlme->state = le16_to_cpu(mlme->state);
mlme->code = le16_to_cpu(mlme->code);
mlme->size = le16_to_cpu(mlme->size);
break;
}
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
break;
default:
BUG();
}
}
static void
mgt_cpu_to_le(int type, void *data)
{
switch (type) {
case OID_TYPE_U32:
*(u32 *) data = cpu_to_le32(*(u32 *) data);
break;
case OID_TYPE_BUFFER:{
struct obj_buffer *buff = data;
buff->size = cpu_to_le32(buff->size);
buff->addr = cpu_to_le32(buff->addr);
break;
}
case OID_TYPE_BSS:{
struct obj_bss *bss = data;
bss->age = cpu_to_le16(bss->age);
bss->channel = cpu_to_le16(bss->channel);
bss->capinfo = cpu_to_le16(bss->capinfo);
bss->rates = cpu_to_le16(bss->rates);
bss->basic_rates = cpu_to_le16(bss->basic_rates);
break;
}
case OID_TYPE_BSSLIST:{
struct obj_bsslist *list = data;
int i;
list->nr = cpu_to_le32(list->nr);
for (i = 0; i < list->nr; i++)
mgt_cpu_to_le(OID_TYPE_BSS, &list->bsslist[i]);
break;
}
case OID_TYPE_FREQUENCIES:{
struct obj_frequencies *freq = data;
int i;
freq->nr = cpu_to_le16(freq->nr);
for (i = 0; i < freq->nr; i++)
freq->mhz[i] = cpu_to_le16(freq->mhz[i]);
break;
}
case OID_TYPE_MLME:{
struct obj_mlme *mlme = data;
mlme->id = cpu_to_le16(mlme->id);
mlme->state = cpu_to_le16(mlme->state);
mlme->code = cpu_to_le16(mlme->code);
break;
}
case OID_TYPE_MLMEEX:{
struct obj_mlmeex *mlme = data;
mlme->id = cpu_to_le16(mlme->id);
mlme->state = cpu_to_le16(mlme->state);
mlme->code = cpu_to_le16(mlme->code);
mlme->size = cpu_to_le16(mlme->size);
break;
}
case OID_TYPE_SSID:
case OID_TYPE_KEY:
case OID_TYPE_ADDR:
case OID_TYPE_RAW:
break;
default:
BUG();
}
}
/* Note : data is modified during this function */
int
mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
{
......@@ -265,7 +421,7 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
int response_op = PIMFOR_OP_ERROR;
int dlen;
void *cache, *_data = data;
u32 oid, u;
u32 oid;
BUG_ON(OID_NUM_LAST <= n);
BUG_ON(extra > isl_oid[n].range);
......@@ -279,13 +435,11 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
cache += (cache ? extra * dlen : 0);
oid = isl_oid[n].oid + extra;
if (data == NULL)
if (_data == NULL)
/* we are requested to re-set a cached value */
_data = cache;
if ((isl_oid[n].flags & OID_FLAG_U32) && data) {
u = cpu_to_le32(*(u32 *) data);
_data = &u;
}
else
mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data);
/* If we are going to write to the cache, we don't want anyone to read
* it -> acquire write lock.
* Else we could acquire a read lock to be sure we don't bother the
......@@ -313,6 +467,10 @@ mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
up_write(&priv->mib_sem);
}
/* re-set given data to what it was */
if (data)
mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
return ret;
}
......@@ -326,7 +484,7 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
struct islpci_mgmtframe *response = NULL;
int dlen;
void *cache, *_res=NULL;
void *cache, *_res = NULL;
u32 oid;
BUG_ON(OID_NUM_LAST <= n);
......@@ -362,20 +520,19 @@ mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
_res = cache;
ret = 0;
}
if (isl_oid[n].flags & OID_FLAG_U32) {
if (ret)
res->u = 0;
else
res->u = le32_to_cpu(*(u32 *) _res);
} else {
if ((isl_oid[n].flags & OID_FLAG_TYPE) == OID_TYPE_U32)
res->u = ret ? 0 : le32_to_cpu(*(u32 *) _res);
else {
res->ptr = kmalloc(reslen, GFP_KERNEL);
BUG_ON(res->ptr == NULL);
if (ret)
memset(res->ptr, 0, reslen);
else
else {
memcpy(res->ptr, _res, reslen);
mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE,
res->ptr);
}
}
if (cache)
up_read(&priv->mib_sem);
......@@ -404,7 +561,7 @@ mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
int j = 0;
u32 oid = t->oid;
BUG_ON(data == NULL);
while (j <= t->range){
while (j <= t->range) {
response = NULL;
ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
oid, data, t->size,
......@@ -431,13 +588,21 @@ mgt_set(islpci_private *priv, enum oid_num_t n, void *data)
BUG_ON(priv->mib[n] == NULL);
memcpy(priv->mib[n], data, isl_oid[n].size);
if (isl_oid[n].flags & OID_FLAG_U32)
*(u32 *) priv->mib[n] = cpu_to_le32(*(u32 *) priv->mib[n]);
mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]);
}
/* Commits the cache. If something goes wrong, it restarts the device. Lock
* outside
*/
void
mgt_get(islpci_private *priv, enum oid_num_t n, void *res)
{
BUG_ON(OID_NUM_LAST <= n);
BUG_ON(priv->mib[n] == NULL);
BUG_ON(res == NULL);
memcpy(res, priv->mib[n], isl_oid[n].size);
mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res);
}
/* Commits the cache. Lock outside. */
static enum oid_num_t commit_part1[] = {
OID_INL_CONFIG,
......@@ -530,3 +695,102 @@ mgt_oidtonum(u32 oid)
return 0;
}
int
mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
{
switch (isl_oid[n].flags & OID_FLAG_TYPE) {
case OID_TYPE_U32:
return snprintf(str, PRIV_STR_SIZE, "%u\n", r->u);
break;
case OID_TYPE_BUFFER:{
struct obj_buffer *buff = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
"size=%u\naddr=0x%X\n", buff->size,
buff->addr);
}
break;
case OID_TYPE_BSS:{
struct obj_bss *bss = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
"age=%u\nchannel=%u\n\
capinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n", bss->age, bss->channel, bss->capinfo, bss->rates, bss->basic_rates);
}
break;
case OID_TYPE_BSSLIST:{
struct obj_bsslist *list = r->ptr;
int i, k;
k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
for (i = 0; i < list->nr; i++)
k += snprintf(str + k, PRIV_STR_SIZE - k,
"bss[%u] : \nage=%u\nchannel=%u\ncapinfo=0x%X\nrates=0x%X\nbasic_rates=0x%X\n",
i, list->bsslist[i].age,
list->bsslist[i].channel,
list->bsslist[i].capinfo,
list->bsslist[i].rates,
list->bsslist[i].basic_rates);
return k;
}
break;
case OID_TYPE_FREQUENCIES:{
struct obj_frequencies *freq = r->ptr;
int i, t;
printk("nr : %u\n", freq->nr);
t = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", freq->nr);
for (i = 0; i < freq->nr; i++)
t += snprintf(str + t, PRIV_STR_SIZE - t,
"mhz[%u]=%u\n", i, freq->mhz[i]);
return t;
}
break;
case OID_TYPE_MLME:{
struct obj_mlme *mlme = r->ptr;
return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
code=0x%X\n", mlme->id, mlme->state,
mlme->code);
}
break;
case OID_TYPE_MLMEEX:{
struct obj_mlmeex *mlme = r->ptr;
return snprintf(str, PRIV_STR_SIZE, "id=0x%X\nstate=0x%X\n\
code=0x%X\nsize=0x%X\n", mlme->id, mlme->state,
mlme->code, mlme->size);
}
break;
case OID_TYPE_SSID:{
struct obj_ssid *ssid = r->ptr;
return snprintf(str, PRIV_STR_SIZE,
"length=%u\noctets=%s\n",
ssid->length, ssid->octets);
}
break;
case OID_TYPE_KEY:{
struct obj_key *key = r->ptr;
int t, i;
t = snprintf(str, PRIV_STR_SIZE,
"type=0x%X\nlength=0x%X\nkey=0x",
key->type, key->length);
for (i = 0; i < key->length; i++)
t += snprintf(str + t, PRIV_STR_SIZE - t,
"%02X:", key->key[i]);
t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");
return t;
}
break;
case OID_TYPE_RAW:
case OID_TYPE_ADDR:{
unsigned char *buff = r->ptr;
int t, i;
t = snprintf(str, PRIV_STR_SIZE, "hex data=");
for (i = 0; i < isl_oid[n].size; i++)
t += snprintf(str + t, PRIV_STR_SIZE - t,
"%02X:", buff[i]);
t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");
return t;
}
break;
default:
BUG();
}
return 0;
}
......@@ -28,9 +28,12 @@ int mgt_init(islpci_private *);
void mgt_clean(islpci_private *);
/* I don't know where to put these 3 */
extern const int frequency_list_bg[];
extern const int frequency_list_a[];
int channel_of_freq(int);
void mgt_le_to_cpu(int, void *);
int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
......@@ -41,11 +44,15 @@ int mgt_commit_list(islpci_private *, enum oid_num_t *, int);
void mgt_set(islpci_private *, enum oid_num_t, void *);
void mgt_get(islpci_private *, enum oid_num_t, void *);
void mgt_commit(islpci_private *);
int mgt_mlme_answer(islpci_private *);
enum oid_num_t mgt_oidtonum(u32 oid);
int mgt_response_to_str(enum oid_num_t, union oid_res_t *, char *);
#endif /* !defined(_OID_MGT_H) */
/* EOF */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment