/* * i2400m_report_hook - (maybe) act on a report * * @i2400m: device descriptor * @l3l4_hdr: pointer to message; it has been already validated for * consistent size. * @size: size of the message (header + payload). The header length * declaration is assumed to be congruent with @size (as in * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) * * Extract information we might need (like carrien on/off) from a * device report. */ void i2400m_report_hook(struct i2400m *i2400m, const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) { struct device *dev = i2400m_dev(i2400m); unsigned msg_type; d_fnstart(3, dev, "(i2400m %p l3l4_hdr %p size %zu)\n", i2400m, l3l4_hdr, size); /* Chew on the message, we might need some information from * here */ msg_type = le16_to_cpu(l3l4_hdr->type); switch (msg_type) { case I2400M_MT_REPORT_STATE: /* carrier detection... */ i2400m_report_state_hook(i2400m, l3l4_hdr, size, "REPORT STATE"); break; /* If the device is ready for power save, then ask it to do * it. */ case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { if (i2400m_power_save_disabled) d_printf(1, dev, "ready for powersave, " "not requesting (disabled by module " "parameter)\n"); else { d_printf(1, dev, "ready for powersave, " "requesting\n"); i2400m_cmd_enter_powersave(i2400m); } } break; } d_fnend(3, dev, "(i2400m %p l3l4_hdr %p size %zu) = void\n", i2400m, l3l4_hdr, size); }
void i2400m_report_hook(struct i2400m *i2400m, const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) { struct device *dev = i2400m_dev(i2400m); unsigned msg_type; d_fnstart(3, dev, "(i2400m %p l3l4_hdr %p size %zu)\n", i2400m, l3l4_hdr, size); msg_type = le16_to_cpu(l3l4_hdr->type); switch (msg_type) { case I2400M_MT_REPORT_STATE: i2400m_report_state_hook(i2400m, l3l4_hdr, size, "REPORT STATE"); break; case I2400M_MT_REPORT_POWERSAVE_READY: if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { if (i2400m_power_save_disabled) d_printf(1, dev, "ready for powersave, " "not requesting (disabled by module " "parameter)\n"); else { d_printf(1, dev, "ready for powersave, " "requesting\n"); i2400m_cmd_enter_powersave(i2400m); } } break; } d_fnend(3, dev, "(i2400m %p l3l4_hdr %p size %zu) = void\n", i2400m, l3l4_hdr, size); }
/* * Query the device for its state, update the WiMAX stack's idea of it * * @i2400m: device descriptor * * Returns: 0 if ok, < 0 errno code on error. * * Executes a 'Get State' command and parses the returned * TLVs. * * Because this is almost identical to a 'Report State', we use * i2400m_report_state_hook() to parse the answer. This will set the * carrier state, as well as the RF Kill switches state. */ static int i2400m_cmd_get_state(struct i2400m *i2400m) { int result; struct device *dev = i2400m_dev(i2400m); struct sk_buff *ack_skb; struct i2400m_l3l4_hdr *cmd; const struct i2400m_l3l4_hdr *ack; size_t ack_len; char strerr[32]; result = -ENOMEM; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (cmd == NULL) goto error_alloc; cmd->type = cpu_to_le16(I2400M_MT_GET_STATE); cmd->length = 0; cmd->version = cpu_to_le16(I2400M_L3L4_VERSION); ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); if (IS_ERR(ack_skb)) { dev_err(dev, "Failed to issue 'get state' command: %ld\n", PTR_ERR(ack_skb)); result = PTR_ERR(ack_skb); goto error_msg_to_dev; } ack = wimax_msg_data_len(ack_skb, &ack_len); result = i2400m_msg_check_status(ack, strerr, sizeof(strerr)); if (result < 0) { dev_err(dev, "'get state' (0x%04x) command failed: " "%d - %s\n", I2400M_MT_GET_STATE, result, strerr); goto error_cmd_failed; } i2400m_report_state_hook(i2400m, ack, ack_len - sizeof(*ack), "GET STATE"); result = 0; kfree_skb(ack_skb); error_cmd_failed: error_msg_to_dev: kfree(cmd); error_alloc: return result; }