You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(14) |
Aug
(46) |
Sep
(117) |
Oct
(24) |
Nov
(10) |
Dec
(1) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(11) |
Feb
(2) |
Mar
(1) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
(2) |
Sep
(2) |
Oct
(1) |
Nov
|
Dec
|
2007 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
(3) |
Apr
(3) |
May
(1) |
Jun
(5) |
Jul
(7) |
Aug
(1) |
Sep
(8) |
Oct
(2) |
Nov
(27) |
Dec
(33) |
2009 |
Jan
(11) |
Feb
(10) |
Mar
(10) |
Apr
(16) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Michael Wu <fla...@so...> - 2005-09-14 02:22:24
|
On Tuesday 13 September 2005 21:35, James Ketrenos wrote: > Michael Wu wrote: > >(resend, sent to oss.sgi.com by mistake) > > > >On Tuesday 13 September 2005 19:35, James Ketrenos wrote: > >>Added ieee80211_radiotap.h to enhance statistic reporting to user space > >>from wireless drivers. > >> > >>Signed-off-by: James Ketrenos <jke...@li...> > > > >I'm not sure, but didn't Mike Kershaw create this patch? > > Yes. Building ieee80211_radiotap.h was all his work. He also put > together patches to the ipw2200 to use those headers (which are a part > of that series that will be sent out after I send out a driver > compatibility series for the ieee80211 patches) > Oh, that reminds me. A bunch of information that is put into the radiotap header is put inside struct ieee80211_rx_stats when the driver passes the frame to the ieee80211 layer. I think it is a better idea to expand ieee80211_rx_stats to include all information necessary for filling in a radiotap header, and let the ieee80211 tack on the header. I would prefer either that or giving drivers access to the generic monitor mode path so frames can be passed to userspace ASAP. Also, we probably want an ioctl or some way to switch between raw ieee80211 frames and radiotap headers. -Michael Wu |
From: Michael Wu <fla...@so...> - 2005-09-14 01:52:09
|
On Tuesday 13 September 2005 21:31, James Ketrenos wrote: > See patch below (cumulative to prior series): > > include/net/ieee80211.h | 13 +++++++++++-- > 1 files changed, 11 insertions(+), 2 deletions(-) > > diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h > --- a/include/net/ieee80211.h > +++ b/include/net/ieee80211.h > @@ -609,17 +609,22 @@ struct ieee80211_auth { > __le16 algorithm; > __le16 transaction; > __le16 status; > + /* challenge */ > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > struct ieee80211_disassoc { > struct ieee80211_hdr_3addr header; > - __le16 reason_code; > + __le16 reason; > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > Opps, didn't notice this last time. Disassoc/deauth do not have any info elements. My patch did not include the zero length array at the end of this frame. Otherwise, it looks pretty good.. Thanks, -Michael Wu |
From: James K. <jke...@li...> - 2005-09-14 01:36:08
|
Michael Wu wrote: >(resend, sent to oss.sgi.com by mistake) > >On Tuesday 13 September 2005 19:35, James Ketrenos wrote: > > >>Added ieee80211_radiotap.h to enhance statistic reporting to user space >>from wireless drivers. >> >>Signed-off-by: James Ketrenos <jke...@li...> >> >> >I'm not sure, but didn't Mike Kershaw create this patch? > Yes. Building ieee80211_radiotap.h was all his work. He also put together patches to the ipw2200 to use those headers (which are a part of that series that will be sent out after I send out a driver compatibility series for the ieee80211 patches) >I was expecting a >signed-off-by line by him. > > I'm not sure where that signed-off-line went. I'm pretty sure I had typed it in during the original commit; now that I've rebased 3 times, I don't actually have the original commit logs though -- so not sure if I just don't remember, or what. The GIT log in the bughost.org repository does list him as the author. The git-format-patch-script didn't seem to make emails with legible author information though (it stuck the author information in between the first line of the commit message and the rest of the message) James |
From: James K. <jke...@li...> - 2005-09-14 01:32:05
|
Michael Wu wrote: >(resend, don't know why kmail decided to send to oss.sgi.com) > >This patch plus patch 5 looks very similar to my management frame patch >except.. > > Yes, I noticed that when I saw your patch today. I liked that you added more IE comments. >On Tuesday 13 September 2005 18:53, James Ketrenos wrote: > > >>@@ -552,6 +577,17 @@ struct ieee80211_authentication { >> struct ieee80211_info_element info_element[0]; >> } __attribute__ ((packed)); >> >>+struct ieee80211_disassoc { >> >> >Add alias for deauthentication frame here? > > Done. > > >>+ struct ieee80211_hdr_3addr header; >>+ u16 reason_code; >> >> >If we do not append _code to "status", why append _code to "reason"? > > I can't think of any good reasons. _code removed. See patch below (cumulative to prior series): include/net/ieee80211.h | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -609,17 +609,22 @@ struct ieee80211_auth { __le16 algorithm; __le16 transaction; __le16 status; + /* challenge */ struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); struct ieee80211_disassoc { struct ieee80211_hdr_3addr header; - __le16 reason_code; + __le16 reason; struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); +/* Alias deauth for disassoc */ +#define ieee82011_deauth ieee80211_disassoc + struct ieee80211_probe_request { struct ieee80211_hdr_3addr header; + /* SSID, supported rates */ struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); @@ -628,6 +633,8 @@ struct ieee80211_probe_response { u32 time_stamp[2]; __le16 beacon_interval; __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN */ struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); @@ -638,6 +645,7 @@ struct ieee80211_assoc_request { struct ieee80211_hdr_3addr header; __le16 capability; __le16 listen_interval; + /* SSID, supported rates, RSN */ struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); @@ -654,7 +662,8 @@ struct ieee80211_assoc_response { __le16 capability; __le16 status; __le16 aid; - struct ieee80211_info_element info_element[0]; /* supported rates */ + /* supported rates */ + struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); struct ieee80211_txb { |
From: James K. <jke...@li...> - 2005-09-14 01:15:11
|
Michael Wu wrote: >(resend, sent to oss.sgi.com by mistake) > >On Tuesday 13 September 2005 19:36, James Ketrenos wrote: > > >>ieee80211: use endian-aware types >> >>From: Michael Wu <fla...@so...> >> >>This patch: >>- fixes misc. whitespace/comments >>- replaces u16 with __le16/__be16 where appropriate >> >>Signed-off-by: Michael Wu <fla...@so...> >>Signed-off-by: Jiri Benc <jb...@su...> >> >>Signed-off-by: James Ketrenos <jke...@li...> >> >> >> >The original patch already went in, and this patch looks nothing like the one >I sent in. > > This patch series was built on the ieee80211 tree used in the ipw2x00 drivers, which had already incorporated a some endian changes. At the point in that tree that we applied your patch structures had moved, and other structures had come into place that also needed the __le16 transitions. This changes were incoporated at the same time the script laid down this commit message. I apologize for the confusion. James >-Michael Wu >- >To unsubscribe from this list: send the line "unsubscribe netdev" in >the body of a message to maj...@vg... >More majordomo info at http://vger.kernel.org/majordomo-info.html > > |
From: Michael Wu <fla...@so...> - 2005-09-13 23:57:53
|
(resend, sent to oss.sgi.com by mistake) On Tuesday 13 September 2005 19:35, James Ketrenos wrote: > Added ieee80211_radiotap.h to enhance statistic reporting to user space > from wireless drivers. > > Signed-off-by: James Ketrenos <jke...@li...> I'm not sure, but didn't Mike Kershaw create this patch? I was expecting a signed-off-by line by him. -Michael Wu |
From: Michael Wu <fla...@so...> - 2005-09-13 23:57:00
|
(resend, sent to oss.sgi.com by mistake) On Tuesday 13 September 2005 19:36, James Ketrenos wrote: > ieee80211: use endian-aware types > > From: Michael Wu <fla...@so...> > > This patch: > - fixes misc. whitespace/comments > - replaces u16 with __le16/__be16 where appropriate > > Signed-off-by: Michael Wu <fla...@so...> > Signed-off-by: Jiri Benc <jb...@su...> > > Signed-off-by: James Ketrenos <jke...@li...> > The original patch already went in, and this patch looks nothing like the one I sent in. -Michael Wu |
From: Michael Wu <fla...@so...> - 2005-09-13 23:56:20
|
(resend, don't know why kmail decided to send to oss.sgi.com) This patch plus patch 5 looks very similar to my management frame patch except.. On Tuesday 13 September 2005 18:53, James Ketrenos wrote: > @@ -552,6 +577,17 @@ struct ieee80211_authentication { > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > +struct ieee80211_disassoc { Add alias for deauthentication frame here? > + struct ieee80211_hdr_3addr header; > + u16 reason_code; If we do not append _code to "status", why append _code to "reason"? > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > +struct ieee80211_probe_request { > + struct ieee80211_hdr_3addr header; > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > struct ieee80211_probe_response { > struct ieee80211_hdr_3addr header; > u32 time_stamp[2]; > @@ -560,14 +596,25 @@ struct ieee80211_probe_response { > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > -struct ieee80211_assoc_request_frame { > +/* Alias beacon for probe_response */ > +#define ieee80211_beacon ieee80211_probe_response > + > +struct ieee80211_assoc_request { > + struct ieee80211_hdr_3addr header; > + u16 capability; > + u16 listen_interval; > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > +struct ieee80211_reassoc_request { > + struct ieee80211_hdr_3addr header; > __le16 capability; > __le16 listen_interval; > u8 current_ap[ETH_ALEN]; > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > -struct ieee80211_assoc_response_frame { > +struct ieee80211_assoc_response { > struct ieee80211_hdr_3addr header; > __le16 capability; > __le16 status; |
From: Michael Wu <fla...@so...> - 2005-09-13 23:48:17
|
On Tuesday 13 September 2005 19:36, James Ketrenos wrote: > ieee80211: use endian-aware types > > From: Michael Wu <fla...@so...> > > This patch: > - fixes misc. whitespace/comments > - replaces u16 with __le16/__be16 where appropriate > > Signed-off-by: Michael Wu <fla...@so...> > Signed-off-by: Jiri Benc <jb...@su...> > > Signed-off-by: James Ketrenos <jke...@li...> > The original patch already went in, and this patch looks nothing like the one I sent in. -Michael Wu |
From: Michael Wu <fla...@so...> - 2005-09-13 23:45:44
|
This patch plus patch 5 looks very similar to my management frame patch except.. On Tuesday 13 September 2005 18:53, James Ketrenos wrote: > @@ -552,6 +577,17 @@ struct ieee80211_authentication { > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > +struct ieee80211_disassoc { Add alias for deauthentication frame here? > + struct ieee80211_hdr_3addr header; > + u16 reason_code; If we do not append _code to "status", why append _code to "reason"? > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > +struct ieee80211_probe_request { > + struct ieee80211_hdr_3addr header; > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > struct ieee80211_probe_response { > struct ieee80211_hdr_3addr header; > u32 time_stamp[2]; > @@ -560,14 +596,25 @@ struct ieee80211_probe_response { > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > -struct ieee80211_assoc_request_frame { > +/* Alias beacon for probe_response */ > +#define ieee80211_beacon ieee80211_probe_response > + > +struct ieee80211_assoc_request { > + struct ieee80211_hdr_3addr header; > + u16 capability; > + u16 listen_interval; > + struct ieee80211_info_element info_element[0]; > +} __attribute__ ((packed)); > + > +struct ieee80211_reassoc_request { > + struct ieee80211_hdr_3addr header; > __le16 capability; > __le16 listen_interval; > u8 current_ap[ETH_ALEN]; > struct ieee80211_info_element info_element[0]; > } __attribute__ ((packed)); > > -struct ieee80211_assoc_response_frame { > +struct ieee80211_assoc_response { > struct ieee80211_hdr_3addr header; > __le16 capability; > __le16 status; |
From: James K. <jke...@li...> - 2005-09-13 23:40:18
|
[Bug 768] Keep auth mode unchanged after iwconfig key off/on cycle. Signed-off-by: Zhu Yi <yi...@in...> Signed-off-by: James Ketrenos <jke...@li...> --- net/ieee80211/ieee80211_wx.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) 026d02fd0ed64ee1de4202080261883034fb355a diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -411,11 +411,15 @@ int ieee80211_wx_set_encode(struct ieee8 sec.flags |= SEC_ACTIVE_KEY; } } - ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); - sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.flags |= SEC_AUTH_MODE; - IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? - "OPEN" : "SHARED KEY"); + if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) { + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : + WLAN_AUTH_SHARED_KEY; + sec.flags |= SEC_AUTH_MODE; + IEEE80211_DEBUG_WX("Auth: %s\n", + sec.auth_mode == WLAN_AUTH_OPEN ? + "OPEN" : "SHARED KEY"); + } /* For now we just support WEP, so only set that security level... * TODO: When WPA is added this is one place that needs to change */ |
From: James K. <jke...@li...> - 2005-09-13 23:39:34
|
Mixed PTK/GTK CCMP/TKIP support. Signed-off-by: Hong Liu <hon...@in...> Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 3 +++ net/ieee80211/ieee80211_module.c | 2 ++ net/ieee80211/ieee80211_rx.c | 3 ++- net/ieee80211/ieee80211_wx.c | 13 ++++++++++--- 4 files changed, 17 insertions(+), 4 deletions(-) dd7f00c9b6ed7c260712182b04e6e74f5ba7e179 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -860,6 +860,9 @@ struct ieee80211_device { int host_encrypt; int host_encrypt_msdu; int host_decrypt; + /* host performs multicast decryption */ + int host_mc_decrypt; + int host_open_frag; int ieee802_1x; /* is IEEE 802.1X used */ diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -136,6 +136,8 @@ struct net_device *alloc_ieee80211(int s /* Default to enabling full open WEP with host based encrypt/decrypt */ ieee->host_encrypt = 1; ieee->host_decrypt = 1; + ieee->host_mc_decrypt = 1; + /* Host fragementation in Open mode. Default is enabled. * Note: host fragmentation is always enabled if host encryption * is enabled. For cards can do hardware encryption, they must do diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -420,7 +420,8 @@ int ieee80211_rx(struct ieee80211_device return 1; } - if (ieee->host_decrypt) { + if (is_multicast_ether_addr(hdr->addr1) ? ieee->host_mc_decrypt : + ieee->host_decrypt) { int idx = 0; if (skb->len >= hdrlen + 3) idx = skb->data[hdrlen + 3] >> 6; diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -492,6 +492,7 @@ int ieee80211_wx_set_encodeext(struct ie struct iw_point *encoding = &wrqu->encoding; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int i, idx, ret = 0; + int group_key = 0; const char *alg, *module; struct ieee80211_crypto_ops *ops; struct ieee80211_crypt_data **crypt; @@ -508,9 +509,10 @@ int ieee80211_wx_set_encodeext(struct ie } else idx = ieee->tx_keyidx; - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { crypt = &ieee->crypt[idx]; - else { + group_key = 1; + } else { if (idx != 0) return -EINVAL; if (ieee->iw_mode == IW_MODE_INFRA) @@ -541,7 +543,9 @@ int ieee80211_wx_set_encodeext(struct ie sec.enabled = 1; sec.encrypt = 1; - if (!(ieee->host_encrypt || ieee->host_decrypt)) + if (group_key ? !ieee->host_mc_decrypt : + !(ieee->host_encrypt || ieee->host_decrypt || + ieee->host_encrypt_msdu)) goto skip_host_crypt; switch (ext->alg) { @@ -631,6 +635,9 @@ int ieee80211_wx_set_encodeext(struct ie sec.flags |= SEC_LEVEL; sec.level = SEC_LEVEL_3; } + /* Don't set sec level for group keys. */ + if (group_key) + sec.flags &= ~SEC_LEVEL; } done: if (ieee->set_security) |
From: James K. <jke...@li...> - 2005-09-13 23:38:40
|
Type-o, capbility definition for QoS, and ERP parsing Added WLAN_CAPABILITY_QOS Fixed type-o WLAN_CAPABILITY_OSSS_OFDM -> WLAN_CAPABILITY_DSSS_OFDM Added ERP IE parsing to ieee80211_rx Added handle_probe_request callback. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) 46385b84b1e85d7616901b0cadb22aa153c4b86b diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -238,8 +238,9 @@ struct ieee80211_snap_hdr { #define WLAN_CAPABILITY_PBCC (1<<6) #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) -#define WLAN_CAPABILITY_OSSS_OFDM (1<<13) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) /* Status codes */ enum ieee80211_statuscode { @@ -769,6 +770,7 @@ struct ieee80211_network { u16 beacon_interval; u16 listen_interval; u16 atim_window; + u8 erp_value; u8 wpa_ie[MAX_WPA_IE_LEN]; size_t wpa_ie_len; u8 rsn_ie[MAX_WPA_IE_LEN]; @@ -919,6 +921,9 @@ struct ieee80211_device { int (*handle_probe_response) (struct net_device * dev, struct ieee80211_probe_response * resp, struct ieee80211_network * network); + int (*handle_probe_request) (struct net_device * dev, + struct ieee80211_probe_request * req, + struct ieee80211_rx_stats * stats); int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response * resp, struct ieee80211_network * network); |
From: James K. <jke...@li...> - 2005-09-13 23:37:59
|
"extern inline" doesn't make much sense. Signed-off-by: Adrian Bunk <bu...@st...> Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) 995ef1f025ac5317c877e649e9af41afeb54e7e8 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -938,12 +938,12 @@ struct ieee80211_device { #define IEEE_G (1<<2) #define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) -extern inline void *ieee80211_priv(struct net_device *dev) +static inline void *ieee80211_priv(struct net_device *dev) { return ((struct ieee80211_device *)netdev_priv(dev))->priv; } -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -959,7 +959,7 @@ extern inline int ieee80211_is_empty_ess return 1; } -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, +static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) { /* @@ -986,7 +986,7 @@ extern inline int ieee80211_is_valid_mod return 0; } -extern inline int ieee80211_get_hdrlen(u16 fc) +static inline int ieee80211_get_hdrlen(u16 fc) { int hdrlen = IEEE80211_3ADDR_LEN; u16 stype = WLAN_FC_GET_STYPE(fc); @@ -1014,7 +1014,7 @@ extern inline int ieee80211_get_hdrlen(u return hdrlen; } -extern inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) +static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) { switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { case IEEE80211_1ADDR_LEN: @@ -1079,12 +1079,12 @@ extern int ieee80211_wx_get_encodeext(st union iwreq_data *wrqu, char *extra); #endif -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) +static inline void ieee80211_increment_scans(struct ieee80211_device *ieee) { ieee->scans++; } -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) +static inline int ieee80211_get_scans(struct ieee80211_device *ieee) { return ieee->scans; } |
From: James K. <jke...@li...> - 2005-09-13 23:36:57
|
ieee80211: use endian-aware types From: Michael Wu <fla...@so...> This patch: - fixes misc. whitespace/comments - replaces u16 with __le16/__be16 where appropriate Signed-off-by: Michael Wu <fla...@so...> Signed-off-by: Jiri Benc <jb...@su...> Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 58 ++++++++++++++++++++++++----------------------- 1 files changed, 29 insertions(+), 29 deletions(-) 644cd16ef63ef1ee185cff5561e610ffa56036d7 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -516,68 +516,68 @@ enum ieee80211_mfie { * information to determine what type of underlying data type is actually * stored in the data. */ struct ieee80211_hdr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 payload[0]; } __attribute__ ((packed)); struct ieee80211_hdr_1addr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 payload[0]; } __attribute__ ((packed)); struct ieee80211_hdr_2addr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 payload[0]; } __attribute__ ((packed)); struct ieee80211_hdr_3addr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 payload[0]; } __attribute__ ((packed)); struct ieee80211_hdr_4addr { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 addr4[ETH_ALEN]; u8 payload[0]; } __attribute__ ((packed)); struct ieee80211_hdr_3addrqos { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 payload[0]; - u16 qos_ctl; + __le16 qos_ctl; } __attribute__ ((packed)); struct ieee80211_hdr_4addrqos { - u16 frame_ctl; - u16 duration_id; + __le16 frame_ctl; + __le16 duration_id; u8 addr1[ETH_ALEN]; u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; - u16 seq_ctl; + __le16 seq_ctl; u8 addr4[ETH_ALEN]; u8 payload[0]; - u16 qos_ctl; + __le16 qos_ctl; } __attribute__ ((packed)); struct ieee80211_info_element { @@ -613,7 +613,7 @@ struct ieee80211_auth { struct ieee80211_disassoc { struct ieee80211_hdr_3addr header; - u16 reason_code; + __le16 reason_code; struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); @@ -635,8 +635,8 @@ struct ieee80211_probe_response { struct ieee80211_assoc_request { struct ieee80211_hdr_3addr header; - u16 capability; - u16 listen_interval; + __le16 capability; + __le16 listen_interval; struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); @@ -661,8 +661,8 @@ struct ieee80211_txb { u8 encrypted; u8 rts_included; u8 reserved; - u16 frag_size; - u16 payload_size; + __le16 frag_size; + __le16 payload_size; struct sk_buff *fragments[0]; }; @@ -712,7 +712,7 @@ struct ieee80211_qos_information_element struct ieee80211_qos_ac_parameter { u8 aci_aifsn; u8 ecw_min_max; - u16 tx_op_limit; + __le16 tx_op_limit; } __attribute__ ((packed)); struct ieee80211_qos_parameter_info { @@ -722,11 +722,11 @@ struct ieee80211_qos_parameter_info { } __attribute__ ((packed)); struct ieee80211_qos_parameters { - u16 cw_min[QOS_QUEUE_NUM]; - u16 cw_max[QOS_QUEUE_NUM]; + __le16 cw_min[QOS_QUEUE_NUM]; + __le16 cw_max[QOS_QUEUE_NUM]; u8 aifs[QOS_QUEUE_NUM]; u8 flag[QOS_QUEUE_NUM]; - u16 tx_op_limit[QOS_QUEUE_NUM]; + __le16 tx_op_limit[QOS_QUEUE_NUM]; } __attribute__ ((packed)); struct ieee80211_qos_data { |
From: James K. <jke...@li...> - 2005-09-13 23:36:05
|
Updated misc. copyright dates. Added version reporting to syslog during ieee80211 subsystem load. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 9 ++++++++- net/ieee80211/ieee80211_module.c | 26 +++++++++++++++++++------- net/ieee80211/ieee80211_rx.c | 2 +- net/ieee80211/ieee80211_tx.c | 2 +- net/ieee80211/ieee80211_wx.c | 2 +- 5 files changed, 30 insertions(+), 11 deletions(-) 051cc01016cb6188fb825ec4f4e7783ac59db64b diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -11,12 +11,17 @@ * * Adaption to a generic IEEE 802.11 stack by James Ketrenos * <jke...@li...> - * Copyright (c) 2004, Intel Corporation + * Copyright (c) 2004-2005, Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. + * + * API Version History + * 1.0.x -- Initial version + * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs, and + * various structure changes */ #ifndef IEEE80211_H #define IEEE80211_H @@ -24,6 +29,8 @@ #include <linux/kernel.h> /* ARRAY_SIZE */ #include <linux/wireless.h> +#define IEEE80211_VERSION "git-1.1.4-pre5" + #ifdef CONFIG_IEEE80211_CRYPT_TKIP_MODULE #ifndef CONFIG_IEEE80211_CRYPT_TKIP #define CONFIG_IEEE80211_CRYPT_TKIP diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -1,6 +1,6 @@ /******************************************************************************* - Copyright(c) 2004 Intel Corporation. All rights reserved. + Copyright(c) 2004-2005 Intel Corporation. All rights reserved. Portions of this file are based on the WEP enablement code provided by the Host AP project hostap-drivers v0.1.3 @@ -53,13 +53,16 @@ #include <net/ieee80211.h> -MODULE_DESCRIPTION("802.11 data/management/control stack"); -MODULE_AUTHOR - ("Copyright (C) 2004 Intel Corporation <jke...@li...>"); +#define DRV_DESCRIPTION "802.11 data/management/control stack" +#define DRV_NAME "ieee80211" +#define DRV_VERSION IEEE80211_VERSION +#define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jke...@li...>" + +MODULE_VERSION(DRV_VERSION); +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -#define DRV_NAME "ieee80211" - static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) { if (ieee->networks) @@ -218,9 +221,11 @@ static int store_debug_level(struct file return strnlen(buf, len); } +#endif /* CONFIG_IEEE80211_DEBUG */ static int __init ieee80211_init(void) { +#ifdef CONFIG_IEEE80211_DEBUG struct proc_dir_entry *e; ieee80211_debug_level = debug; @@ -240,26 +245,33 @@ static int __init ieee80211_init(void) e->read_proc = show_debug_level; e->write_proc = store_debug_level; e->data = NULL; +#endif /* CONFIG_IEEE80211_DEBUG */ + + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); return 0; } static void __exit ieee80211_exit(void) { +#ifdef CONFIG_IEEE80211_DEBUG if (ieee80211_proc) { remove_proc_entry("debug_level", ieee80211_proc); remove_proc_entry(DRV_NAME, proc_net); ieee80211_proc = NULL; } +#endif /* CONFIG_IEEE80211_DEBUG */ } +#ifdef CONFIG_IEEE80211_DEBUG #include <linux/moduleparam.h> module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); +#endif /* CONFIG_IEEE80211_DEBUG */ module_exit(ieee80211_exit); module_init(ieee80211_init); -#endif const char *escape_essid(const char *essid, u8 essid_len) { diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -5,7 +5,7 @@ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen * <jkm...@cc...> * Copyright (c) 2002-2003, Jouni Malinen <jkm...@cc...> - * Copyright (c) 2004, Intel Corporation + * Copyright (c) 2004-2005, Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2004 Intel Corporation. All rights reserved. + Copyright(c) 2004-2005 Intel Corporation. All rights reserved. Portions of this file are based on the WEP enablement code provided by the Host AP project hostap-drivers v0.1.3 |
From: James K. <jke...@li...> - 2005-09-13 23:35:22
|
Added ieee80211_radiotap.h to enhance statistic reporting to user space from wireless drivers. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211_radiotap.h | 237 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 237 insertions(+), 0 deletions(-) create mode 100644 include/net/ieee80211_radiotap.h 4965d2bc32db09b663753aaf7ae3c9218bfac5b9 diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h new file mode 100644 --- /dev/null +++ b/include/net/ieee80211_radiotap.h @@ -0,0 +1,237 @@ +/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */ +/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */ + +/*- + * Copyright (c) 2003, 2004 David Young. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of David Young may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID + * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * Modifications to fit into the linux IEEE 802.11 stack, + * Mike Kershaw (dr...@ki...) + */ + +#ifndef IEEE80211RADIOTAP_H +#define IEEE80211RADIOTAP_H + +#include <linux/version.h> +#include <linux/if_ether.h> +#include <linux/kernel.h> + +/* Kluge the radiotap linktype for now if we don't have it */ +#ifndef ARPHRD_IEEE80211_RADIOTAP +#define ARPHRD_IEEE80211_RADIOTAP 803 +#endif + +/* Radiotap header version (from official NetBSD feed) */ +#define IEEE80211RADIOTAP_VERSION "1.5" +/* Base version of the radiotap packet header data */ +#define PKTHDR_RADIOTAP_VERSION 0 + +/* A generic radio capture format is desirable. There is one for + * Linux, but it is neither rigidly defined (there were not even + * units given for some fields) nor easily extensible. + * + * I suggest the following extensible radio capture format. It is + * based on a bitmap indicating which fields are present. + * + * I am trying to describe precisely what the application programmer + * should expect in the following, and for that reason I tell the + * units and origin of each measurement (where it applies), or else I + * use sufficiently weaselly language ("is a monotonically nondecreasing + * function of...") that I cannot set false expectations for lawyerly + * readers. + */ + +/* XXX tcpdump/libpcap do not tolerate variable-length headers, + * yet, so we pad every radiotap header to 64 bytes. Ugh. + */ +#define IEEE80211_RADIOTAP_HDRLEN 64 + +/* The radio capture header precedes the 802.11 header. */ +struct ieee80211_radiotap_header { + u_int8_t it_version; /* Version 0. Only increases + * for drastic changes, + * introduction of compatible + * new fields does not count. + */ + u_int8_t it_pad; + u_int16_t it_len; /* length of the whole + * header in bytes, including + * it_version, it_pad, + * it_len, and data fields. + */ + u_int32_t it_present; /* A bitmap telling which + * fields are present. Set bit 31 + * (0x80000000) to extend the + * bitmap by another 32 bits. + * Additional extensions are made + * by setting bit 31. + */ +}; + +/* Name Data type Units + * ---- --------- ----- + * + * IEEE80211_RADIOTAP_TSFT u_int64_t microseconds + * + * Value in microseconds of the MAC's 64-bit 802.11 Time + * Synchronization Function timer when the first bit of the + * MPDU arrived at the MAC. For received frames, only. + * + * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap + * + * Tx/Rx frequency in MHz, followed by flags (see below). + * + * IEEE80211_RADIOTAP_FHSS u_int16_t see below + * + * For frequency-hopping radios, the hop set (first byte) + * and pattern (second byte). + * + * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s + * + * Tx/Rx data rate + * + * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from + * one milliwatt (dBm) + * + * RF signal power at the antenna, decibel difference from + * one milliwatt. + * + * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from + * one milliwatt (dBm) + * + * RF noise power at the antenna, decibel difference from one + * milliwatt. + * + * IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB) + * + * RF signal power at the antenna, decibel difference from an + * arbitrary, fixed reference. + * + * IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB) + * + * RF noise power at the antenna, decibel difference from an + * arbitrary, fixed reference point. + * + * IEEE80211_RADIOTAP_LOCK_QUALITY u_int16_t unitless + * + * Quality of Barker code lock. Unitless. Monotonically + * nondecreasing with "better" lock strength. Called "Signal + * Quality" in datasheets. (Is there a standard way to measure + * this?) + * + * IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless + * + * Transmit power expressed as unitless distance from max + * power set at factory calibration. 0 is max power. + * Monotonically nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB) + * + * Transmit power expressed as decibel distance from max power + * set at factory calibration. 0 is max power. Monotonically + * nondecreasing with lower power levels. + * + * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from + * one milliwatt (dBm) + * + * Transmit power expressed as dBm (decibels from a 1 milliwatt + * reference). This is the absolute power level measured at + * the antenna port. + * + * IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap + * + * Properties of transmitted and received frames. See flags + * defined below. + * + * IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index + * + * Unitless indication of the Rx/Tx antenna for this packet. + * The first antenna is antenna 0. + * + * IEEE80211_RADIOTAP_FCS u_int32_t data + * + * FCS from frame in network byte order. + */ +enum ieee80211_radiotap_type { + IEEE80211_RADIOTAP_TSFT = 0, + IEEE80211_RADIOTAP_FLAGS = 1, + IEEE80211_RADIOTAP_RATE = 2, + IEEE80211_RADIOTAP_CHANNEL = 3, + IEEE80211_RADIOTAP_FHSS = 4, + IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5, + IEEE80211_RADIOTAP_DBM_ANTNOISE = 6, + IEEE80211_RADIOTAP_LOCK_QUALITY = 7, + IEEE80211_RADIOTAP_TX_ATTENUATION = 8, + IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9, + IEEE80211_RADIOTAP_DBM_TX_POWER = 10, + IEEE80211_RADIOTAP_ANTENNA = 11, + IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12, + IEEE80211_RADIOTAP_DB_ANTNOISE = 13, + IEEE80211_RADIOTAP_EXT = 31, +}; + +/* Channel flags. */ +#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */ +#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */ +#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */ +#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */ +#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */ +#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */ + +/* For IEEE80211_RADIOTAP_FLAGS */ +#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received + * during CFP + */ +#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received + * with short + * preamble + */ +#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received + * with WEP encryption + */ +#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received + * with fragmentation + */ +#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */ +#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between + * 802.11 header and payload + * (to 32-bit boundary) + */ + +/* Ugly macro to convert literal channel numbers into their mhz equivalents + * There are certianly some conditions that will break this (like feeding it '30') + * but they shouldn't arise since nothing talks on channel 30. */ +#define ieee80211chan2mhz(x) \ + (((x) <= 14) ? \ + (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \ + ((x) + 1000) * 5) + +#endif /* IEEE80211_RADIOTAP_H */ |
From: James K. <jke...@li...> - 2005-09-13 23:33:02
|
Added ieee80211_geo to provide helper functions to drivers for implementing supported channel maps. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 42 ++++++++++++ net/ieee80211/Makefile | 3 + net/ieee80211/ieee80211_geo.c | 141 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 1 deletions(-) create mode 100644 net/ieee80211/ieee80211_geo.c d814c2adddf430e3b97f0dbc9ce6dd5565af1f0f diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -787,6 +787,34 @@ enum ieee80211_state { #define CFG_IEEE80211_COMPUTE_FCS (1<<1) #define CFG_IEEE80211_RTS (1<<2) +#define IEEE80211_24GHZ_MIN_CHANNEL 1 +#define IEEE80211_24GHZ_MAX_CHANNEL 14 +#define IEEE80211_24GHZ_CHANNELS 14 + +#define IEEE80211_52GHZ_MIN_CHANNEL 36 +#define IEEE80211_52GHZ_MAX_CHANNEL 165 +#define IEEE80211_52GHZ_CHANNELS 32 + +enum { + IEEE80211_CH_PASSIVE_ONLY = (1 << 0), + IEEE80211_CH_B_ONLY = (1 << 2), +}; + +struct ieee80211_channel { + u16 freq; + u8 channel; + u8 flags; + u8 max_power; +}; + +struct ieee80211_geo { + u8 name[4]; + u8 bg_channels; + u8 a_channels; + struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS]; + struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS]; +}; + struct ieee80211_device { struct net_device *dev; struct ieee80211_security sec; @@ -795,6 +823,8 @@ struct ieee80211_device { struct net_device_stats stats; struct ieee80211_stats ieee_stats; + struct ieee80211_geo geo; + /* Probe / Beacon management */ struct list_head network_free_list; struct list_head network_list; @@ -1011,6 +1041,18 @@ extern void ieee80211_rx_mgt(struct ieee struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); +/* ieee80211_geo.c */ +extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device + *ieee); +extern int ieee80211_set_geo(struct ieee80211_device *ieee, + const struct ieee80211_geo *geo); + +extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee, + u8 channel); +extern int ieee80211_channel_to_index(struct ieee80211_device *ieee, + u8 channel); +extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq); + /* ieee80211_wx.c */ extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, struct iw_request_info *info, diff --git a/net/ieee80211/Makefile b/net/ieee80211/Makefile --- a/net/ieee80211/Makefile +++ b/net/ieee80211/Makefile @@ -7,5 +7,6 @@ ieee80211-objs := \ ieee80211_module.o \ ieee80211_tx.o \ ieee80211_rx.o \ - ieee80211_wx.o + ieee80211_wx.o \ + ieee80211_geo.o diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c new file mode 100644 --- /dev/null +++ b/net/ieee80211/ieee80211_geo.c @@ -0,0 +1,141 @@ +/****************************************************************************** + + Copyright(c) 2005 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos <ipw...@li...> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +******************************************************************************/ +#include <linux/compiler.h> +#include <linux/config.h> +#include <linux/errno.h> +#include <linux/if_arp.h> +#include <linux/in6.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/proc_fs.h> +#include <linux/skbuff.h> +#include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/types.h> +#include <linux/version.h> +#include <linux/wireless.h> +#include <linux/etherdevice.h> +#include <asm/uaccess.h> + +#include <net/ieee80211.h> + +int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + /* NOTE: If G mode is currently supported but + * this is a B only channel, we don't see it + * as valid. */ + if ((ieee->geo.bg[i].channel == channel) && + (!(ieee->mode & IEEE_G) || + !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY))) + return IEEE80211_24GHZ_BAND; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].channel == channel) + return IEEE80211_52GHZ_BAND; + + return 0; +} + +int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + if (ieee->geo.bg[i].channel == channel) + return i; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].channel == channel) + return i; + + return -1; +} + +u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq) +{ + int i; + + /* Driver needs to initialize the geography map before using + * these helper functions */ + BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); + + freq /= 100000; + + if (ieee->freq_band & IEEE80211_24GHZ_BAND) + for (i = 0; i < ieee->geo.bg_channels; i++) + if (ieee->geo.bg[i].freq == freq) + return ieee->geo.bg[i].channel; + + if (ieee->freq_band & IEEE80211_52GHZ_BAND) + for (i = 0; i < ieee->geo.a_channels; i++) + if (ieee->geo.a[i].freq == freq) + return ieee->geo.a[i].channel; + + return 0; +} + +int ieee80211_set_geo(struct ieee80211_device *ieee, + const struct ieee80211_geo *geo) +{ + memcpy(ieee->geo.name, geo->name, 3); + ieee->geo.name[3] = '\0'; + ieee->geo.bg_channels = geo->bg_channels; + ieee->geo.a_channels = geo->a_channels; + memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * + sizeof(struct ieee80211_channel)); + memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * + sizeof(struct ieee80211_channel)); + return 0; +} + +const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee) +{ + return &ieee->geo; +} + +EXPORT_SYMBOL(ieee80211_is_valid_channel); +EXPORT_SYMBOL(ieee80211_freq_to_channel); +EXPORT_SYMBOL(ieee80211_channel_to_index); +EXPORT_SYMBOL(ieee80211_set_geo); +EXPORT_SYMBOL(ieee80211_get_geo); |
From: James K. <jke...@li...> - 2005-09-13 23:32:12
|
Add QoS (WME) support to the ieee80211 subsystem. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 103 ++++++++++++- net/ieee80211/ieee80211_rx.c | 334 ++++++++++++++++++++++++++++++++++++++++-- net/ieee80211/ieee80211_tx.c | 5 - 3 files changed, 417 insertions(+), 25 deletions(-) f02f23b1b59d6ebab383112524d3c5db9b4f040f diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -98,6 +98,7 @@ #define IEEE80211_STYPE_CFACK 0x0050 #define IEEE80211_STYPE_CFPOLL 0x0060 #define IEEE80211_STYPE_CFACKPOLL 0x0070 +#define IEEE80211_STYPE_QOS_DATA 0x0080 #define IEEE80211_SCTL_FRAG 0x000F #define IEEE80211_SCTL_SEQ 0xFFF0 @@ -159,6 +160,7 @@ const char *escape_essid(const char *ess #define IEEE80211_DL_TX (1<<8) #define IEEE80211_DL_RX (1<<9) +#define IEEE80211_DL_QOS (1<<31) #define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) #define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) @@ -172,6 +174,7 @@ const char *escape_essid(const char *ess #define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) #define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) #define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) +#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) #include <linux/netdevice.h> #include <linux/wireless.h> #include <linux/if_arp.h> /* ARPHRD_ETHER */ @@ -499,6 +502,7 @@ enum ieee80211_mfie { MFIE_TYPE_RSN = 48, MFIE_TYPE_RATES_EX = 50, MFIE_TYPE_GENERIC = 221, + MFIE_TYPE_QOS_PARAMETER = 222, }; /* Minimal header; can be used for passing 802.11 frames with sufficient @@ -546,6 +550,29 @@ struct ieee80211_hdr_4addr { u8 payload[0]; } __attribute__ ((packed)); +struct ieee80211_hdr_3addrqos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 payload[0]; + u16 qos_ctl; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addrqos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; + u16 qos_ctl; +} __attribute__ ((packed)); + struct ieee80211_info_element { u8 id; u8 len; @@ -647,9 +674,68 @@ struct ieee80211_txb { #define MAX_WPA_IE_LEN 64 -#define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +/* QoS structure */ +#define NETWORK_HAS_QOS_PARAMETERS (1<<3) +#define NETWORK_HAS_QOS_INFORMATION (1<<4) +#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION) + +#define QOS_QUEUE_NUM 4 +#define QOS_OUI_LEN 3 +#define QOS_OUI_TYPE 2 +#define QOS_ELEMENT_ID 221 +#define QOS_OUI_INFO_SUB_TYPE 0 +#define QOS_OUI_PARAM_SUB_TYPE 1 +#define QOS_VERSION_1 1 +#define QOS_AIFSN_MIN_VALUE 2 + +struct ieee80211_qos_information_element { + u8 elementID; + u8 length; + u8 qui[QOS_OUI_LEN]; + u8 qui_type; + u8 qui_subtype; + u8 version; + u8 ac_info; +} __attribute__ ((packed)); + +struct ieee80211_qos_ac_parameter { + u8 aci_aifsn; + u8 ecw_min_max; + u16 tx_op_limit; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameter_info { + struct ieee80211_qos_information_element info_element; + u8 reserved; + struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_parameters { + u16 cw_min[QOS_QUEUE_NUM]; + u16 cw_max[QOS_QUEUE_NUM]; + u8 aifs[QOS_QUEUE_NUM]; + u8 flag[QOS_QUEUE_NUM]; + u16 tx_op_limit[QOS_QUEUE_NUM]; +} __attribute__ ((packed)); + +struct ieee80211_qos_data { + struct ieee80211_qos_parameters parameters; + int active; + int supported; + u8 param_count; + u8 old_param_count; +}; + +struct ieee80211_tim_parameters { + u8 tim_count; + u8 tim_period; +} __attribute__ ((packed)); + +/*******************************************************/ struct ieee80211_network { /* These entries are used to identify a unique network */ @@ -659,6 +745,8 @@ struct ieee80211_network { u8 ssid[IW_ESSID_MAX_SIZE + 1]; u8 ssid_len; + struct ieee80211_qos_data qos_data; + /* These are network statistics */ struct ieee80211_rx_stats stats; u16 capability; @@ -678,6 +766,7 @@ struct ieee80211_network { size_t wpa_ie_len; u8 rsn_ie[MAX_WPA_IE_LEN]; size_t rsn_ie_len; + struct ieee80211_tim_parameters tim; struct list_head list; }; @@ -775,10 +864,13 @@ struct ieee80211_device { void (*set_security) (struct net_device * dev, struct ieee80211_security * sec); int (*hard_start_xmit) (struct ieee80211_txb * txb, - struct net_device * dev); + struct net_device * dev, int pri); int (*reset_port) (struct net_device * dev); int (*is_queue_full) (struct net_device * dev, int pri); + int (*handle_management) (struct net_device * dev, + struct ieee80211_network * network, u16 type); + /* Typical STA methods */ int (*handle_auth) (struct net_device * dev, struct ieee80211_auth * auth); @@ -860,11 +952,14 @@ extern inline int ieee80211_is_valid_mod extern inline int ieee80211_get_hdrlen(u16 fc) { int hdrlen = IEEE80211_3ADDR_LEN; + u16 stype = WLAN_FC_GET_STYPE(fc); switch (WLAN_FC_GET_TYPE(fc)) { case IEEE80211_FTYPE_DATA: if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) hdrlen = IEEE80211_4ADDR_LEN; + if (stype & IEEE80211_STYPE_QOS_DATA) + hdrlen += 2; break; case IEEE80211_FTYPE_CTL: switch (WLAN_FC_GET_STYPE(fc)) { diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -545,6 +545,9 @@ int ieee80211_rx(struct ieee80211_device /* Nullfunc frames may have PS-bit set, so they must be passed to * hostap_handle_sta_rx() before being dropped here. */ + + stype &= ~IEEE80211_STYPE_QOS_DATA; + if (stype != IEEE80211_STYPE_DATA && stype != IEEE80211_STYPE_DATA_CFACK && stype != IEEE80211_STYPE_DATA_CFPOLL && @@ -769,6 +772,264 @@ int ieee80211_rx(struct ieee80211_device #define MGMT_FRAME_FIXED_PART_LENGTH 0x24 +static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; + +/* +* Make ther structure we read from the beacon packet has +* the right values +*/ +static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element + *info_element, int sub_type) +{ + + if (info_element->qui_subtype != sub_type) + return -1; + if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) + return -1; + if (info_element->qui_type != QOS_OUI_TYPE) + return -1; + if (info_element->version != QOS_VERSION_1) + return -1; + + return 0; +} + +/* + * Parse a QoS parameter element + */ +static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info + *element_param, struct ieee80211_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2; + + if ((info_element == NULL) || (element_param == NULL)) + return -1; + + if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) { + memcpy(element_param->info_element.qui, info_element->data, + info_element->len); + element_param->info_element.elementID = info_element->id; + element_param->info_element.length = info_element->len; + } else + ret = -1; + if (ret == 0) + ret = ieee80211_verify_qos_info(&element_param->info_element, + QOS_OUI_PARAM_SUB_TYPE); + return ret; +} + +/* + * Parse a QoS information element + */ +static int ieee80211_read_qos_info_element(struct + ieee80211_qos_information_element + *element_info, struct ieee80211_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct ieee80211_qos_information_element) - 2; + + if (element_info == NULL) + return -1; + if (info_element == NULL) + return -1; + + if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) { + memcpy(element_info->qui, info_element->data, + info_element->len); + element_info->elementID = info_element->id; + element_info->length = info_element->len; + } else + ret = -1; + + if (ret == 0) + ret = ieee80211_verify_qos_info(element_info, + QOS_OUI_INFO_SUB_TYPE); + return ret; +} + +/* + * Write QoS parameters from the ac parameters. + */ +static int ieee80211_qos_convert_ac_to_parameters(struct + ieee80211_qos_parameter_info + *param_elm, struct + ieee80211_qos_parameters + *qos_param) +{ + int rc = 0; + int i; + struct ieee80211_qos_ac_parameter *ac_params; + u32 txop; + u8 cw_min; + u8 cw_max; + + for (i = 0; i < QOS_QUEUE_NUM; i++) { + ac_params = &(param_elm->ac_params_record[i]); + + qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F; + qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2; + + cw_min = ac_params->ecw_min_max & 0x0F; + qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1); + + cw_max = (ac_params->ecw_min_max & 0xF0) >> 4; + qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1); + + qos_param->flag[i] = + (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; + + txop = le16_to_cpu(ac_params->tx_op_limit) * 32; + qos_param->tx_op_limit[i] = (u16) txop; + } + return rc; +} + +/* + * we have a generic data element which it may contain QoS information or + * parameters element. check the information element length to decide + * which type to read + */ +static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element + *info_element, + struct ieee80211_network *network) +{ + int rc = 0; + struct ieee80211_qos_parameters *qos_param = NULL; + struct ieee80211_qos_information_element qos_info_element; + + rc = ieee80211_read_qos_info_element(&qos_info_element, info_element); + + if (rc == 0) { + network->qos_data.param_count = qos_info_element.ac_info & 0x0F; + network->flags |= NETWORK_HAS_QOS_INFORMATION; + } else { + struct ieee80211_qos_parameter_info param_element; + + rc = ieee80211_read_qos_param_element(¶m_element, + info_element); + if (rc == 0) { + qos_param = &(network->qos_data.parameters); + ieee80211_qos_convert_ac_to_parameters(¶m_element, + qos_param); + network->flags |= NETWORK_HAS_QOS_PARAMETERS; + network->qos_data.param_count = + param_element.info_element.ac_info & 0x0F; + } + } + + if (rc == 0) { + IEEE80211_DEBUG_QOS("QoS is supported\n"); + network->qos_data.supported = 1; + } + return rc; +} + +static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response + *frame, struct ieee80211_rx_stats *stats) +{ + struct ieee80211_network network_resp; + struct ieee80211_network *network = &network_resp; + struct ieee80211_info_element *info_element; + struct net_device *dev = ieee->dev; + u16 left; + + network->flags = 0; + network->qos_data.active = 0; + network->qos_data.supported = 0; + network->qos_data.param_count = 0; + network->qos_data.old_param_count = 0; + + //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF); + network->atim_window = le16_to_cpu(frame->aid); + network->listen_interval = le16_to_cpu(frame->status); + + info_element = frame->info_element; + left = stats->len - sizeof(*frame); + + while (left >= sizeof(struct ieee80211_info_element)) { + if (sizeof(struct ieee80211_info_element) + + info_element->len > left) { + IEEE80211_DEBUG_QOS("ASSOC RESP: parse failed: " + "info_element->len + 2 > left : " + "info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + + sizeof(struct + ieee80211_info_element), + left, info_element->id); + return 1; + } + + switch (info_element->id) { + case MFIE_TYPE_SSID: + if (ieee80211_is_empty_essid(info_element->data, + info_element->len)) { + network->flags |= NETWORK_EMPTY_ESSID; + break; + } + + network->ssid_len = min(info_element->len, + (u8) IW_ESSID_MAX_SIZE); + memcpy(network->ssid, info_element->data, + network->ssid_len); + if (network->ssid_len < IW_ESSID_MAX_SIZE) + memset(network->ssid + network->ssid_len, 0, + IW_ESSID_MAX_SIZE - network->ssid_len); + + IEEE80211_DEBUG_QOS("MFIE_TYPE_SSID: '%s' len=%d.\n", + network->ssid, network->ssid_len); + break; + + case MFIE_TYPE_TIM: + IEEE80211_DEBUG_QOS("MFIE_TYPE_TIM: ignored\n"); + break; + + case MFIE_TYPE_IBSS_SET: + IEEE80211_DEBUG_QOS("MFIE_TYPE_IBSS_SET: ignored\n"); + break; + + case MFIE_TYPE_CHALLENGE: + IEEE80211_DEBUG_QOS("MFIE_TYPE_CHALLENGE: ignored\n"); + break; + + case MFIE_TYPE_GENERIC: + IEEE80211_DEBUG_QOS("MFIE_TYPE_GENERIC: %d bytes\n", + info_element->len); + ieee80211_parse_qos_info_param_IE(info_element, + network); + break; + + case MFIE_TYPE_RSN: + IEEE80211_DEBUG_QOS("MFIE_TYPE_RSN: %d bytes\n", + info_element->len); + break; + + case MFIE_TYPE_QOS_PARAMETER: + printk("QoS Error need to parse QOS_PARAMETER IE\n"); + break; + + default: + IEEE80211_DEBUG_QOS("unsupported IE %d\n", + info_element->id); + break; + } + + left -= sizeof(struct ieee80211_info_element) + + info_element->len; + info_element = (struct ieee80211_info_element *) + &info_element->data[info_element->len]; + } + + if (ieee->handle_assoc_response != NULL) + ieee->handle_assoc_response(dev, frame, network); + + return 0; +} + +/***************************************************/ + static inline int ieee80211_is_ofdm_rate(u8 rate) { switch (rate & ~IEEE80211_BASIC_RATE_MASK) { @@ -797,6 +1058,9 @@ static inline int ieee80211_network_init struct ieee80211_info_element *info_element; u16 left; u8 i; + network->qos_data.active = 0; + network->qos_data.supported = 0; + network->qos_data.param_count = 0; /* Pull out fixed field data */ memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); @@ -824,13 +1088,11 @@ static inline int ieee80211_network_init info_element = beacon->info_element; left = stats->len - sizeof(*beacon); - while (left >= sizeof(struct ieee80211_info_element)) { - if (sizeof(struct ieee80211_info_element) + info_element->len > - left) { + while (left >= sizeof(*info_element)) { + if (sizeof(*info_element) + info_element->len > left) { IEEE80211_DEBUG_SCAN ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n", - info_element->len + - sizeof(struct ieee80211_info_element), left); + info_element->len + sizeof(*info_element), left); return 1; } @@ -858,15 +1120,14 @@ static inline int ieee80211_network_init #ifdef CONFIG_IEEE80211_DEBUG p = rates_str; #endif - network->rates_len = - min(info_element->len, MAX_RATES_LENGTH); + network->rates_len = min(info_element->len, + MAX_RATES_LENGTH); for (i = 0; i < network->rates_len; i++) { network->rates[i] = info_element->data[i]; #ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, - sizeof(rates_str) - (p - - rates_str), - "%02X ", network->rates[i]); + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); #endif if (ieee80211_is_ofdm_rate (info_element->data[i])) { @@ -886,15 +1147,14 @@ static inline int ieee80211_network_init #ifdef CONFIG_IEEE80211_DEBUG p = rates_str; #endif - network->rates_ex_len = - min(info_element->len, MAX_RATES_EX_LENGTH); + network->rates_ex_len = min(info_element->len, + MAX_RATES_EX_LENGTH); for (i = 0; i < network->rates_ex_len; i++) { network->rates_ex[i] = info_element->data[i]; #ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, - sizeof(rates_str) - (p - - rates_str), - "%02X ", network->rates[i]); + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); #endif if (ieee80211_is_ofdm_rate (info_element->data[i])) { @@ -940,6 +1200,10 @@ static inline int ieee80211_network_init case MFIE_TYPE_GENERIC: IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len); + if (!ieee80211_parse_qos_info_param_IE(info_element, + network)) + break; + if (info_element->len >= 4 && info_element->data[0] == 0x00 && info_element->data[1] == 0x50 && @@ -961,14 +1225,18 @@ static inline int ieee80211_network_init network->rsn_ie_len); break; + case MFIE_TYPE_QOS_PARAMETER: + printk(KERN_ERR + "QoS Error need to parse QOS_PARAMETER IE\n"); + break; + default: IEEE80211_DEBUG_SCAN("unsupported IE %d\n", info_element->id); break; } - left -= sizeof(struct ieee80211_info_element) + - info_element->len; + left -= sizeof(*info_element) + info_element->len; info_element = (struct ieee80211_info_element *) &info_element->data[info_element->len]; } @@ -1015,6 +1283,9 @@ static inline int is_same_network(struct static inline void update_network(struct ieee80211_network *dst, struct ieee80211_network *src) { + int qos_active; + u8 old_param; + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); dst->capability = src->capability; memcpy(dst->rates, src->rates, src->rates_len); @@ -1037,6 +1308,28 @@ static inline void update_network(struct dst->rsn_ie_len = src->rsn_ie_len; dst->last_scanned = jiffies; + qos_active = src->qos_data.active; + old_param = dst->qos_data.old_param_count; + if (dst->flags & NETWORK_HAS_QOS_MASK) + memcpy(&dst->qos_data, &src->qos_data, + sizeof(struct ieee80211_qos_data)); + else { + dst->qos_data.supported = src->qos_data.supported; + dst->qos_data.param_count = src->qos_data.param_count; + } + + if (dst->qos_data.supported == 1) { + if (dst->ssid_len) + IEEE80211_DEBUG_QOS + ("QoS the network %s is QoS supported\n", + dst->ssid); + else + IEEE80211_DEBUG_QOS + ("QoS the network is QoS supported\n"); + } + dst->qos_data.active = qos_active; + dst->qos_data.old_param_count = old_param; + /* dst->last_associate is not overwritten */ } @@ -1178,6 +1471,9 @@ void ieee80211_rx_mgt(struct ieee80211_d IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n", WLAN_FC_GET_STYPE(le16_to_cpu (header->frame_ctl))); + ieee80211_handle_assoc_resp(ieee, + (struct ieee80211_assoc_response *) + header, stats); break; case IEEE80211_STYPE_REASSOC_RESP: diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -479,7 +479,7 @@ int ieee80211_xmit(struct sk_buff *skb, dev_kfree_skb_any(skb); if (txb) { - int ret = (*ieee->hard_start_xmit) (txb, dev); + int ret = (*ieee->hard_start_xmit) (txb, dev, priority); if (ret == 0) { stats->tx_packets++; stats->tx_bytes += txb->payload_size; @@ -514,6 +514,7 @@ int ieee80211_tx_frame(struct ieee80211_ unsigned long flags; struct net_device_stats *stats = &ieee->stats; struct sk_buff *skb_frag; + int priority = -1; spin_lock_irqsave(&ieee->lock, flags); @@ -554,7 +555,7 @@ int ieee80211_tx_frame(struct ieee80211_ spin_unlock_irqrestore(&ieee->lock, flags); if (txb) { - if ((*ieee->hard_start_xmit) (txb, ieee->dev) == 0) { + if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) { stats->tx_packets++; stats->tx_bytes += txb->payload_size; return 0; |
From: James K. <jke...@li...> - 2005-09-13 23:30:12
|
Per the conversations with folks at OLS, the QoS layer in 802.11 drivers can now result in NETDEV_TX_BUSY being returned when the queue a packet is targetted for is full. To implement this, ieee80211_xmit will now call the driver's is_queue_full to determine if the current priority queue is full. If so, NETDEV_TX_BUSY is returned to the kernel and no processing is done on the frame. Signed-off-by: James Ketrenos <jke...@li...> --- net/ieee80211/ieee80211_tx.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) 4868637e29922d96e049a8817500477075bb87cc diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -253,6 +253,9 @@ int ieee80211_xmit(struct sk_buff *skb, int priority = skb->priority; int snapped = 0; + if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority)) + return NETDEV_TX_BUSY; + spin_lock_irqsave(&ieee->lock, flags); /* If there is no driver handler to take the TXB, dont' bother @@ -482,6 +485,14 @@ int ieee80211_xmit(struct sk_buff *skb, stats->tx_bytes += txb->payload_size; return 0; } + + if (ret == NETDEV_TX_BUSY) { + printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; " + "driver should report queue full via " + "ieee_device->is_queue_full.\n", + ieee->dev->name); + } + ieee80211_txb_free(txb); } |
From: James K. <jke...@li...> - 2005-09-13 23:29:12
|
This fixes several things: 1. TKIP encryption Originally, TKIP encryption issues msdu + mpdu encryption on every fragment. Change the behavior to msdu encryption on the whole packet, then mpdu encryption on every fragment. 2. Avoid repeated fragmentation when !host_encrypt. We only need do fragmentation when using host encryption. Otherwise we only need pass the whole packet to driver, letting driver do the fragmentation. 3. change the txb->payload_size to correct value FW will use this value to determine whether to do fragmentation. If we pass the wrong value, fw may cut on the wrong bound which will make decryption fail when we do host encryption. Signed-off-by: Hong Liu <liu...@in...> Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 2 include/net/ieee80211_crypt.h | 3 - net/ieee80211/ieee80211_crypt.c | 4 - net/ieee80211/ieee80211_crypt_ccmp.c | 4 - net/ieee80211/ieee80211_crypt_tkip.c | 5 + net/ieee80211/ieee80211_crypt_wep.c | 4 - net/ieee80211/ieee80211_module.c | 7 +- net/ieee80211/ieee80211_tx.c | 149 +++++++++++++++++++--------------- 8 files changed, 103 insertions(+), 75 deletions(-) 295b581fdd63ad211ce0ce4ecbef84c5c630543f diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -730,7 +730,9 @@ struct ieee80211_device { /* If the host performs {en,de}cryption, then set to 1 */ int host_encrypt; + int host_encrypt_msdu; int host_decrypt; + int host_open_frag; int ieee802_1x; /* is IEEE 802.1X used */ /* WPA data */ diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h --- a/include/net/ieee80211_crypt.h +++ b/include/net/ieee80211_crypt.h @@ -81,7 +81,8 @@ struct ieee80211_crypto_ops { * extra_postfix_len; encrypt need not use all this space, but * the result must start at the beginning of the buffer and correct * length must be returned */ - int extra_prefix_len, extra_postfix_len; + int extra_mpdu_prefix_len, extra_mpdu_postfix_len; + int extra_msdu_prefix_len, extra_msdu_postfix_len; struct module *owner; }; diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c --- a/net/ieee80211/ieee80211_crypt.c +++ b/net/ieee80211/ieee80211_crypt.c @@ -220,8 +220,8 @@ static struct ieee80211_crypto_ops ieee8 .decrypt_msdu = NULL, .set_key = NULL, .get_key = NULL, - .extra_prefix_len = 0, - .extra_postfix_len = 0, + .extra_mpdu_prefix_len = 0, + .extra_mpdu_postfix_len = 0, .owner = THIS_MODULE, }; diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -436,8 +436,8 @@ static struct ieee80211_crypto_ops ieee8 .set_key = ieee80211_ccmp_set_key, .get_key = ieee80211_ccmp_get_key, .print_stats = ieee80211_ccmp_print_stats, - .extra_prefix_len = CCMP_HDR_LEN, - .extra_postfix_len = CCMP_MIC_LEN, + .extra_mpdu_prefix_len = CCMP_HDR_LEN, + .extra_mpdu_postfix_len = CCMP_MIC_LEN, .owner = THIS_MODULE, }; diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -665,8 +665,9 @@ static struct ieee80211_crypto_ops ieee8 .set_key = ieee80211_tkip_set_key, .get_key = ieee80211_tkip_get_key, .print_stats = ieee80211_tkip_print_stats, - .extra_prefix_len = 4 + 4, /* IV + ExtIV */ - .extra_postfix_len = 8 + 4, /* MIC + ICV */ + .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */ + .extra_mpdu_postfix_len = 4, /* ICV */ + .extra_msdu_postfix_len = 8, /* MIC */ .owner = THIS_MODULE, }; diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c @@ -239,8 +239,8 @@ static struct ieee80211_crypto_ops ieee8 .set_key = prism2_wep_set_key, .get_key = prism2_wep_get_key, .print_stats = prism2_wep_print_stats, - .extra_prefix_len = 4, /* IV */ - .extra_postfix_len = 4, /* ICV */ + .extra_mpdu_prefix_len = 4, /* IV */ + .extra_mpdu_postfix_len = 4, /* ICV */ .owner = THIS_MODULE, }; diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -133,6 +133,12 @@ struct net_device *alloc_ieee80211(int s /* Default to enabling full open WEP with host based encrypt/decrypt */ ieee->host_encrypt = 1; ieee->host_decrypt = 1; + /* Host fragementation in Open mode. Default is enabled. + * Note: host fragmentation is always enabled if host encryption + * is enabled. For cards can do hardware encryption, they must do + * hardware fragmentation as well. So we don't need a variable + * like host_enc_frag. */ + ieee->host_open_frag = 1; ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ INIT_LIST_HEAD(&ieee->crypt_deinit_list); @@ -147,7 +153,6 @@ struct net_device *alloc_ieee80211(int s ieee->tkip_countermeasures = 0; ieee->drop_unencrypted = 0; ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; return dev; diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -128,7 +128,7 @@ payload of each frame is reduced to 492 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; -static inline int ieee80211_put_snap(u8 * data, u16 h_proto) +static inline int ieee80211_copy_snap(u8 * data, u16 h_proto) { struct ieee80211_snap_hdr *snap; u8 *oui; @@ -173,15 +173,9 @@ static inline int ieee80211_encrypt_frag #endif /* To encrypt, frame format is: * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ - - // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. - /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. */ atomic_inc(&crypt->refcnt); res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) + if (crypt->ops->encrypt_mpdu) res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); atomic_dec(&crypt->refcnt); @@ -236,7 +230,7 @@ static struct ieee80211_txb *ieee80211_a return txb; } -/* Incoming skb is converted to a txb which consist of +/* Incoming skb is converted to a txb which consists of * a block of 802.11 fragment packets (stored as skbs) */ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) { @@ -247,7 +241,7 @@ int ieee80211_xmit(struct sk_buff *skb, rts_required; unsigned long flags; struct net_device_stats *stats = &ieee->stats; - int ether_type, encrypt, host_encrypt; + int ether_type, encrypt, host_encrypt, host_encrypt_msdu; int bytes, fc, hdr_len; struct sk_buff *skb_frag; struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */ @@ -255,8 +249,9 @@ int ieee80211_xmit(struct sk_buff *skb, .seq_ctl = 0 }; u8 dest[ETH_ALEN], src[ETH_ALEN]; - struct ieee80211_crypt_data *crypt; + int priority = skb->priority; + int snapped = 0; spin_lock_irqsave(&ieee->lock, flags); @@ -280,6 +275,7 @@ int ieee80211_xmit(struct sk_buff *skb, encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && ieee->sec.encrypt; host_encrypt = ieee->host_encrypt && encrypt; + host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt; if (!encrypt && ieee->ieee802_1x && ieee->drop_unencrypted && ether_type != ETH_P_PAE) { @@ -305,14 +301,12 @@ int ieee80211_xmit(struct sk_buff *skb, if (ieee->iw_mode == IW_MODE_INFRA) { fc |= IEEE80211_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, - Addr3 = DA */ + /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */ memcpy(header.addr1, ieee->bssid, ETH_ALEN); memcpy(header.addr2, src, ETH_ALEN); memcpy(header.addr3, dest, ETH_ALEN); } else if (ieee->iw_mode == IW_MODE_ADHOC) { - /* not From/To DS: Addr1 = DA, Addr2 = SA, - Addr3 = BSSID */ + /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */ memcpy(header.addr1, dest, ETH_ALEN); memcpy(header.addr2, src, ETH_ALEN); memcpy(header.addr3, ieee->bssid, ETH_ALEN); @@ -320,42 +314,75 @@ int ieee80211_xmit(struct sk_buff *skb, header.frame_ctl = cpu_to_le16(fc); hdr_len = IEEE80211_3ADDR_LEN; - /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) */ - if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest)) - frag_size = MAX_FRAG_THRESHOLD; - else - frag_size = ieee->fts; - - /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account for - * it when determining the amount of payload space. */ - bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN; - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - bytes_per_frag -= IEEE80211_FCS_LEN; + /* Encrypt msdu first on the whole data packet. */ + if ((host_encrypt || host_encrypt_msdu) && + crypt && crypt->ops && crypt->ops->encrypt_msdu) { + int res = 0; + int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len + + crypt->ops->extra_msdu_postfix_len; + struct sk_buff *skb_new = dev_alloc_skb(len); + if (unlikely(!skb_new)) + goto failed; + skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len); + memcpy(skb_put(skb_new, hdr_len), &header, hdr_len); + snapped = 1; + ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)), + ether_type); + memcpy(skb_put(skb_new, skb->len), skb->data, skb->len); + res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv); + if (res < 0) { + IEEE80211_ERROR("msdu encryption failed\n"); + dev_kfree_skb_any(skb_new); + goto failed; + } + dev_kfree_skb_any(skb); + skb = skb_new; + bytes += crypt->ops->extra_msdu_prefix_len + + crypt->ops->extra_msdu_postfix_len; + skb_pull(skb, hdr_len); + } + + if (host_encrypt || ieee->host_open_frag) { + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) */ + if (is_multicast_ether_addr(dest)) + frag_size = MAX_FRAG_THRESHOLD; + else + frag_size = ieee->fts; + + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account + * for it when determining the amount of payload space. */ + bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN; + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + bytes_per_frag -= IEEE80211_FCS_LEN; - /* Each fragment may need to have room for encryptiong pre/postfix */ - if (host_encrypt) - bytes_per_frag -= crypt->ops->extra_prefix_len + - crypt->ops->extra_postfix_len; + /* Each fragment may need to have room for encryptiong + * pre/postfix */ + if (host_encrypt) + bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + + crypt->ops->extra_mpdu_postfix_len; - /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; + /* Number of fragments is the total + * bytes_per_frag / payload_per_fragment */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + } else { + nr_frags = 1; + bytes_per_frag = bytes_last_frag = bytes; + frag_size = bytes + IEEE80211_3ADDR_LEN; + } rts_required = (frag_size > ieee->rts && ieee->config & CFG_IEEE80211_RTS); if (rts_required) nr_frags++; - else - bytes_last_frag = bytes_per_frag; /* When we allocate the TXB we allocate enough space for the reserve * and full fragment bytes (bytes_per_frag doesn't include prefix, @@ -367,7 +394,11 @@ int ieee80211_xmit(struct sk_buff *skb, goto failed; } txb->encrypted = encrypt; - txb->payload_size = bytes; + if (host_encrypt) + txb->payload_size = frag_size * (nr_frags - 1) + + bytes_last_frag; + else + txb->payload_size = bytes; if (rts_required) { skb_frag = txb->fragments[0]; @@ -399,7 +430,8 @@ int ieee80211_xmit(struct sk_buff *skb, skb_frag = txb->fragments[i]; if (host_encrypt) - skb_reserve(skb_frag, crypt->ops->extra_prefix_len); + skb_reserve(skb_frag, + crypt->ops->extra_mpdu_prefix_len); frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len); @@ -416,11 +448,10 @@ int ieee80211_xmit(struct sk_buff *skb, bytes = bytes_last_frag; } - /* Put a SNAP header on the first fragment */ - if (i == 0) { - ieee80211_put_snap(skb_put - (skb_frag, SNAP_SIZE + sizeof(u16)), - ether_type); + if (i == 0 && !snapped) { + ieee80211_copy_snap(skb_put + (skb_frag, SNAP_SIZE + sizeof(u16)), + ether_type); bytes -= SNAP_SIZE + sizeof(u16); } @@ -434,19 +465,6 @@ int ieee80211_xmit(struct sk_buff *skb, if (host_encrypt) ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); - /* ipw2200/2915 Hardware encryption doesn't support TKIP MIC */ - if (!ieee->host_encrypt && encrypt && - (ieee->sec.level == SEC_LEVEL_2) && - crypt && crypt->ops && crypt->ops->encrypt_msdu) { - int res = 0; - res = crypt->ops->encrypt_msdu(skb_frag, hdr_len, - crypt->priv); - if (res < 0) { - IEEE80211_ERROR("TKIP MIC encryption failed\n"); - goto failed; - } - } - if (ieee->config & (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) skb_put(skb_frag, 4); @@ -458,7 +476,8 @@ int ieee80211_xmit(struct sk_buff *skb, dev_kfree_skb_any(skb); if (txb) { - if ((*ieee->hard_start_xmit) (txb, dev) == 0) { + int ret = (*ieee->hard_start_xmit) (txb, dev); + if (ret == 0) { stats->tx_packets++; stats->tx_bytes += txb->payload_size; return 0; |
From: James K. <jke...@li...> - 2005-09-13 23:28:11
|
Added ieee80211_tx_frame to convert generic 802.11 data frames into txbs for transmission. Added several purpose specific callbacks (handle_assoc, handle_auth, etc.) which the driver can register with for being notified on reception of various frame elements. Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 23 +++++++++++++++ net/ieee80211/ieee80211_rx.c | 58 ++++++++++++++++++++++++++++---------- net/ieee80211/ieee80211_tx.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 15 deletions(-) 92366419f4fafbb4720a99d7cd61f1351395c085 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -775,6 +775,27 @@ struct ieee80211_device { int (*hard_start_xmit) (struct ieee80211_txb * txb, struct net_device * dev); int (*reset_port) (struct net_device * dev); + int (*is_queue_full) (struct net_device * dev, int pri); + + /* Typical STA methods */ + int (*handle_auth) (struct net_device * dev, + struct ieee80211_auth * auth); + int (*handle_disassoc) (struct net_device * dev, + struct ieee80211_disassoc * assoc); + int (*handle_beacon) (struct net_device * dev, + struct ieee80211_beacon * beacon, + struct ieee80211_network * network); + int (*handle_probe_response) (struct net_device * dev, + struct ieee80211_probe_response * resp, + struct ieee80211_network * network); + int (*handle_assoc_response) (struct net_device * dev, + struct ieee80211_assoc_response * resp, + struct ieee80211_network * network); + + /* Typical AP methods */ + int (*handle_assoc_request) (struct net_device * dev); + int (*handle_reassoc_request) (struct net_device * dev, + struct ieee80211_reassoc_request * req); /* This must be the last item so that it points to the data * allocated beyond this structure by alloc_ieee80211 */ @@ -883,6 +904,8 @@ extern int ieee80211_set_encryption(stru /* ieee80211_tx.c */ extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev); extern void ieee80211_txb_free(struct ieee80211_txb *); +extern int ieee80211_tx_frame(struct ieee80211_device *ieee, + struct ieee80211_hdr *frame, int len); /* ieee80211_rx.c */ extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1040,12 +1040,18 @@ static inline void update_network(struct /* dst->last_associate is not overwritten */ } +static inline int is_beacon(int fc) +{ + return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON); +} + static inline void ieee80211_process_probe_response(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_rx_stats *stats) { + struct net_device *dev = ieee->dev; struct ieee80211_network network; struct ieee80211_network *target; struct ieee80211_network *oldest = NULL; @@ -1081,11 +1087,10 @@ static inline void ieee80211_process_pro escape_essid(info_element->data, info_element->len), MAC_ARG(beacon->header.addr3), - WLAN_FC_GET_STYPE(le16_to_cpu - (beacon->header. - frame_ctl)) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); + is_beacon(le16_to_cpu + (beacon->header. + frame_ctl)) ? + "BEACON" : "PROBE RESPONSE"); return; } @@ -1134,11 +1139,10 @@ static inline void ieee80211_process_pro escape_essid(network.ssid, network.ssid_len), MAC_ARG(network.bssid), - WLAN_FC_GET_STYPE(le16_to_cpu - (beacon->header. - frame_ctl)) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); + is_beacon(le16_to_cpu + (beacon->header. + frame_ctl)) ? + "BEACON" : "PROBE RESPONSE"); #endif memcpy(target, &network, sizeof(*target)); list_add_tail(&target->list, &ieee->network_list); @@ -1147,15 +1151,22 @@ static inline void ieee80211_process_pro escape_essid(target->ssid, target->ssid_len), MAC_ARG(target->bssid), - WLAN_FC_GET_STYPE(le16_to_cpu - (beacon->header. - frame_ctl)) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); + is_beacon(le16_to_cpu + (beacon->header. + frame_ctl)) ? + "BEACON" : "PROBE RESPONSE"); update_network(target, &network); } spin_unlock_irqrestore(&ieee->lock, flags); + + if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) { + if (ieee->handle_beacon != NULL) + ieee->handle_beacon(dev, beacon, &network); + } else { + if (ieee->handle_probe_response != NULL) + ieee->handle_probe_response(dev, beacon, &network); + } } void ieee80211_rx_mgt(struct ieee80211_device *ieee, @@ -1196,6 +1207,23 @@ void ieee80211_rx_mgt(struct ieee80211_d ieee80211_probe_response *) header, stats); break; + case IEEE80211_STYPE_AUTH: + + IEEE80211_DEBUG_MGMT("recieved auth (%d)\n", + WLAN_FC_GET_STYPE(le16_to_cpu + (header->frame_ctl))); + + if (ieee->handle_auth != NULL) + ieee->handle_auth(ieee->dev, + (struct ieee80211_auth *)header); + break; + + case IEEE80211_STYPE_DISASSOC: + if (ieee->handle_disassoc != NULL) + ieee->handle_disassoc(ieee->dev, + (struct ieee80211_disassoc *) + header); + break; default: IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n", diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -473,7 +473,71 @@ int ieee80211_xmit(struct sk_buff *skb, netif_stop_queue(dev); stats->tx_errors++; return 1; +} + +/* Incoming 802.11 strucure is converted to a TXB + * a block of 802.11 fragment packets (stored as skbs) */ +int ieee80211_tx_frame(struct ieee80211_device *ieee, + struct ieee80211_hdr *frame, int len) +{ + struct ieee80211_txb *txb = NULL; + unsigned long flags; + struct net_device_stats *stats = &ieee->stats; + struct sk_buff *skb_frag; + + spin_lock_irqsave(&ieee->lock, flags); + + /* If there is no driver handler to take the TXB, dont' bother + * creating it... */ + if (!ieee->hard_start_xmit) { + printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name); + goto success; + } + + if (unlikely(len < 24)) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, len); + goto success; + } + + /* When we allocate the TXB we allocate enough space for the reserve + * and full fragment bytes (bytes_per_frag doesn't include prefix, + * postfix, header, FCS, etc.) */ + txb = ieee80211_alloc_txb(1, len, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + txb->encrypted = 0; + txb->payload_size = len; + + skb_frag = txb->fragments[0]; + memcpy(skb_put(skb_frag, len), frame, len); + + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + skb_put(skb_frag, 4); + + success: + spin_unlock_irqrestore(&ieee->lock, flags); + + if (txb) { + if ((*ieee->hard_start_xmit) (txb, ieee->dev) == 0) { + stats->tx_packets++; + stats->tx_bytes += txb->payload_size; + return 0; + } + ieee80211_txb_free(txb); + } + return 0; + + failed: + spin_unlock_irqrestore(&ieee->lock, flags); + stats->tx_errors++; + return 1; } +EXPORT_SYMBOL(ieee80211_tx_frame); EXPORT_SYMBOL(ieee80211_txb_free); |
From: James K. <jke...@li...> - 2005-09-13 22:55:30
|
This patch adds support for the creation of RTS packets when the config flag CFG_IEEE80211_RTS has been set. Signed-Off-By: Ivo van Doorn <Iv...@gm...> Signed-off-by: James Ketrenos <jke...@li...> --- include/net/ieee80211.h | 2 ++ net/ieee80211/ieee80211_module.c | 1 + net/ieee80211/ieee80211_tx.c | 41 +++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) 027b1c24310778280a43bfe0c494c22616834cf4 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -696,6 +696,7 @@ enum ieee80211_state { #define CFG_IEEE80211_RESERVE_FCS (1<<0) #define CFG_IEEE80211_COMPUTE_FCS (1<<1) +#define CFG_IEEE80211_RTS (1<<2) struct ieee80211_device { struct net_device *dev; @@ -753,6 +754,7 @@ struct ieee80211_device { struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN]; unsigned int frag_next_idx; u16 fts; /* Fragmentation Threshold */ + u16 rts; /* RTS threshold */ /* Association info */ u8 bssid[ETH_ALEN]; diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -126,6 +126,7 @@ struct net_device *alloc_ieee80211(int s /* Default fragmentation threshold is maximum payload size */ ieee->fts = DEFAULT_FTS; + ieee->rts = DEFAULT_FTS; ieee->scan_age = DEFAULT_MAX_SCAN_AGE; ieee->open_wep = 1; diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -236,13 +236,15 @@ static struct ieee80211_txb *ieee80211_a return txb; } -/* SKBs are added to the ieee->tx_queue. */ +/* Incoming skb is converted to a txb which consist of + * a block of 802.11 fragment packets (stored as skbs) */ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) { struct ieee80211_device *ieee = netdev_priv(dev); struct ieee80211_txb *txb = NULL; struct ieee80211_hdr_3addr *frag_hdr; - int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size, + rts_required; unsigned long flags; struct net_device_stats *stats = &ieee->stats; int ether_type, encrypt, host_encrypt; @@ -348,6 +350,13 @@ int ieee80211_xmit(struct sk_buff *skb, else bytes_last_frag = bytes_per_frag; + rts_required = (frag_size > ieee->rts + && ieee->config & CFG_IEEE80211_RTS); + if (rts_required) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + /* When we allocate the TXB we allocate enough space for the reserve * and full fragment bytes (bytes_per_frag doesn't include prefix, * postfix, header, FCS, etc.) */ @@ -360,7 +369,33 @@ int ieee80211_xmit(struct sk_buff *skb, txb->encrypted = encrypt; txb->payload_size = bytes; - for (i = 0; i < nr_frags; i++) { + if (rts_required) { + skb_frag = txb->fragments[0]; + frag_hdr = + (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len); + + /* + * Set header frame_ctl to the RTS. + */ + header.frame_ctl = + cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); + memcpy(frag_hdr, &header, hdr_len); + + /* + * Restore header frame_ctl to the original data setting. + */ + header.frame_ctl = cpu_to_le16(fc); + + if (ieee->config & + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) + skb_put(skb_frag, 4); + + txb->rts_included = 1; + i = 1; + } else + i = 0; + + for (; i < nr_frags; i++) { skb_frag = txb->fragments[i]; if (host_encrypt) |
From: James K. <jke...@li...> - 2005-09-13 22:54:29
|
Fixed a stray struct ieee80211_hdr usage Signed-off-by: James Ketrenos <jke...@li...> --- net/ieee80211/ieee80211_rx.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) 17c83ce6dee44783ae4c65ed0eb3bd515a58e0cd diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_ca if (frag == 0) { /* Reserve enough space to fit maximum frame length */ skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct ieee80211_hdr) + + sizeof(struct ieee80211_hdr_4addr) + 8 /* LLC */ + 2 /* alignment */ + 8 /* WEP */ + ETH_ALEN /* WDS */ ); |
From: James K. <jke...@li...> - 2005-09-13 22:53:19
|
Renamed ieee80211_hdr to ieee80211_hdr_4addr and modified ieee80211_hdr to just contain the frame_ctrl and duration_id. Changed uses of ieee80211_hdr to ieee80211_hdr_4addr or ieee80211_hdr_3addr based on what was expected for that portion of code. Signed-off-by: James Ketrenos <jke...@li...> NOTE: This requires changing driver's that use ieee80211_hdr to use the appropriate structure. --- include/net/ieee80211.h | 117 ++++++++++++++++++++++++++-------- net/ieee80211/ieee80211_crypt_ccmp.c | 10 +-- net/ieee80211/ieee80211_crypt_tkip.c | 27 ++++---- net/ieee80211/ieee80211_rx.c | 30 ++++----- net/ieee80211/ieee80211_tx.c | 11 ++- 5 files changed, 130 insertions(+), 65 deletions(-) f8ab44d00fb0d51bc34f1a2716dd2340fd82f042 diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -39,33 +39,13 @@ represents the 2304 bytes of real data, plus a possible 8 bytes of WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ -#define IEEE80211_HLEN 30 -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -struct ieee80211_hdr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; -} __attribute__ ((packed)); - #define IEEE80211_1ADDR_LEN 10 #define IEEE80211_2ADDR_LEN 16 #define IEEE80211_3ADDR_LEN 24 #define IEEE80211_4ADDR_LEN 30 #define IEEE80211_FCS_LEN 4 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) #define MIN_FRAG_THRESHOLD 256U #define MAX_FRAG_THRESHOLD 2346U @@ -521,6 +501,51 @@ enum ieee80211_mfie { MFIE_TYPE_GENERIC = 221, }; +/* Minimal header; can be used for passing 802.11 frames with sufficient + * information to determine what type of underlying data type is actually + * stored in the data. */ +struct ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_1addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_2addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 payload[0]; +} __attribute__ ((packed)); + +struct ieee80211_hdr_4addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; +} __attribute__ ((packed)); + struct ieee80211_info_element { u8 id; u8 len; @@ -544,7 +569,7 @@ struct ieee80211_info_element { u16 status; */ -struct ieee80211_authentication { +struct ieee80211_auth { struct ieee80211_hdr_3addr header; __le16 algorithm; __le16 transaction; @@ -552,6 +577,17 @@ struct ieee80211_authentication { struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); +struct ieee80211_disassoc { + struct ieee80211_hdr_3addr header; + u16 reason_code; + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_hdr_3addr header; + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + struct ieee80211_probe_response { struct ieee80211_hdr_3addr header; u32 time_stamp[2]; @@ -560,14 +596,25 @@ struct ieee80211_probe_response { struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); -struct ieee80211_assoc_request_frame { +/* Alias beacon for probe_response */ +#define ieee80211_beacon ieee80211_probe_response + +struct ieee80211_assoc_request { + struct ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + struct ieee80211_info_element info_element[0]; +} __attribute__ ((packed)); + +struct ieee80211_reassoc_request { + struct ieee80211_hdr_3addr header; __le16 capability; __le16 listen_interval; u8 current_ap[ETH_ALEN]; struct ieee80211_info_element info_element[0]; } __attribute__ ((packed)); -struct ieee80211_assoc_response_frame { +struct ieee80211_assoc_response { struct ieee80211_hdr_3addr header; __le16 capability; __le16 status; @@ -578,7 +625,8 @@ struct ieee80211_assoc_response_frame { struct ieee80211_txb { u8 nr_frags; u8 encrypted; - u16 reserved; + u8 rts_included; + u8 reserved; u16 frag_size; u16 payload_size; struct sk_buff *fragments[0]; @@ -809,6 +857,21 @@ extern inline int ieee80211_get_hdrlen(u return hdrlen; } +extern inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) +{ + switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { + case IEEE80211_1ADDR_LEN: + return ((struct ieee80211_hdr_1addr *)hdr)->payload; + case IEEE80211_2ADDR_LEN: + return ((struct ieee80211_hdr_2addr *)hdr)->payload; + case IEEE80211_3ADDR_LEN: + return ((struct ieee80211_hdr_3addr *)hdr)->payload; + case IEEE80211_4ADDR_LEN: + return ((struct ieee80211_hdr_4addr *)hdr)->payload; + } + +} + /* ieee80211.c */ extern void free_ieee80211(struct net_device *dev); extern struct net_device *alloc_ieee80211(int sizeof_priv); @@ -823,7 +886,7 @@ extern void ieee80211_txb_free(struct ie extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats); extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr *header, + struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats); /* ieee80211_wx.c */ diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -119,7 +119,7 @@ static inline void xor_block(u8 * b, u8 } static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct ieee80211_hdr *hdr, + struct ieee80211_hdr_4addr *hdr, u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0) { u8 *pos, qc = 0; @@ -196,7 +196,7 @@ static int ieee80211_ccmp_encrypt(struct struct ieee80211_ccmp_data *key = priv; int data_len, i, blocks, last, len; u8 *pos, *mic; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_4addr *hdr; u8 *b0 = key->tx_b0; u8 *b = key->tx_b; u8 *e = key->tx_e; @@ -229,7 +229,7 @@ static int ieee80211_ccmp_encrypt(struct *pos++ = key->tx_pn[1]; *pos++ = key->tx_pn[0]; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; @@ -258,7 +258,7 @@ static int ieee80211_ccmp_decrypt(struct { struct ieee80211_ccmp_data *key = priv; u8 keyidx, *pos; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_4addr *hdr; u8 *b0 = key->rx_b0; u8 *b = key->rx_b; u8 *a = key->rx_a; @@ -272,7 +272,7 @@ static int ieee80211_ccmp_decrypt(struct return -1; } - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -260,7 +260,7 @@ static int ieee80211_tkip_encrypt(struct struct ieee80211_tkip_data *tkey = priv; int len; u8 rc4key[16], *pos, *icv; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_4addr *hdr; u32 crc; struct scatterlist sg; @@ -268,7 +268,7 @@ static int ieee80211_tkip_encrypt(struct skb->len < hdr_len) return -1; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, tkey->tx_iv32); @@ -319,7 +319,7 @@ static int ieee80211_tkip_decrypt(struct u8 keyidx, *pos; u32 iv32; u16 iv16; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_4addr *hdr; u8 icv[4]; u32 crc; struct scatterlist sg; @@ -328,7 +328,7 @@ static int ieee80211_tkip_decrypt(struct if (skb->len < hdr_len + 8 + 4) return -1; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { @@ -441,9 +441,9 @@ static int michael_mic(struct ieee80211_ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) { - struct ieee80211_hdr *hdr11; + struct ieee80211_hdr_4addr *hdr11; - hdr11 = (struct ieee80211_hdr *)skb->data; + hdr11 = (struct ieee80211_hdr_4addr *)skb->data; switch (le16_to_cpu(hdr11->frame_ctl) & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { case IEEE80211_FCTL_TODS: @@ -492,7 +492,8 @@ static int ieee80211_michael_mic_add(str #if WIRELESS_EXT >= 18 static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr *hdr, int keyidx) + struct ieee80211_hdr_4addr *hdr, + int keyidx) { union iwreq_data wrqu; struct iw_michaelmicfailure ev; @@ -512,7 +513,8 @@ static void ieee80211_michael_mic_failur } #elif WIRELESS_EXT >= 15 static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr *hdr, int keyidx) + struct ieee80211_hdr_4addr *hdr, + int keyidx) { union iwreq_data wrqu; char buf[128]; @@ -526,9 +528,8 @@ static void ieee80211_michael_mic_failur wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); } #else /* WIRELESS_EXT >= 15 */ -static inline void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr *hdr, - int keyidx) +static inline void ieee80211_michael_mic_failure(struct net_device *dev, struct ieee80211_hdr_4addr + *hdr, int keyidx) { } #endif /* WIRELESS_EXT >= 15 */ @@ -547,8 +548,8 @@ static int ieee80211_michael_mic_verify( skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) return -1; if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_hdr_4addr *hdr; + hdr = (struct ieee80211_hdr_4addr *)skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " "MSDU from " MAC_FMT " keyidx=%d\n", skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2), diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -87,7 +87,7 @@ static struct ieee80211_frag_entry *ieee /* Called only as a tasklet (software IRQ) */ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee, - struct ieee80211_hdr *hdr) + struct ieee80211_hdr_4addr *hdr) { struct sk_buff *skb = NULL; u16 sc; @@ -138,7 +138,7 @@ static struct sk_buff *ieee80211_frag_ca /* Called only as a tasklet (software IRQ) */ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, - struct ieee80211_hdr *hdr) + struct ieee80211_hdr_4addr *hdr) { u16 sc; unsigned int seq; @@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211 ieee->dev->name); return 0; /* - hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *) + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *) skb->data);*/ } @@ -232,13 +232,13 @@ static int ieee80211_is_eapol_frame(stru { struct net_device *dev = ieee->dev; u16 fc, ethertype; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_3addr *hdr; u8 *pos; if (skb->len < 24) return 0; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_3addr *)skb->data; fc = le16_to_cpu(hdr->frame_ctl); /* check that the frame is unicast frame to us */ @@ -271,13 +271,13 @@ static inline int ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_crypt_data *crypt) { - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_3addr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) return 0; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_3addr *)skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); #ifdef CONFIG_IEEE80211_CRYPT_TKIP @@ -314,13 +314,13 @@ ieee80211_rx_frame_decrypt_msdu(struct i struct sk_buff *skb, int keyidx, struct ieee80211_crypt_data *crypt) { - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_3addr *hdr; int res, hdrlen; if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) return 0; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_3addr *)skb->data; hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); atomic_inc(&crypt->refcnt); @@ -343,7 +343,7 @@ int ieee80211_rx(struct ieee80211_device struct ieee80211_rx_stats *rx_stats) { struct net_device *dev = ieee->dev; - struct ieee80211_hdr *hdr; + struct ieee80211_hdr_4addr *hdr; size_t hdrlen; u16 fc, type, stype, sc; struct net_device_stats *stats; @@ -363,7 +363,7 @@ int ieee80211_rx(struct ieee80211_device struct ieee80211_crypt_data *crypt = NULL; int keyidx = 0; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; stats = &ieee->stats; if (skb->len < 10) { @@ -563,7 +563,7 @@ int ieee80211_rx(struct ieee80211_device (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) goto rx_dropped; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; /* skb: hdr + (possibly fragmented) plaintext payload */ // PR: FIXME: hostap has additional conditions in the "if" below: @@ -617,7 +617,7 @@ int ieee80211_rx(struct ieee80211_device /* this was the last fragment and the frame will be * delivered, so remove skb from fragment cache */ skb = frag_skb; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; ieee80211_frag_cache_invalidate(ieee, hdr); } @@ -627,7 +627,7 @@ int ieee80211_rx(struct ieee80211_device ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) goto rx_dropped; - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (struct ieee80211_hdr_4addr *)skb->data; if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) { if ( /*ieee->ieee802_1x && */ ieee80211_is_eapol_frame(ieee, skb)) { @@ -1159,7 +1159,7 @@ static inline void ieee80211_process_pro } void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr *header, + struct ieee80211_hdr_4addr *header, struct ieee80211_rx_stats *stats) { switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) { diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -158,11 +158,11 @@ static inline int ieee80211_encrypt_frag int res; #ifdef CONFIG_IEEE80211_CRYPT_TKIP - struct ieee80211_hdr *header; + struct ieee80211_hdr_3addr *header; if (ieee->tkip_countermeasures && crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - header = (struct ieee80211_hdr *)frag->data; + header = (struct ieee80211_hdr_3addr *)frag->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " "TX packet to " MAC_FMT "\n", @@ -241,14 +241,14 @@ int ieee80211_xmit(struct sk_buff *skb, { struct ieee80211_device *ieee = netdev_priv(dev); struct ieee80211_txb *txb = NULL; - struct ieee80211_hdr *frag_hdr; + struct ieee80211_hdr_3addr *frag_hdr; int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; unsigned long flags; struct net_device_stats *stats = &ieee->stats; int ether_type, encrypt, host_encrypt; int bytes, fc, hdr_len; struct sk_buff *skb_frag; - struct ieee80211_hdr header = { /* Ensure zero initialized */ + struct ieee80211_hdr_3addr header = { /* Ensure zero initialized */ .duration_id = 0, .seq_ctl = 0 }; @@ -366,7 +366,8 @@ int ieee80211_xmit(struct sk_buff *skb, if (host_encrypt) skb_reserve(skb_frag, crypt->ops->extra_prefix_len); - frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len); + frag_hdr = + (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len); memcpy(frag_hdr, &header, hdr_len); /* If this is not the last fragment, then add the MOREFRAGS |