fix up hostapd for mac80211
[librecmc/librecmc.git] / package / mac80211 / patches / 015-hostapd-ioctl-hw-features.patch
1 ---
2  net/mac80211/ieee80211_ioctl.c |  102 +++++++++++++++++++++++++++++++++++++++++
3  1 file changed, 102 insertions(+)
4
5 --- everything.orig/net/mac80211/ieee80211_ioctl.c      2007-11-07 13:19:32.281514919 +0100
6 +++ everything/net/mac80211/ieee80211_ioctl.c   2007-11-07 13:19:33.681513453 +0100
7 @@ -125,6 +125,105 @@ static int ieee80211_ioctl_siwgenie(stru
8         return -EOPNOTSUPP;
9  }
10  
11 +/*
12 + * Wow. This ioctl interface is such crap, it's tied
13 + * to internal definitions. I hope it dies soon.
14 + */
15 +static int mode_to_hostapd_mode(enum ieee80211_phymode mode)
16 +{
17 +       switch (mode) {
18 +       case MODE_IEEE80211A:
19 +               return 0;
20 +       case MODE_IEEE80211B:
21 +               return 1;
22 +       case MODE_IEEE80211G:
23 +               return 3;
24 +       case NUM_IEEE80211_MODES:
25 +               WARN_ON(1);
26 +               break;
27 +       }
28 +       WARN_ON(1);
29 +       return -1;
30 +}
31 +
32 +static int channel_flags_to_hostapd_flags(int flags)
33 +{
34 +       int res = 0;
35 +
36 +       if (flags & IEEE80211_CHAN_W_SCAN)
37 +               res |= 1;
38 +       if (flags & IEEE80211_CHAN_W_ACTIVE_SCAN)
39 +               res |= 2;
40 +       if (flags & IEEE80211_CHAN_W_IBSS)
41 +               res |= 4;
42 +
43 +       return res;
44 +}
45 +
46 +struct ieee80211_channel_data {
47 +       short chan; /* channel number (IEEE 802.11) */
48 +       short freq; /* frequency in MHz */
49 +       int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */
50 +};
51 +
52 +struct ieee80211_rate_data {
53 +       int rate; /* rate in 100 kbps */
54 +       int flags; /* IEEE80211_RATE_ flags */
55 +};
56 +
57 +static int ieee80211_ioctl_get_hw_features(struct net_device *dev,
58 +                                          struct prism2_hostapd_param *param,
59 +                                          int param_len)
60 +{
61 +       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
62 +       u8 *pos = param->u.hw_features.data;
63 +       int left = param_len - (pos - (u8 *) param);
64 +       int i;
65 +       struct hostapd_ioctl_hw_modes_hdr *hdr;
66 +       struct ieee80211_rate_data *rate;
67 +       struct ieee80211_channel_data *chan;
68 +       struct ieee80211_hw_mode *mode;
69 +
70 +       param->u.hw_features.flags = 0;
71 +
72 +       param->u.hw_features.num_modes = 0;
73 +       list_for_each_entry(mode, &local->modes_list, list) {
74 +               int clen, rlen;
75 +
76 +               param->u.hw_features.num_modes++;
77 +               clen =
78 +                   mode->num_channels * sizeof(struct ieee80211_channel_data);
79 +               rlen = mode->num_rates * sizeof(struct ieee80211_rate_data);
80 +               if (left < sizeof(*hdr) + clen + rlen)
81 +                       return -E2BIG;
82 +               left -= sizeof(*hdr) + clen + rlen;
83 +
84 +               hdr = (struct hostapd_ioctl_hw_modes_hdr *)pos;
85 +               hdr->mode = mode_to_hostapd_mode(mode->mode);
86 +               hdr->num_channels = mode->num_channels;
87 +               hdr->num_rates = mode->num_rates;
88 +
89 +               pos = (u8 *) (hdr + 1);
90 +               chan = (struct ieee80211_channel_data *)pos;
91 +               for (i = 0; i < mode->num_channels; i++) {
92 +                       chan[i].chan = mode->channels[i].chan;
93 +                       chan[i].freq = mode->channels[i].freq;
94 +                       chan[i].flag = channel_flags_to_hostapd_flags(
95 +                                               mode->channels[i].flag);
96 +               }
97 +               pos += clen;
98 +
99 +               rate = (struct ieee80211_rate_data *)pos;
100 +               for (i = 0; i < mode->num_rates; i++) {
101 +                       rate[i].rate = mode->rates[i].rate;
102 +                       rate[i].flags = mode->rates[i].flags;
103 +               }
104 +               pos += rlen;
105 +       }
106 +
107 +       return 0;
108 +}
109 +
110  
111  static int ieee80211_ioctl_priv_hostapd(struct net_device *dev,
112                                         struct iw_point *p)
113 @@ -151,6 +250,9 @@ static int ieee80211_ioctl_priv_hostapd(
114         }
115  
116         switch (param->cmd) {
117 +       case PRISM2_HOSTAPD_GET_HW_FEATURES:
118 +               ret = ieee80211_ioctl_get_hw_features(dev, param, p->length);
119 +               break;
120         default:
121                 ret = -EOPNOTSUPP;
122                 break;