nexmon – Blame information for rev 1

Subversion Repositories:
Rev:
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