aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wimax')
-rw-r--r--drivers/net/wimax/i2400m/control.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index 0f58418748aa..b42e34727983 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -400,7 +400,53 @@ out:
400 400
401 401
402/* 402/*
403 * Parse a 'state report' and extract carrier on/off information 403 * Process a TLV from a 'state report'
404 *
405 * @i2400m: device descriptor
406 * @tlv: pointer to the TLV header; it has been already validated for
407 * consistent size.
408 * @tag: for error messages
409 *
410 * Act on the TLVs from a 'state report'.
411 */
412static
413void i2400m_report_state_parse_tlv(struct i2400m *i2400m,
414 const struct i2400m_tlv_hdr *tlv,
415 const char *tag)
416{
417 struct device *dev = i2400m_dev(i2400m);
418 const struct i2400m_tlv_media_status *ms;
419 const struct i2400m_tlv_system_state *ss;
420 const struct i2400m_tlv_rf_switches_status *rfss;
421
422 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) {
423 ss = container_of(tlv, typeof(*ss), hdr);
424 d_printf(2, dev, "%s: system state TLV "
425 "found (0x%04x), state 0x%08x\n",
426 tag, I2400M_TLV_SYSTEM_STATE,
427 le32_to_cpu(ss->state));
428 i2400m_report_tlv_system_state(i2400m, ss);
429 }
430 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) {
431 rfss = container_of(tlv, typeof(*rfss), hdr);
432 d_printf(2, dev, "%s: RF status TLV "
433 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
434 tag, I2400M_TLV_RF_STATUS,
435 le32_to_cpu(rfss->sw_rf_switch),
436 le32_to_cpu(rfss->hw_rf_switch));
437 i2400m_report_tlv_rf_switches_status(i2400m, rfss);
438 }
439 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) {
440 ms = container_of(tlv, typeof(*ms), hdr);
441 d_printf(2, dev, "%s: Media Status TLV: %u\n",
442 tag, le32_to_cpu(ms->media_status));
443 i2400m_report_tlv_media_status(i2400m, ms);
444 }
445}
446
447
448/*
449 * Parse a 'state report' and extract information
404 * 450 *
405 * @i2400m: device descriptor 451 * @i2400m: device descriptor
406 * @l3l4_hdr: pointer to message; it has been already validated for 452 * @l3l4_hdr: pointer to message; it has been already validated for
@@ -409,13 +455,7 @@ out:
409 * declaration is assumed to be congruent with @size (as in 455 * declaration is assumed to be congruent with @size (as in
410 * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) 456 * sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
411 * 457 *
412 * Extract from the report state the system state TLV and infer from 458 * Walk over the TLVs in a report state and act on them.
413 * there if we have a carrier or not. Update our local state and tell
414 * netdev.
415 *
416 * When setting the carrier, it's fine to set OFF twice (for example),
417 * as netif_carrier_off() will not generate two OFF events (just on
418 * the transitions).
419 */ 459 */
420static 460static
421void i2400m_report_state_hook(struct i2400m *i2400m, 461void i2400m_report_state_hook(struct i2400m *i2400m,
@@ -424,9 +464,6 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
424{ 464{
425 struct device *dev = i2400m_dev(i2400m); 465 struct device *dev = i2400m_dev(i2400m);
426 const struct i2400m_tlv_hdr *tlv; 466 const struct i2400m_tlv_hdr *tlv;
427 const struct i2400m_tlv_system_state *ss;
428 const struct i2400m_tlv_rf_switches_status *rfss;
429 const struct i2400m_tlv_media_status *ms;
430 size_t tlv_size = le16_to_cpu(l3l4_hdr->length); 467 size_t tlv_size = le16_to_cpu(l3l4_hdr->length);
431 468
432 d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n", 469 d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
@@ -434,34 +471,8 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
434 tlv = NULL; 471 tlv = NULL;
435 472
436 while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl, 473 while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
437 tlv_size, tlv))) { 474 tlv_size, tlv)))
438 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, 475 i2400m_report_state_parse_tlv(i2400m, tlv, tag);
439 sizeof(*ss))) {
440 ss = container_of(tlv, typeof(*ss), hdr);
441 d_printf(2, dev, "%s: system state TLV "
442 "found (0x%04x), state 0x%08x\n",
443 tag, I2400M_TLV_SYSTEM_STATE,
444 le32_to_cpu(ss->state));
445 i2400m_report_tlv_system_state(i2400m, ss);
446 }
447 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS,
448 sizeof(*rfss))) {
449 rfss = container_of(tlv, typeof(*rfss), hdr);
450 d_printf(2, dev, "%s: RF status TLV "
451 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
452 tag, I2400M_TLV_RF_STATUS,
453 le32_to_cpu(rfss->sw_rf_switch),
454 le32_to_cpu(rfss->hw_rf_switch));
455 i2400m_report_tlv_rf_switches_status(i2400m, rfss);
456 }
457 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS,
458 sizeof(*ms))) {
459 ms = container_of(tlv, typeof(*ms), hdr);
460 d_printf(2, dev, "%s: Media Status TLV: %u\n",
461 tag, le32_to_cpu(ms->media_status));
462 i2400m_report_tlv_media_status(i2400m, ms);
463 }
464 }
465 d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n", 476 d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
466 i2400m, l3l4_hdr, size, tag); 477 i2400m, l3l4_hdr, size, tag);
467} 478}