~ubuntu-branches/debian/sid/acx100/sid

« back to all changes in this revision

Viewing changes to src/setrate.c

  • Committer: Bazaar Package Importer
  • Author(s): Miguel Gea Milvaques
  • Date: 2005-04-13 23:36:11 UTC
  • Revision ID: james.westby@ubuntu.com-20050413233611-5ec8mnua3b9k3t4u
Tags: upstream-0.2.0pre8+52
ImportĀ upstreamĀ versionĀ 0.2.0pre8+52

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* TODO: stop #including, move into wireless.c
 
2
 * until then, keep in sync copies in prism54/ and acx111/ dirs
 
3
 * code+data size: less than 1k */
 
4
 
 
5
enum {
 
6
        DOT11_RATE_1,
 
7
        DOT11_RATE_2,
 
8
        DOT11_RATE_5,
 
9
        DOT11_RATE_11,
 
10
        DOT11_RATE_22,
 
11
        DOT11_RATE_33,
 
12
        DOT11_RATE_6,
 
13
        DOT11_RATE_9,
 
14
        DOT11_RATE_12,
 
15
        DOT11_RATE_18,
 
16
        DOT11_RATE_24,
 
17
        DOT11_RATE_36,
 
18
        DOT11_RATE_48,
 
19
        DOT11_RATE_54,
 
20
};
 
21
enum {
 
22
        DOT11_MOD_DBPSK,
 
23
        DOT11_MOD_DQPSK,
 
24
        DOT11_MOD_CCK,
 
25
        DOT11_MOD_OFDM,
 
26
        DOT11_MOD_CCKOFDM,
 
27
        DOT11_MOD_PBCC,
 
28
};
 
29
static const u8 ratelist[] = { 1,2,5,11,22,33,6,9,12,18,24,36,48,54 };
 
30
static const u8 dot11ratebyte[] = { 1*2,2*2,11,11*2,22*2,33*2,6*2,9*2,12*2,18*2,24*2,36*2,48*2,54*2 };
 
31
static const u8 default_modulation[] = {
 
32
        DOT11_MOD_DBPSK,
 
33
        DOT11_MOD_DQPSK,
 
34
        DOT11_MOD_CCK,
 
35
        DOT11_MOD_CCK,
 
36
        DOT11_MOD_PBCC,
 
37
        DOT11_MOD_PBCC,
 
38
        DOT11_MOD_OFDM,
 
39
        DOT11_MOD_OFDM,
 
40
        DOT11_MOD_OFDM,
 
41
        DOT11_MOD_OFDM,
 
42
        DOT11_MOD_OFDM,
 
43
        DOT11_MOD_OFDM,
 
44
        DOT11_MOD_OFDM,
 
45
        DOT11_MOD_OFDM,
 
46
};
 
47
 
 
48
static /* TODO: remove 'static' when moved to wireless.c */
 
49
int
 
50
rate_mbit2enum(int n) {
 
51
        int i=0;
 
52
        while(i<sizeof(ratelist)) {
 
53
                if(n==ratelist[i]) return i;
 
54
                i++;
 
55
        }
 
56
        return -EINVAL;
 
57
}
 
58
 
 
59
static int
 
60
get_modulation(int r_enum, char suffix) {
 
61
        if(suffix==',' || suffix==' ' || suffix=='\0') {
 
62
                /* could shorten default_mod by 8 bytes:
 
63
                if(r_enum>=DOT11_RATE_6) return DOT11_MOD_OFDM; */
 
64
                return default_modulation[r_enum];
 
65
        }
 
66
        if(suffix=='c') {
 
67
                if(r_enum<DOT11_RATE_5 || r_enum>DOT11_RATE_11) return -EINVAL;
 
68
                return DOT11_MOD_CCK;
 
69
        }
 
70
        if(suffix=='p') {
 
71
                if(r_enum<DOT11_RATE_5 || r_enum>DOT11_RATE_33) return -EINVAL;
 
72
                return DOT11_MOD_PBCC;
 
73
        }
 
74
        if(suffix=='o') {
 
75
                if(r_enum<DOT11_RATE_6) return -EINVAL;
 
76
                return DOT11_MOD_OFDM;
 
77
        }
 
78
        if(suffix=='d') {
 
79
                if(r_enum<DOT11_RATE_6) return -EINVAL;
 
80
                return DOT11_MOD_CCKOFDM;
 
81
        }
 
82
        return -EINVAL;
 
83
}
 
84
 
 
85
#if UNUSED
 
86
static int
 
87
fill_ratevector(const char **pstr, u8 *vector, int size,
 
88
                int (*supported)(int mbit, int mod, void *opaque), void *opaque, int or_mask)
 
