/** * i2400m_set_idle_timeout - Set the device's idle mode timeout * * @i2400m: i2400m device descriptor * * @msecs: milliseconds for the timeout to enter idle mode. Between * 100 to 300000 (5m); 0 to disable. In increments of 100. * * After this @msecs of the link being idle (no data being sent or * received), the device will negotiate with the basestation entering * idle mode for saving power. The connection is maintained, but * getting out of it (done in tx.c) will require some negotiation, * possible crypto re-handshake and a possible DHCP re-lease. * * Only available if fw_version >= 0x00090002. * * Returns: 0 if ok, < 0 errno code on error. */ int i2400m_set_idle_timeout(struct i2400m *i2400m, unsigned msecs) { int result; struct device *dev = i2400m_dev(i2400m); struct sk_buff *ack_skb; struct { struct i2400m_l3l4_hdr hdr; struct i2400m_tlv_config_idle_timeout cit; } *cmd; const struct i2400m_l3l4_hdr *ack; size_t ack_len; char strerr[32]; result = -ENOSYS; if (i2400m_le_v1_3(i2400m)) goto error_alloc; result = -ENOMEM; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (cmd == NULL) goto error_alloc; cmd->hdr.type = cpu_to_le16(I2400M_MT_GET_STATE); cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr)); cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); cmd->cit.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT); cmd->cit.hdr.length = cpu_to_le16(sizeof(cmd->cit.timeout)); cmd->cit.timeout = cpu_to_le32(msecs); ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd)); if (IS_ERR(ack_skb)) { dev_err(dev, "Failed to issue 'set idle timeout' 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, "'set idle timeout' (0x%04x) command failed: " "%d - %s\n", I2400M_MT_GET_STATE, result, strerr); goto error_cmd_failed; } result = 0; kfree_skb(ack_skb); error_cmd_failed: error_msg_to_dev: kfree(cmd); error_alloc: return result; }
/** * i2400m_dev_initialize - Initialize the device once communications are ready * * @i2400m: device descriptor * * Returns: 0 if ok, < 0 errno code on error. * * Configures the device to work the way we like it. * * At the point of this call, the device is registered with the WiMAX * and netdev stacks, firmware is uploaded and we can talk to the * device normally. */ int i2400m_dev_initialize(struct i2400m *i2400m) { int result; struct device *dev = i2400m_dev(i2400m); struct i2400m_tlv_config_idle_parameters idle_params; struct i2400m_tlv_config_idle_timeout idle_timeout; struct i2400m_tlv_config_d2h_data_format df; struct i2400m_tlv_config_dl_host_reorder dlhr; const struct i2400m_tlv_hdr *args[9]; unsigned argc = 0; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); if (i2400m_passive_mode) goto out_passive; /* Disable idle mode? (enabled by default) */ if (i2400m_idle_mode_disabled) { if (i2400m_le_v1_3(i2400m)) { idle_params.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS); idle_params.hdr.length = cpu_to_le16( sizeof(idle_params) - sizeof(idle_params.hdr)); idle_params.idle_timeout = 0; idle_params.idle_paging_interval = 0; args[argc++] = &idle_params.hdr; } else { idle_timeout.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT); idle_timeout.hdr.length = cpu_to_le16( sizeof(idle_timeout) - sizeof(idle_timeout.hdr)); idle_timeout.timeout = 0; args[argc++] = &idle_timeout.hdr; } } if (i2400m_ge_v1_4(i2400m)) { /* Enable extended RX data format? */ df.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_D2H_DATA_FORMAT); df.hdr.length = cpu_to_le16( sizeof(df) - sizeof(df.hdr)); df.format = 1; args[argc++] = &df.hdr; /* Enable RX data reordering? * (switch flipped in rx.c:i2400m_rx_setup() after fw upload) */ if (i2400m->rx_reorder) { dlhr.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_DL_HOST_REORDER); dlhr.hdr.length = cpu_to_le16( sizeof(dlhr) - sizeof(dlhr.hdr)); dlhr.reorder = 1; args[argc++] = &dlhr.hdr; } } result = i2400m_set_init_config(i2400m, args, argc); if (result < 0) goto error; out_passive: /* * Update state: Here it just calls a get state; parsing the * result (System State TLV and RF Status TLV [done in the rx * path hooks]) will set the hardware and software RF-Kill * status. */ result = i2400m_cmd_get_state(i2400m); error: if (result < 0) dev_err(dev, "failed to initialize the device: %d\n", result); d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; }
int i2400m_dev_initialize(struct i2400m *i2400m) { int result; struct device *dev = i2400m_dev(i2400m); struct i2400m_tlv_config_idle_parameters idle_params; struct i2400m_tlv_config_idle_timeout idle_timeout; struct i2400m_tlv_config_d2h_data_format df; struct i2400m_tlv_config_dl_host_reorder dlhr; const struct i2400m_tlv_hdr *args[9]; unsigned argc = 0; d_fnstart(3, dev, "(i2400m %p)\n", i2400m); if (i2400m_passive_mode) goto out_passive; if (i2400m_idle_mode_disabled) { if (i2400m_le_v1_3(i2400m)) { idle_params.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS); idle_params.hdr.length = cpu_to_le16( sizeof(idle_params) - sizeof(idle_params.hdr)); idle_params.idle_timeout = 0; idle_params.idle_paging_interval = 0; args[argc++] = &idle_params.hdr; } else { idle_timeout.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT); idle_timeout.hdr.length = cpu_to_le16( sizeof(idle_timeout) - sizeof(idle_timeout.hdr)); idle_timeout.timeout = 0; args[argc++] = &idle_timeout.hdr; } } if (i2400m_ge_v1_4(i2400m)) { df.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_D2H_DATA_FORMAT); df.hdr.length = cpu_to_le16( sizeof(df) - sizeof(df.hdr)); df.format = 1; args[argc++] = &df.hdr; if (i2400m->rx_reorder) { dlhr.hdr.type = cpu_to_le16(I2400M_TLV_CONFIG_DL_HOST_REORDER); dlhr.hdr.length = cpu_to_le16( sizeof(dlhr) - sizeof(dlhr.hdr)); dlhr.reorder = 1; args[argc++] = &dlhr.hdr; } } result = i2400m_set_init_config(i2400m, args, argc); if (result < 0) goto error; out_passive: result = i2400m_cmd_get_state(i2400m); error: if (result < 0) dev_err(dev, "failed to initialize the device: %d\n", result); d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); return result; }