nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* Note : this particular snipset of code is available under |
2 | * the LGPL, MPL or BSD license (at your choice). |
||
3 | * Jean II |
||
4 | */ |
||
5 | |||
6 | /* --------------------------- INCLUDE --------------------------- */ |
||
7 | |||
8 | /* Backward compatibility for Wireless Extension 9 */ |
||
9 | #ifndef IW_POWER_MODIFIER |
||
10 | #define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ |
||
11 | #define IW_POWER_MIN 0x0001 /* Value is a minimum */ |
||
12 | #define IW_POWER_MAX 0x0002 /* Value is a maximum */ |
||
13 | #define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ |
||
14 | #endif IW_POWER_MODIFIER |
||
15 | |||
16 | struct net_local { |
||
17 | int pm_on; // Power Management enabled |
||
18 | int pm_multi; // Receive multicasts |
||
19 | int pm_period; // Power Management period |
||
20 | int pm_period_auto; // Power Management auto mode |
||
21 | int pm_max_period; // Power Management max period |
||
22 | int pm_min_period; // Power Management min period |
||
23 | int pm_timeout; // Power Management timeout |
||
24 | }; |
||
25 | |||
26 | /* --------------------------- HANDLERS --------------------------- */ |
||
27 | |||
28 | static int ioctl_set_power(struct net_device *dev, |
||
29 | struct iw_request_info *info, |
||
30 | struct iw_param *prq, |
||
31 | char *extra) |
||
32 | { |
||
33 | /* Disable it ? */ |
||
34 | if(prq->disabled) |
||
35 | { |
||
36 | local->pm_on = 0; |
||
37 | } |
||
38 | else |
||
39 | { |
||
40 | /* Check mode */ |
||
41 | switch(prq->flags & IW_POWER_MODE) |
||
42 | { |
||
43 | case IW_POWER_UNICAST_R: |
||
44 | local->pm_multi = 0; |
||
45 | local->need_commit = 1; |
||
46 | break; |
||
47 | case IW_POWER_ALL_R: |
||
48 | local->pm_multi = 1; |
||
49 | local->need_commit = 1; |
||
50 | break; |
||
51 | case IW_POWER_ON: /* None = ok */ |
||
52 | break; |
||
53 | default: /* Invalid */ |
||
54 | return(-EINVAL); |
||
55 | } |
||
56 | /* Set period */ |
||
57 | if(prq->flags & IW_POWER_PERIOD) |
||
58 | { |
||
59 | int period = prq->value; |
||
60 | #if WIRELESS_EXT < 21 |
||
61 | period /= 1000000; |
||
62 | #endif |
||
63 | /* Hum: check if within bounds... */ |
||
64 | |||
65 | /* Activate PM */ |
||
66 | local->pm_on = 1; |
||
67 | local->need_commit = 1; |
||
68 | |||
69 | /* Check min value */ |
||
70 | if(prq->flags & IW_POWER_MIN) |
||
71 | { |
||
72 | local->pm_min_period = period; |
||
73 | local->pm_period_auto = 1; |
||
74 | } |
||
75 | else |
||
76 | /* Check max value */ |
||
77 | if(prq->flags & IW_POWER_MAX) |
||
78 | { |
||
79 | local->pm_max_period = period; |
||
80 | local->pm_period_auto = 1; |
||
81 | } |
||
82 | else |
||
83 | { |
||
84 | /* Fixed value */ |
||
85 | local->pm_period = period; |
||
86 | local->pm_period_auto = 0; |
||
87 | } |
||
88 | } |
||
89 | /* Set timeout */ |
||
90 | if(prq->flags & IW_POWER_TIMEOUT) |
||
91 | { |
||
92 | /* Activate PM */ |
||
93 | local->pm_on = 1; |
||
94 | local->need_commit = 1; |
||
95 | /* Fixed value in ms */ |
||
96 | local->pm_timeout = prq->value/1000; |
||
97 | } |
||
98 | } |
||
99 | |||
100 | return(0); |
||
101 | } |
||
102 | |||
103 | static int ioctl_get_power(struct net_device *dev, |
||
104 | struct iw_request_info *info, |
||
105 | struct iw_param *prq, |
||
106 | char *extra) |
||
107 | { |
||
108 | prq->disabled = !local->pm_on; |
||
109 | /* By default, display the period */ |
||
110 | if(!(prq->flags & IW_POWER_TIMEOUT)) |
||
111 | { |
||
112 | int inc_flags = prq->flags; |
||
113 | prq->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE; |
||
114 | /* Check if auto */ |
||
115 | if(local->pm_period_auto) |
||
116 | { |
||
117 | /* By default, the min */ |
||
118 | if(!(inc_flags & IW_POWER_MAX)) |
||
119 | { |
||
120 | prq->value = local->pm_min_period; |
||
121 | #if WIRELESS_EXT < 21 |
||
122 | prq->value *= 1000000; |
||
123 | #endif |
||
124 | prq->flags |= IW_POWER_MIN; |
||
125 | } |
||
126 | else |
||
127 | { |
||
128 | prq->value = local->pm_max_period; |
||
129 | #if WIRELESS_EXT < 21 |
||
130 | prq->value *= 1000000; |
||
131 | #endif |
||
132 | prq->flags |= IW_POWER_MAX; |
||
133 | } |
||
134 | } |
||
135 | else |
||
136 | { |
||
137 | /* Fixed value. Check the flags */ |
||
138 | if(inc_flags & (IW_POWER_MIN | IW_POWER_MAX)) |
||
139 | return(-EINVAL); |
||
140 | else |
||
141 | { |
||
142 | prq->value = local->pm_period; |
||
143 | #if WIRELESS_EXT < 21 |
||
144 | prq->value *= 1000000; |
||
145 | #endif |
||
146 | } |
||
147 | } |
||
148 | } |
||
149 | else |
||
150 | { |
||
151 | /* Deal with the timeout - always fixed */ |
||
152 | prq->flags = IW_POWER_TIMEOUT; |
||
153 | prq->value = local->pm_timeout * 1000; |
||
154 | } |
||
155 | if(local->pm_multi) |
||
156 | prq->flags |= IW_POWER_ALL_R; |
||
157 | else |
||
158 | prq->flags |= IW_POWER_UNICAST_R; |
||
159 | |||
160 | return(0); |
||
161 | } |
||
162 | |||
163 | static int ioctl_get_range(struct net_device *dev, |
||
164 | struct iw_request_info *info, |
||
165 | struct iw_point *rrq, |
||
166 | char *extra) |
||
167 | { |
||
168 | struct iw_range *range = (struct iw_range *) extra; |
||
169 | |||
170 | rrq->length = sizeof(struct iw_range); |
||
171 | |||
172 | memset(range, 0, sizeof(struct iw_range)); |
||
173 | |||
174 | #if WIRELESS_EXT > 10 |
||
175 | /* Version we are compiled with */ |
||
176 | range->we_version_compiled = WIRELESS_EXT; |
||
177 | /* Minimum version we recommend */ |
||
178 | range->we_version_source = 8; |
||
179 | #endif /* WIRELESS_EXT > 10 */ |
||
180 | |||
181 | #if WIRELESS_EXT > 9 |
||
182 | #if WIRELESS_EXT < 21 |
||
183 | range.min_pmp = 1000000; /* 1 units */ |
||
184 | range.max_pmp = 12000000; /* 12 units */ |
||
185 | #else |
||
186 | range.min_pmp = 1; /* 1 units */ |
||
187 | range.max_pmp = 12; /* 12 units */ |
||
188 | #endif |
||
189 | range.min_pmt = 1000; /* 1 ms */ |
||
190 | range.max_pmt = 1000000; /* 1 s */ |
||
191 | range.pmp_flags = IW_POWER_PERIOD | IW_POWER_RELATIVE | |
||
192 | IW_POWER_MIN | IW_POWER_MAX; |
||
193 | range.pmt_flags = IW_POWER_TIMEOUT; |
||
194 | range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R; |
||
195 | #endif /* WIRELESS_EXT > 9 */ |
||
196 | return(0); |
||
197 | } |
||
198 | |||
199 | /* --------------------------- BINDING --------------------------- */ |
||
200 | |||
201 | #if WIRELESS_EXT > 12 |
||
202 | /* Use the new driver API, save overhead */ |
||
203 | static const iw_handler handler_table[] = |
||
204 | { |
||
205 | ... |
||
206 | (iw_handler) ioctl_set_power, /* SIOCSIWPOWER */ |
||
207 | (iw_handler) ioctl_get_power, /* SIOCGIWPOWER */ |
||
208 | }; |
||
209 | #else /* WIRELESS_EXT < 12 */ |
||
210 | /* Use old API in the ioctl handler */ |
||
211 | static int |
||
212 | do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
||
213 | { |
||
214 | struct iwreq *wrq = (struct iwreq *) ifr; |
||
215 | int err = 0; |
||
216 | |||
217 | switch (cmd) |
||
218 | { |
||
219 | #if WIRELESS_EXT > 8 |
||
220 | /* Set the desired Power Management mode */ |
||
221 | case SIOCSIWPOWER: |
||
222 | err = ioctl_set_power(dev, NULL, &(wrq->u.power), NULL); |
||
223 | break; |
||
224 | |||
225 | /* Get the power management settings */ |
||
226 | case SIOCGIWPOWER: |
||
227 | err = ioctl_get_power(dev, NULL, &(wrq->u.power), NULL); |
||
228 | break; |
||
229 | #endif /* WIRELESS_EXT > 8 */ |
||
230 | } |
||
231 | return(err); |
||
232 | } |
||
233 | #endif /* WIRELESS_EXT < 12 */ |
||
234 |