diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-04-20 10:03:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-07 15:02:12 -0400 |
commit | f5eda47f45e90dfa38e25d569b9ac84ba94f8301 (patch) | |
tree | 5f806ae4729696cebef0bef0c261c6353b18045a /drivers/net/wireless/b43/debugfs.c | |
parent | 2afc49015db927fea7bc6ca33c0a60bf5d7c2c5f (diff) |
b43: Rewrite LO calibration algorithm
This patch distributes the Local Oscillator calibration bursts over time,
so that calibration only happens when it's actually needed.
Currently we periodically perform a recalibration of the whole table.
The table is huge and this takes lots of time. Additionally only small bits
of the table are actually needed at a given time. So instead of maintaining
a huge table with all possible calibration values, we create dynamic calibration
settings that
a) We only calibrate when they are actually needed.
b) Are cached for some time until they expire.
So a recalibration might happen if we need a calibration setting that's not
cached, or if the active calibration setting expires.
Currently the expire timeout is set to 30 seconds. We may raise that in future.
This patch reduces overall memory consumption by nuking the
huge static calibration tables.
This patch has been tested on several 4306, 4311 and 4318 flavours.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/debugfs.c')
-rw-r--r-- | drivers/net/wireless/b43/debugfs.c | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index 7fca2ebc747f..210e2789c1c3 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c | |||
@@ -270,24 +270,22 @@ static int restart_write_file(struct b43_wldev *dev, | |||
270 | return err; | 270 | return err; |
271 | } | 271 | } |
272 | 272 | ||
273 | static ssize_t append_lo_table(ssize_t count, char *buf, const size_t bufsize, | 273 | static unsigned long calc_expire_secs(unsigned long now, |
274 | struct b43_loctl table[B43_NR_BB][B43_NR_RF]) | 274 | unsigned long time, |
275 | unsigned long expire) | ||
275 | { | 276 | { |
276 | unsigned int i, j; | 277 | expire = time + expire; |
277 | struct b43_loctl *ctl; | 278 | |
278 | 279 | if (time_after(now, expire)) | |
279 | for (i = 0; i < B43_NR_BB; i++) { | 280 | return 0; /* expired */ |
280 | for (j = 0; j < B43_NR_RF; j++) { | 281 | if (expire < now) { |
281 | ctl = &(table[i][j]); | 282 | /* jiffies wrapped */ |
282 | fappend("(bbatt %2u, rfatt %2u) -> " | 283 | expire -= MAX_JIFFY_OFFSET; |
283 | "(I %+3d, Q %+3d, Used: %d, Calibrated: %d)\n", | 284 | now -= MAX_JIFFY_OFFSET; |
284 | i, j, ctl->i, ctl->q, | ||
285 | ctl->used, | ||
286 | b43_loctl_is_calibrated(ctl)); | ||
287 | } | ||
288 | } | 285 | } |
286 | B43_WARN_ON(expire < now); | ||
289 | 287 | ||
290 | return count; | 288 | return (expire - now) / HZ; |
291 | } | 289 | } |
292 | 290 | ||
293 | static ssize_t loctls_read_file(struct b43_wldev *dev, | 291 | static ssize_t loctls_read_file(struct b43_wldev *dev, |
@@ -296,27 +294,45 @@ static ssize_t loctls_read_file(struct b43_wldev *dev, | |||
296 | ssize_t count = 0; | 294 | ssize_t count = 0; |
297 | struct b43_txpower_lo_control *lo; | 295 | struct b43_txpower_lo_control *lo; |
298 | int i, err = 0; | 296 | int i, err = 0; |
297 | struct b43_lo_calib *cal; | ||
298 | unsigned long now = jiffies; | ||
299 | struct b43_phy *phy = &dev->phy; | ||
299 | 300 | ||
300 | if (dev->phy.type != B43_PHYTYPE_G) { | 301 | if (phy->type != B43_PHYTYPE_G) { |
301 | fappend("Device is not a G-PHY\n"); | 302 | fappend("Device is not a G-PHY\n"); |
302 | err = -ENODEV; | 303 | err = -ENODEV; |
303 | goto out; | 304 | goto out; |
304 | } | 305 | } |
305 | lo = dev->phy.lo_control; | 306 | lo = phy->lo_control; |
306 | fappend("-- Local Oscillator calibration data --\n\n"); | 307 | fappend("-- Local Oscillator calibration data --\n\n"); |
307 | fappend("Measured: %d, Rebuild: %d, HW-power-control: %d\n", | 308 | fappend("HW-power-control enabled: %d\n", |
308 | lo->lo_measured, | ||
309 | lo->rebuild, | ||
310 | dev->phy.hardware_power_control); | 309 | dev->phy.hardware_power_control); |
311 | fappend("TX Bias: 0x%02X, TX Magn: 0x%02X\n", | 310 | fappend("TX Bias: 0x%02X, TX Magn: 0x%02X (expire in %lu sec)\n", |
312 | lo->tx_bias, lo->tx_magn); | 311 | lo->tx_bias, lo->tx_magn, |
313 | fappend("Power Vector: 0x%08X%08X\n", | 312 | calc_expire_secs(now, lo->txctl_measured_time, |
313 | B43_LO_TXCTL_EXPIRE)); | ||
314 | fappend("Power Vector: 0x%08X%08X (expires in %lu sec)\n", | ||
314 | (unsigned int)((lo->power_vector & 0xFFFFFFFF00000000ULL) >> 32), | 315 | (unsigned int)((lo->power_vector & 0xFFFFFFFF00000000ULL) >> 32), |
315 | (unsigned int)(lo->power_vector & 0x00000000FFFFFFFFULL)); | 316 | (unsigned int)(lo->power_vector & 0x00000000FFFFFFFFULL), |
316 | fappend("\nControl table WITH PADMIX:\n"); | 317 | calc_expire_secs(now, lo->pwr_vec_read_time, |
317 | count = append_lo_table(count, buf, bufsize, lo->with_padmix); | 318 | B43_LO_PWRVEC_EXPIRE)); |
318 | fappend("\nControl table WITHOUT PADMIX:\n"); | 319 | |
319 | count = append_lo_table(count, buf, bufsize, lo->no_padmix); | 320 | fappend("\nCalibrated settings:\n"); |
321 | list_for_each_entry(cal, &lo->calib_list, list) { | ||
322 | bool active; | ||
323 | |||
324 | active = (b43_compare_bbatt(&cal->bbatt, &phy->bbatt) && | ||
325 | b43_compare_rfatt(&cal->rfatt, &phy->rfatt)); | ||
326 | fappend("BB(%d), RF(%d,%d) -> I=%d, Q=%d " | ||
327 | "(expires in %lu sec)%s\n", | ||
328 | cal->bbatt.att, | ||
329 | cal->rfatt.att, cal->rfatt.with_padmix, | ||
330 | cal->ctl.i, cal->ctl.q, | ||
331 | calc_expire_secs(now, cal->calib_time, | ||
332 | B43_LO_CALIB_EXPIRE), | ||
333 | active ? " ACTIVE" : ""); | ||
334 | } | ||
335 | |||
320 | fappend("\nUsed RF attenuation values: Value(WithPadmix flag)\n"); | 336 | fappend("\nUsed RF attenuation values: Value(WithPadmix flag)\n"); |
321 | for (i = 0; i < lo->rfatt_list.len; i++) { | 337 | for (i = 0; i < lo->rfatt_list.len; i++) { |
322 | fappend("%u(%d), ", | 338 | fappend("%u(%d), ", |
@@ -351,7 +367,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, | |||
351 | struct b43_dfs_file *dfile; | 367 | struct b43_dfs_file *dfile; |
352 | ssize_t uninitialized_var(ret); | 368 | ssize_t uninitialized_var(ret); |
353 | char *buf; | 369 | char *buf; |
354 | const size_t bufsize = 1024 * 128; | 370 | const size_t bufsize = 1024 * 16; /* 16 kiB buffer */ |
355 | const size_t buforder = get_order(bufsize); | 371 | const size_t buforder = get_order(bufsize); |
356 | int err = 0; | 372 | int err = 0; |
357 | 373 | ||
@@ -380,8 +396,6 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, | |||
380 | err = -ENOMEM; | 396 | err = -ENOMEM; |
381 | goto out_unlock; | 397 | goto out_unlock; |
382 | } | 398 | } |
383 | /* Sparse warns about the following memset, because it has a big | ||
384 | * size value. That warning is bogus, so I will ignore it. --mb */ | ||
385 | memset(buf, 0, bufsize); | 399 | memset(buf, 0, bufsize); |
386 | if (dfops->take_irqlock) { | 400 | if (dfops->take_irqlock) { |
387 | spin_lock_irq(&dev->wl->irq_lock); | 401 | spin_lock_irq(&dev->wl->irq_lock); |
@@ -523,6 +537,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev) | |||
523 | add_dyn_dbg("debug_dmaverbose", B43_DBG_DMAVERBOSE, 0); | 537 | add_dyn_dbg("debug_dmaverbose", B43_DBG_DMAVERBOSE, 0); |
524 | add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0); | 538 | add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0); |
525 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); | 539 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); |
540 | add_dyn_dbg("debug_lo", B43_DBG_LO, 0); | ||
526 | 541 | ||
527 | #undef add_dyn_dbg | 542 | #undef add_dyn_dbg |
528 | } | 543 | } |