o wl3501: introduce iw_mgmt_info_element & associate functions and enums

Also aimed at inclusion on the core wireless extensions, with this we are
closer to 802.11 specs with regards to frame management elements stuff.
Next patches will deal with other elements that are done in a raw way such
as the phys parameter set (DS in this driver).
parent d9468289
......@@ -203,7 +203,28 @@ enum wl3501_status {
#define IW_REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan */
#define IW_REG_DOMAIN_ISRAEL 0x50 /* Channel 3 - 9 Israel */
#define WL3501_ESSID_MAX_LEN (IW_ESSID_MAX_SIZE + 2)
enum iw_mgmt_info_element_ids {
IW_MGMT_INFO_ELEMENT_SSID, /* Service Set Identity */
IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
IW_MGMT_INFO_ELEMENT_FH_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_TIM, /* Traffic Information Map */
IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
/* 7-15: Reserved, unused */
IW_MGMT_INFO_ELEMENT_CHALLENGE_TEXT = 16,
/* 17-31 Reserved for challenge text extension */
/* 32-255 Reserved, unused */
};
/* FIXME: check if it need to be bigger */
#define IW_MGMT_INFO_ELEMENT_MAX_DATA IW_ESSID_MAX_SIZE
struct iw_mgmt_info_element {
enum iw_mgmt_info_element_ids id;
u8 len;
u8 data[IW_MGMT_INFO_ELEMENT_MAX_DATA];
} __attribute__ ((packed));
struct wl3501_tx_hdr {
u16 tx_cnt;
......@@ -244,19 +265,19 @@ struct wl3501_rx_hdr {
};
struct wl3501_start_req {
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 beacon_period;
u16 dtim_period;
u16 probe_delay;
u16 cap_info;
char ssid[WL3501_ESSID_MAX_LEN];
u8 bss_basic_rate_set[10];
u8 operational_rate_set[10];
u8 cf_pset[8];
u8 phy_pset[3];
u8 ibss_pset[4];
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 beacon_period;
u16 dtim_period;
u16 probe_delay;
u16 cap_info;
struct iw_mgmt_info_element ssid;
u8 bss_basic_rate_set[10];
u8 operational_rate_set[10];
u8 cf_pset[8];
u8 phy_pset[3];
u8 ibss_pset[4];
};
struct wl3501_assoc_req {
......@@ -317,25 +338,25 @@ struct wl3501_get_confirm {
};
struct wl3501_join_req {
u16 next_blk;
u8 sig_id;
u8 reserved;
u8 operational_rate_set[10];
u16 reserved2;
u16 timeout;
u16 probe_delay;
u8 timestamp[8];
u8 local_time[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
u16 next_blk;
u8 sig_id;
u8 reserved;
u8 operational_rate_set[10];
u16 reserved2;
u16 timeout;
u16 probe_delay;
u8 timestamp[8];
u8 local_time[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
struct iw_mgmt_info_element ssid;
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
};
struct wl3501_join_confirm {
......@@ -361,36 +382,36 @@ struct wl3501_pwr_mgmt_confirm {
};
struct wl3501_scan_req {
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 probe_delay;
u16 min_chan_time;
u16 max_chan_time;
u8 chan_list[14];
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
enum wl3501_scan_type scan_type;
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 probe_delay;
u16 min_chan_time;
u16 max_chan_time;
u8 chan_list[14];
u8 bssid[ETH_ALEN];
struct iw_mgmt_info_element ssid;
enum wl3501_scan_type scan_type;
};
struct wl3501_scan_confirm {
u16 next_blk;
u8 sig_id;
u8 reserved;
u16 status;
char timestamp[8];
char localtime[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
u8 rssi;
u16 next_blk;
u8 sig_id;
u8 reserved;
u16 status;
char timestamp[8];
char localtime[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
struct iw_mgmt_info_element ssid;
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
u8 rssi;
};
struct wl3501_start_confirm {
......@@ -527,10 +548,10 @@ struct wl3501_card {
u16 esbq_confirm_start;
u16 esbq_confirm_end;
u16 esbq_confirm;
u8 essid[WL3501_ESSID_MAX_LEN];
struct iw_mgmt_info_element essid;
struct iw_mgmt_info_element keep_essid;
u8 bssid[ETH_ALEN];
int net_type;
u8 keep_essid[WL3501_ESSID_MAX_LEN];
char nick[32];
char card_name[32];
char firmware_date[32];
......
......@@ -220,6 +220,23 @@ static int iw_default_channel(int reg_domain)
return rc;
}
static void iw_set_mgmt_info_element(enum iw_mgmt_info_element_ids id,
struct iw_mgmt_info_element *element,
void *value, int len)
{
int real_len = min_t(int, len, sizeof(element->data));
element->id = id;
element->len = real_len;
memcpy(element->data, value, real_len);
}
static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
struct iw_mgmt_info_element *from)
{
iw_set_mgmt_info_element(from->id, to, from->data, from->len);
}
/*
* A linked list of "instances" of the wl24 device. Each actual PCMCIA card
* corresponds to one device instance, and is described by one dev_link_t
......@@ -654,8 +671,8 @@ static int wl3501_mgmt_start(struct wl3501_card *this)
.cap_info = wl3501_fw_cap_info(this),
};
memcpy(sig.ssid, this->essid, WL3501_ESSID_MAX_LEN);
memcpy(this->keep_essid, this->essid, WL3501_ESSID_MAX_LEN);
iw_copy_mgmt_info_element(&sig.ssid, &this->essid);
iw_copy_mgmt_info_element(&this->keep_essid, &this->essid);
return wl3501_esbq_exec(this, &sig, sizeof(sig));
}
......@@ -674,15 +691,15 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
(this->net_type == IW_MODE_ADHOC &&
(sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
this->net_type == IW_MODE_AUTO) {
if (!this->essid[1])
if (!this->essid.len)
matchflag = 1;
else if (this->essid[1] == 3 &&
!strncmp((char *)&this->essid[2], "ANY", 3))
else if (this->essid.len == 3 &&
!strncmp(this->essid.data, "ANY", 3))
matchflag = 1;
else if (this->essid[1] != sig.ssid[1])
else if (this->essid.len != sig.ssid.len)
matchflag = 0;
else if (memcmp(&this->essid[2], &sig.ssid[2],
this->essid[1]))
else if (memcmp(this->essid.data, sig.ssid.data,
this->essid.len))
matchflag = 0;
else
matchflag = 1;
......@@ -895,16 +912,17 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
memcpy(this->bssid,
this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2];
memcpy(this->keep_essid, this->bss_set[i].ssid,
WL3501_ESSID_MAX_LEN);
iw_copy_mgmt_info_element(&this->keep_essid,
&this->bss_set[i].ssid);
wl3501_mgmt_auth(this);
}
} else {
const int i = this->join_sta_bss;
memcpy(this->bssid, this->bss_set[i].bssid, ETH_ALEN);
memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2];
memcpy(this->keep_essid,
this->bss_set[i].ssid, WL3501_ESSID_MAX_LEN);
iw_copy_mgmt_info_element(&this->keep_essid,
&this->bss_set[i].ssid);
wl3501_online(dev);
}
} else {
......@@ -1696,8 +1714,9 @@ static int wl3501_set_essid(struct net_device *dev,
int rc = 0;
if (wrqu->data.flags) {
strlcpy(this->essid + 2, extra, min_t(u16, wrqu->data.length,
IW_ESSID_MAX_SIZE));
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
&this->essid,
extra, wrqu->data.length);
rc = wl3501_reset(dev);
}
return rc;
......@@ -1712,8 +1731,8 @@ static int wl3501_get_essid(struct net_device *dev,
spin_lock_irqsave(&this->lock, flags);
wrqu->essid.flags = 1;
wrqu->essid.length = IW_ESSID_MAX_SIZE;
strlcpy(extra, this->essid + 2, IW_ESSID_MAX_SIZE);
wrqu->essid.length = this->essid.len;
strlcpy(extra, this->essid.data, this->essid.len);
spin_unlock_irqrestore(&this->lock, flags);
return 0;
}
......@@ -2118,11 +2137,8 @@ static void wl3501_config(dev_link_t *link)
this->bss_cnt = 0;
this->join_sta_bss = 0;
this->adhoc_times = 0;
this->essid[0] = 0;
this->essid[1] = 3;
this->essid[2] = 'A';
this->essid[3] = 'N';
this->essid[4] = 'Y';
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID, &this->essid,
"ANY", 3);
this->card_name[0] = '\0';
this->firmware_date[0] = '\0';
this->rssi = 255;
......
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