1 /* TODO: stop #including, move into wireless.c
2 * until then, keep in sync copies in prism54/ and acx/ dirs
3 * code+data size: less than 1k */
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
[] = {
48 static /* TODO: remove 'static' when moved to wireless.c */
50 rate_mbit2enum(int n
) {
52 while(i
<sizeof(ratelist
)) {
53 if(n
==ratelist
[i
]) return i
;
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
];
67 if(r_enum
<DOT11_RATE_5
|| r_enum
>DOT11_RATE_11
) return -EINVAL
;
71 if(r_enum
<DOT11_RATE_5
|| r_enum
>DOT11_RATE_33
) return -EINVAL
;
72 return DOT11_MOD_PBCC
;
75 if(r_enum
<DOT11_RATE_6
) return -EINVAL
;
76 return DOT11_MOD_OFDM
;
79 if(r_enum
<DOT11_RATE_6
) return -EINVAL
;
80 return DOT11_MOD_CCKOFDM
;
87 fill_ratevector(const char **pstr
, u8
*vector
, int size
,
88 int (*supported
)(int mbit
, int mod
, void *opaque
), void *opaque
, int or_mask
)
90 unsigned long rate_mbit
;
92 const char *str
= *pstr
;
96 rate_mbit
= simple_strtoul(str
, (char**)&str
, 10);
97 if(rate_mbit
>INT_MAX
) return -EINVAL
;
99 rate_enum
= rate_mbit2enum(rate_mbit
);
100 if(rate_enum
<0) return rate_enum
;
103 mod
= get_modulation(rate_enum
, c
);
104 if(mod
<0) return mod
;
106 if(c
>='a' && c
<='z') c
= *++str
;
107 if(c
!=',' && c
!=' ' && c
!='\0') return -EINVAL
;
110 int r
= supported(rate_mbit
, mod
, opaque
);
114 *vector
++ = dot11ratebyte
[rate_enum
] | or_mask
;
118 } while(size
>0 && c
==',');
120 if(size
<1) return -E2BIG
;
121 *vector
=0; /* TODO: sort, remove dups? */
127 static /* TODO: remove 'static' when moved to wireless.c */
129 fill_ratevectors(const char *str
, u8
*brate
, u8
*orate
, int size
,
130 int (*supported
)(int mbit
, int mod
, void *opaque
), void *opaque
)
134 r
= fill_ratevector(&str
, brate
, size
, supported
, opaque
, 0x80);
140 r
= fill_ratevector(&str
, orate
, size
, supported
, opaque
, 0);
142 /* TODO: sanitize, e.g. remove/error on rates already in basic rate set? */
151 /* TODO: use u64 masks? */
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
),
159 unsigned long rate_mbit
;
162 const char *str
= *pstr
;
166 rate_mbit
= simple_strtoul(str
, (char**)&str
, 10);
167 if(rate_mbit
>INT_MAX
) return -EINVAL
;
169 rate_enum
= rate_mbit2enum(rate_mbit
);
170 if(rate_enum
<0) return rate_enum
;
173 mod
= get_modulation(rate_enum
, c
);
174 if(mod
<0) return mod
;
176 if(c
>='a' && c
<='z') c
= *++str
;
177 if(c
!=',' && c
!=' ' && c
!='\0') return -EINVAL
;
180 int r
= supported(rate_mbit
, mod
, opaque
);
184 m
|= gen_mask(rate_mbit
, mod
, opaque
);
193 static /* TODO: remove 'static' when moved to wireless.c */
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
),
202 r
= fill_ratemask(&str
, bmask
, supported
, gen_mask
, opaque
);
207 r
= fill_ratemask(&str
, omask
, supported
, gen_mask
, opaque
);