89
{
 
90
        unsigned long rate_mbit;
 
91
        int rate_enum,mod;
 
92
        const char *str = *pstr;
 
93
        char c;
 
94
 
 
95
        do {
 
96
                rate_mbit = simple_strtoul(str, (char**)&str, 10);
 
97
                if(rate_mbit>INT_MAX) return -EINVAL;
 
98
 
 
99
                rate_enum = rate_mbit2enum(rate_mbit);
 
100
                if(rate_enum<0) return rate_enum;
 
101
                
 
102
                c = *str;
 
103
                mod = get_modulation(rate_enum, c);
 
104
                if(mod<0) return mod;
 
105
                
 
106
                if(c>='a' && c<='z') c = *++str;
 
107
                if(c!=',' && c!=' ' && c!='\0') return -EINVAL;
 
108
                
 
109
                if(supported) {
 
110
                        int r = supported(rate_mbit, mod, opaque);
 
111
                        if(r) return r;
 
112
                }
 
113
 
 
114
                *vector++ = dot11ratebyte[rate_enum] | or_mask;
 
115
                
 
116
                size--;
 
117
                str++;
 
118
        } while(size>0 && c==',');
 
119
        
 
120
        if(size<1) return -E2BIG;
 
121
        *vector=0; /* TODO: sort, remove dups? */
 
122
        
 
123
        *pstr = str-1;
 
124
        return 0;
 
125
}
 
126
 
 
127
static /* TODO: remove 'static' when moved to wireless.c */
 
128
int
 
129
fill_ratevectors(const char *str, u8 *brate, u8 *orate, int size,
 
130
                int (*supported)(int mbit, int mod, void *opaque), void *opaque)
 
131
{
 
132
        int r;
 
133
        
 
134
        r = fill_ratevector(&str, brate, size, supported, opaque, 0x80);
 
135
        if(r) return r;
 
136
 
 
137
        orate[0] = 0;
 
138
        if(*str==' ') {
 
139
                str++;
 
140
                r = fill_ratevector(&str, orate, size, supported, opaque, 0);
 
141
                if(r) return r;
 
142
                /* TODO: sanitize, e.g. remove/error on rates already in basic rate set? */
 
143
        }
 
144
        if(*str)
 
145
                return -EINVAL;
 
146
 
 
147
        return 0;
 
148
}
 
149
#endif
 
150
 
 
151
/* TODO: use u64 masks? */
 
152
 
 
153
static int
 
154
fill_ratemask(const char **pstr, u32* mask,
 
155
                int (*supported)(int mbit, int mod,void *opaque),
 
156
                u32 (*gen_mask)(int mbit, int mod,void *opaque),
 
157
                void *opaque)
 
158
{
 
159
        unsigned long rate_mbit;
 
160
        int rate_enum,mod;
 
161
        u32 m = 0;
 
162
        const char *str = *pstr;
 
163
        char c;
 
164
 
 
165
        do {
 
166
                rate_mbit = simple_strtoul(str, (char**)&str, 10);
 
167
                if(rate_mbit>INT_MAX) return -EINVAL;
 
168
                
 
169
                rate_enum = rate_mbit2enum(rate_mbit);
 
170
                if(rate_enum<0) return rate_enum;
 
171
                
 
172
                c = *str;
 
173
                mod = get_modulation(rate_enum, c);
 
174
                if(mod<0) return mod;
 
175
 
 
176
                if(c>='a' && c<='z') c = *++str;
 
177
                if(c!=',' && c!=' ' && c!='\0') return -EINVAL;
 
178
                
 
179
                if(supported) {
 
180
                        int r = supported(rate_mbit, mod, opaque);
 
181
                        if(r) return r;
 
182
                }
 
183
 
 
184
                m |= gen_mask(rate_mbit, mod, opaque);
 
185
                str++;
 
186
        } while(c==',');
 
187
        
 
188
        *pstr = str-1;
 
189
        *mask |= m;
 
190
        return 0;
 
191
}
 
192
 
 
193
static /* TODO: remove 'static' when moved to wireless.c */
 
194
int
 
195
fill_ratemasks(const char *str, u32 *bmask, u32 *omask,
 
196
                int (*supported)(int mbit, int mod,void *opaque),
 
197
                u32 (*gen_mask)(int mbit, int mod,void *opaque),
 
198
                void *opaque)
 
199
{
 
200
        int r;
 
201
 
 
202
        r = fill_ratemask(&str, bmask, supported, gen_mask, opaque);
 
203
        if(r) return r;
 
204
 
 
205
        if(*str==' ') {
 
206
                str++;
 
207
                r = fill_ratemask(&str, omask, supported, gen_mask, opaque);
 
208
                if(r) return r;
 
209
        }
 
210
        if(*str)
 
211
                return -EINVAL;
 
212
        return 0;
 
213
}