Lines Matching +full:tx +full:- +full:sched +full:- +full:sp
1 // SPDX-License-Identifier: GPL-2.0-only
9 #include <linux/sched.h>
18 #define CAL_NF(nf) ((s32)(-(s32)(nf)))
22 * lbs_cmd_copyback - Simple callback that copies response back into command
37 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); in lbs_cmd_copyback()
44 * lbs_cmd_async_callback - Simple callback that ignores the result.
62 * is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
82 * lbs_update_hw_spec - Updates the hardware details like MAC address
92 int ret = -1; in lbs_update_hw_spec()
97 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); in lbs_update_hw_spec()
102 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo); in lbs_update_hw_spec()
106 priv->fwrelease = le32_to_cpu(cmd.fwrelease); in lbs_update_hw_spec()
107 priv->fwrelease = (priv->fwrelease << 8) | in lbs_update_hw_spec()
108 (priv->fwrelease >> 24 & 0xff); in lbs_update_hw_spec()
114 netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n", in lbs_update_hw_spec()
116 priv->fwrelease >> 24 & 0xff, in lbs_update_hw_spec()
117 priv->fwrelease >> 16 & 0xff, in lbs_update_hw_spec()
118 priv->fwrelease >> 8 & 0xff, in lbs_update_hw_spec()
119 priv->fwrelease & 0xff, in lbs_update_hw_spec()
120 priv->fwcapinfo); in lbs_update_hw_spec()
124 /* Clamp region code to 8-bit since FW spec indicates that it should in lbs_update_hw_spec()
125 * only ever be 8-bit, even though the field size is 16-bit. Some firmware in lbs_update_hw_spec()
126 * returns non-zero high 8 bits here. in lbs_update_hw_spec()
131 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) in lbs_update_hw_spec()
132 priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; in lbs_update_hw_spec()
134 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; in lbs_update_hw_spec()
138 if (priv->regioncode == lbs_region_code_to_index[i]) in lbs_update_hw_spec()
144 priv->regioncode = 0x10; in lbs_update_hw_spec()
145 netdev_info(priv->dev, in lbs_update_hw_spec()
149 if (priv->current_addr[0] == 0xff) in lbs_update_hw_spec()
150 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); in lbs_update_hw_spec()
152 if (!priv->copied_hwaddr) { in lbs_update_hw_spec()
153 eth_hw_addr_set(priv->dev, priv->current_addr); in lbs_update_hw_spec()
154 if (priv->mesh_dev) in lbs_update_hw_spec()
155 eth_hw_addr_set(priv->mesh_dev, priv->current_addr); in lbs_update_hw_spec()
156 priv->copied_hwaddr = 1; in lbs_update_hw_spec()
166 if (priv->is_host_sleep_activated) { in lbs_ret_host_sleep_cfg()
167 priv->is_host_sleep_configured = 0; in lbs_ret_host_sleep_cfg()
168 if (priv->psstate == PS_STATE_FULL_POWER) { in lbs_ret_host_sleep_cfg()
169 priv->is_host_sleep_activated = 0; in lbs_ret_host_sleep_cfg()
170 wake_up_interruptible(&priv->host_sleep_q); in lbs_ret_host_sleep_cfg()
173 priv->is_host_sleep_configured = 1; in lbs_ret_host_sleep_cfg()
190 if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported) in lbs_host_sleep_cfg()
195 cmd_config.gpio = priv->wol_gpio; in lbs_host_sleep_cfg()
196 cmd_config.gap = priv->wol_gap; in lbs_host_sleep_cfg()
213 netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret); in lbs_host_sleep_cfg()
221 * lbs_set_ps_mode - Sets the Power Save mode
249 ret = -EOPNOTSUPP; in lbs_set_ps_mode()
263 struct sleep_params *sp) in lbs_cmd_802_11_sleep_params() argument
271 cmd.error = cpu_to_le16(sp->sp_error); in lbs_cmd_802_11_sleep_params()
272 cmd.offset = cpu_to_le16(sp->sp_offset); in lbs_cmd_802_11_sleep_params()
273 cmd.stabletime = cpu_to_le16(sp->sp_stabletime); in lbs_cmd_802_11_sleep_params()
274 cmd.calcontrol = sp->sp_calcontrol; in lbs_cmd_802_11_sleep_params()
275 cmd.externalsleepclk = sp->sp_extsleepclk; in lbs_cmd_802_11_sleep_params()
276 cmd.reserved = cpu_to_le16(sp->sp_reserved); in lbs_cmd_802_11_sleep_params()
290 sp->sp_error = le16_to_cpu(cmd.error); in lbs_cmd_802_11_sleep_params()
291 sp->sp_offset = le16_to_cpu(cmd.offset); in lbs_cmd_802_11_sleep_params()
292 sp->sp_stabletime = le16_to_cpu(cmd.stabletime); in lbs_cmd_802_11_sleep_params()
293 sp->sp_calcontrol = cmd.calcontrol; in lbs_cmd_802_11_sleep_params()
294 sp->sp_extsleepclk = cmd.externalsleepclk; in lbs_cmd_802_11_sleep_params()
295 sp->sp_reserved = le16_to_cpu(cmd.reserved); in lbs_cmd_802_11_sleep_params()
305 if (priv->is_deep_sleep) { in lbs_wait_for_ds_awake()
306 if (!wait_event_interruptible_timeout(priv->ds_awake_q, in lbs_wait_for_ds_awake()
307 !priv->is_deep_sleep, (10 * HZ))) { in lbs_wait_for_ds_awake()
308 netdev_err(priv->dev, "ds_awake_q: timer expired\n"); in lbs_wait_for_ds_awake()
309 ret = -1; in lbs_wait_for_ds_awake()
321 if (priv->is_deep_sleep != 1) { in lbs_set_deep_sleep()
323 BUG_ON(!priv->enter_deep_sleep); in lbs_set_deep_sleep()
324 ret = priv->enter_deep_sleep(priv); in lbs_set_deep_sleep()
326 netif_stop_queue(priv->dev); in lbs_set_deep_sleep()
327 netif_carrier_off(priv->dev); in lbs_set_deep_sleep()
330 netdev_err(priv->dev, "deep sleep: already enabled\n"); in lbs_set_deep_sleep()
333 if (priv->is_deep_sleep) { in lbs_set_deep_sleep()
335 BUG_ON(!priv->exit_deep_sleep); in lbs_set_deep_sleep()
336 ret = priv->exit_deep_sleep(priv); in lbs_set_deep_sleep()
340 netdev_err(priv->dev, in lbs_set_deep_sleep()
353 priv->is_host_sleep_activated = 1; in lbs_ret_host_sleep_activate()
354 wake_up_interruptible(&priv->host_sleep_q); in lbs_ret_host_sleep_activate()
366 if (priv->is_host_sleep_activated != 1) { in lbs_set_host_sleep()
368 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria, in lbs_set_host_sleep()
371 netdev_info(priv->dev, in lbs_set_host_sleep()
376 if (priv->psstate == PS_STATE_FULL_POWER) { in lbs_set_host_sleep()
383 netdev_info(priv->dev, in lbs_set_host_sleep()
389 priv->host_sleep_q, in lbs_set_host_sleep()
390 priv->is_host_sleep_activated, in lbs_set_host_sleep()
392 netdev_err(priv->dev, in lbs_set_host_sleep()
394 ret = -1; in lbs_set_host_sleep()
397 netdev_err(priv->dev, "host sleep: already enabled\n"); in lbs_set_host_sleep()
400 if (priv->is_host_sleep_activated) in lbs_set_host_sleep()
409 * lbs_set_snmp_mib - Set an SNMP MIB value
442 ret = -EINVAL; in lbs_set_snmp_mib()
456 * lbs_get_tx_power - Get the min, max, and current TX power
488 * lbs_set_monitor_mode - Enable or disable monitor mode
511 priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP : in lbs_set_monitor_mode()
519 * lbs_get_channel - Get the radio channel
552 priv->channel = ret; in lbs_update_channel()
560 * lbs_set_channel - Set the radio channel
571 u8 old_channel = priv->channel; in lbs_set_channel()
584 priv->channel = (uint8_t) le16_to_cpu(cmd.channel); in lbs_set_channel()
586 priv->channel); in lbs_set_channel()
593 * lbs_get_rssi - Get current RSSI and noise floor
624 * lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
633 struct wiphy *wiphy = priv->wdev->wiphy; in lbs_set_11d_domain_info()
634 struct ieee80211_supported_band **bands = wiphy->bands; in lbs_set_11d_domain_info()
647 if (!priv->country_code[0]) in lbs_set_11d_domain_info()
654 priv->country_code[0], priv->country_code[1]); in lbs_set_11d_domain_info()
656 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); in lbs_set_11d_domain_info()
659 domain->country_code[0] = priv->country_code[0]; in lbs_set_11d_domain_info()
660 domain->country_code[1] = priv->country_code[1]; in lbs_set_11d_domain_info()
661 domain->country_code[2] = ' '; in lbs_set_11d_domain_info()
678 (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS); in lbs_set_11d_domain_info()
680 ch = &bands[band]->channels[i]; in lbs_set_11d_domain_info()
681 if (ch->flags & IEEE80211_CHAN_DISABLED) in lbs_set_11d_domain_info()
686 next_chan = first_channel = (u32) ch->hw_value; in lbs_set_11d_domain_info()
687 max_pwr = ch->max_power; in lbs_set_11d_domain_info()
692 if ((ch->hw_value == next_chan + 1) && in lbs_set_11d_domain_info()
693 (ch->max_power == max_pwr)) { in lbs_set_11d_domain_info()
702 t = &domain->triplet[num_triplet]; in lbs_set_11d_domain_info()
703 t->chans.first_channel = first_channel; in lbs_set_11d_domain_info()
704 t->chans.num_channels = num_parsed_chan; in lbs_set_11d_domain_info()
705 t->chans.max_power = max_pwr; in lbs_set_11d_domain_info()
715 t = &domain->triplet[num_triplet]; in lbs_set_11d_domain_info()
716 t->chans.first_channel = first_channel; in lbs_set_11d_domain_info()
717 t->chans.num_channels = num_parsed_chan; in lbs_set_11d_domain_info()
718 t->chans.max_power = max_pwr; in lbs_set_11d_domain_info()
727 domain->header.len = cpu_to_le16(sizeof(domain->country_code) + in lbs_set_11d_domain_info()
732 le16_to_cpu(domain->header.len)); in lbs_set_11d_domain_info()
747 * lbs_get_reg - Read a MAC, Baseband, or RF register
772 ret = -EINVAL; in lbs_get_reg()
789 * lbs_set_reg - Write a MAC, Baseband, or RF register
814 ret = -EINVAL; in lbs_set_reg()
834 if (!cmdnode->cmdbuf->size) { in lbs_queue_cmd()
838 cmdnode->result = 0; in lbs_queue_cmd()
841 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { in lbs_queue_cmd()
842 struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; in lbs_queue_cmd()
844 if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { in lbs_queue_cmd()
845 if (priv->psstate != PS_STATE_FULL_POWER) in lbs_queue_cmd()
850 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) in lbs_queue_cmd()
853 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_queue_cmd()
856 list_add_tail(&cmdnode->list, &priv->cmdpendingq); in lbs_queue_cmd()
858 list_add(&cmdnode->list, &priv->cmdpendingq); in lbs_queue_cmd()
860 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_queue_cmd()
863 le16_to_cpu(cmdnode->cmdbuf->command)); in lbs_queue_cmd()
876 cmd = cmdnode->cmdbuf; in lbs_submit_command()
878 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_submit_command()
879 priv->seqnum++; in lbs_submit_command()
880 cmd->seqnum = cpu_to_le16(priv->seqnum); in lbs_submit_command()
881 priv->cur_cmd = cmdnode; in lbs_submit_command()
882 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_submit_command()
884 cmdsize = le16_to_cpu(cmd->size); in lbs_submit_command()
885 command = le16_to_cpu(cmd->command); in lbs_submit_command()
892 command, le16_to_cpu(cmd->seqnum), cmdsize); in lbs_submit_command()
893 lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); in lbs_submit_command()
895 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); in lbs_submit_command()
898 netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n", in lbs_submit_command()
901 priv->dnld_sent = DNLD_RES_RECEIVED; in lbs_submit_command()
906 priv->is_deep_sleep = 1; in lbs_submit_command()
910 mod_timer(&priv->command_timer, jiffies + timeo); in lbs_submit_command()
916 * after cleans it. Requires priv->driver_lock held.
924 cmdnode->callback = NULL; in __lbs_cleanup_and_insert_cmd()
925 cmdnode->callback_arg = 0; in __lbs_cleanup_and_insert_cmd()
927 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); in __lbs_cleanup_and_insert_cmd()
929 list_add_tail(&cmdnode->list, &priv->cmdfreeq); in __lbs_cleanup_and_insert_cmd()
937 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_cleanup_and_insert_cmd()
939 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_cleanup_and_insert_cmd()
951 list_del_init(&cmd->list); in __lbs_complete_command()
953 cmd->result = result; in __lbs_complete_command()
954 cmd->cmdwaitqwoken = 1; in __lbs_complete_command()
955 wake_up(&cmd->cmdwait_q); in __lbs_complete_command()
957 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) in __lbs_complete_command()
959 priv->cur_cmd = NULL; in __lbs_complete_command()
960 wake_up(&priv->waitq); in __lbs_complete_command()
967 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_complete_command()
969 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_complete_command()
975 int ret = -EINVAL; in lbs_set_radio()
982 if (priv->fwrelease < 0x09000000) { in lbs_set_radio()
998 priv->txpower_cur = 0; in lbs_set_radio()
1004 priv->radio_on = radio_on; in lbs_set_radio()
1017 cmd.action = cpu_to_le16(priv->mac_control); in lbs_set_mac_control()
1029 cmd.action = cpu_to_le16(priv->mac_control); in lbs_set_mac_control_sync()
1037 * lbs_allocate_cmd_buffer - allocates the command buffer and links
1042 * returns: 0 for success or -1 on error
1055 ret = -1; in lbs_allocate_cmd_buffer()
1058 priv->cmd_array = cmdarray; in lbs_allocate_cmd_buffer()
1065 ret = -1; in lbs_allocate_cmd_buffer()
1083 kfree(priv->cmd_array); in lbs_allocate_cmd_buffer()
1084 priv->cmd_array = NULL; in lbs_allocate_cmd_buffer()
1090 * lbs_free_cmd_buffer - free the command buffer
1102 if (priv->cmd_array == NULL) { in lbs_free_cmd_buffer()
1107 cmdarray = priv->cmd_array; in lbs_free_cmd_buffer()
1118 if (priv->cmd_array) { in lbs_free_cmd_buffer()
1119 kfree(priv->cmd_array); in lbs_free_cmd_buffer()
1120 priv->cmd_array = NULL; in lbs_free_cmd_buffer()
1128 * lbs_get_free_cmd_node - gets a free command node if available in
1144 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_get_free_cmd_node()
1146 if (!list_empty(&priv->cmdfreeq)) { in lbs_get_free_cmd_node()
1147 tempnode = list_first_entry(&priv->cmdfreeq, in lbs_get_free_cmd_node()
1149 list_del_init(&tempnode->list); in lbs_get_free_cmd_node()
1155 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_get_free_cmd_node()
1161 * lbs_execute_next_command - execute next command in command
1166 * returns: 0 on success or -1 on error
1178 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_execute_next_command()
1180 if (priv->cur_cmd) { in lbs_execute_next_command()
1181 netdev_alert(priv->dev, in lbs_execute_next_command()
1183 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_execute_next_command()
1184 ret = -1; in lbs_execute_next_command()
1188 if (!list_empty(&priv->cmdpendingq)) { in lbs_execute_next_command()
1189 cmdnode = list_first_entry(&priv->cmdpendingq, in lbs_execute_next_command()
1193 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_execute_next_command()
1196 cmd = cmdnode->cmdbuf; in lbs_execute_next_command()
1198 if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) { in lbs_execute_next_command()
1199 if ((priv->psstate == PS_STATE_SLEEP) || in lbs_execute_next_command()
1200 (priv->psstate == PS_STATE_PRE_SLEEP)) { in lbs_execute_next_command()
1203 le16_to_cpu(cmd->command), in lbs_execute_next_command()
1204 priv->psstate); in lbs_execute_next_command()
1205 ret = -1; in lbs_execute_next_command()
1210 le16_to_cpu(cmd->command), priv->psstate); in lbs_execute_next_command()
1211 } else if (priv->psstate != PS_STATE_FULL_POWER) { in lbs_execute_next_command()
1213 * 1. Non-PS command: in lbs_execute_next_command()
1223 if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) { in lbs_execute_next_command()
1226 if ((priv->psstate == PS_STATE_SLEEP) in lbs_execute_next_command()
1227 || (priv->psstate == PS_STATE_PRE_SLEEP) in lbs_execute_next_command()
1231 priv->needtowakeup = 1; in lbs_execute_next_command()
1249 psm->action); in lbs_execute_next_command()
1250 if (psm->action != in lbs_execute_next_command()
1260 if ((priv->psstate == PS_STATE_SLEEP) || in lbs_execute_next_command()
1261 (priv->psstate == PS_STATE_PRE_SLEEP)) { in lbs_execute_next_command()
1265 priv->needtowakeup = 1; in lbs_execute_next_command()
1275 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_execute_next_command()
1276 list_del_init(&cmdnode->list); in lbs_execute_next_command()
1277 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_execute_next_command()
1279 le16_to_cpu(cmd->command)); in lbs_execute_next_command()
1286 if ((priv->psmode != LBS802_11POWERMODECAM) && in lbs_execute_next_command()
1287 (priv->psstate == PS_STATE_FULL_POWER) && in lbs_execute_next_command()
1288 (priv->connect_status == LBS_CONNECTED)) { in lbs_execute_next_command()
1309 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep, in lbs_send_confirmsleep()
1312 netdev_alert(priv->dev, "confirm_sleep failed\n"); in lbs_send_confirmsleep()
1316 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_send_confirmsleep()
1318 /* We don't get a response on the sleep-confirmation */ in lbs_send_confirmsleep()
1319 priv->dnld_sent = DNLD_RES_RECEIVED; in lbs_send_confirmsleep()
1321 if (priv->is_host_sleep_configured) { in lbs_send_confirmsleep()
1322 priv->is_host_sleep_activated = 1; in lbs_send_confirmsleep()
1323 wake_up_interruptible(&priv->host_sleep_q); in lbs_send_confirmsleep()
1327 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) in lbs_send_confirmsleep()
1328 priv->psstate = PS_STATE_SLEEP; in lbs_send_confirmsleep()
1330 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_send_confirmsleep()
1334 * lbs_ps_confirm_sleep - checks condition and prepares to
1346 spin_lock_irqsave(&priv->driver_lock, flags); in lbs_ps_confirm_sleep()
1347 if (priv->dnld_sent) { in lbs_ps_confirm_sleep()
1352 /* In-progress command? */ in lbs_ps_confirm_sleep()
1353 if (priv->cur_cmd) { in lbs_ps_confirm_sleep()
1359 if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { in lbs_ps_confirm_sleep()
1363 spin_unlock_irqrestore(&priv->driver_lock, flags); in lbs_ps_confirm_sleep()
1381 if (priv->surpriseremoved) { in __lbs_cmd_async()
1383 cmdnode = ERR_PTR(-ENOENT); in __lbs_cmd_async()
1390 if (priv->is_deep_sleep) { in __lbs_cmd_async()
1392 cmdnode = ERR_PTR(-EBUSY); in __lbs_cmd_async()
1401 wake_up(&priv->waitq); in __lbs_cmd_async()
1402 cmdnode = ERR_PTR(-ENOBUFS); in __lbs_cmd_async()
1406 cmdnode->callback = callback; in __lbs_cmd_async()
1407 cmdnode->callback_arg = callback_arg; in __lbs_cmd_async()
1410 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); in __lbs_cmd_async()
1413 cmdnode->cmdbuf->command = cpu_to_le16(command); in __lbs_cmd_async()
1414 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); in __lbs_cmd_async()
1415 cmdnode->cmdbuf->result = 0; in __lbs_cmd_async()
1419 cmdnode->cmdwaitqwoken = 0; in __lbs_cmd_async()
1421 wake_up(&priv->waitq); in __lbs_cmd_async()
1457 wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); in __lbs_cmd()
1459 spin_lock_irqsave(&priv->driver_lock, flags); in __lbs_cmd()
1460 ret = cmdnode->result; in __lbs_cmd()
1462 netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n", in __lbs_cmd()
1466 spin_unlock_irqrestore(&priv->driver_lock, flags); in __lbs_cmd()