8 #include <linux/sched.h>
9 #include <linux/slab.h>
10 #include <linux/if_arp.h>
11 #include <linux/export.h>
17 #define CAL_NF(nf) ((s32)(-(s32)(nf)))
18 #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
37 memcpy(buf, resp, copy_len);
67 static u8 is_command_allowed_in_ps(
u16 cmd)
96 memset(&cmd, 0,
sizeof(cmd));
115 netdev_info(priv->
dev,
"%pM, fw %u.%u.%up%u, cap 0x%08x\n",
122 lbs_deb_cmd(
"GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
144 if (i >= MRVDRV_MAX_REGION_CODE) {
146 netdev_info(priv->
dev,
147 "unidentified region code; using the default (USA)\n");
202 if (p_wol_config !=
NULL)
210 lbs_ret_host_sleep_cfg, 0);
217 netdev_info(priv->
dev,
"HOST_SLEEP_CFG failed %d\n", ret);
241 memset(&cmd, 0,
sizeof(cmd));
254 lbs_deb_cmd(
"PS_MODE: unknown action 0x%X\n", cmd_action);
278 memset(&cmd, 0,
sizeof(cmd));
293 lbs_deb_cmd(
"error 0x%x, offset 0x%x, stabletime 0x%x, "
294 "calcontrol 0x%x extsleepclk 0x%x\n",
311 static int lbs_wait_for_ds_awake(
struct lbs_private *priv)
320 netdev_err(priv->
dev,
"ds_awake_q: timer expired\n");
341 netif_stop_queue(priv->
dev);
345 netdev_err(priv->
dev,
"deep sleep: already enabled\n");
353 ret = lbs_wait_for_ds_awake(priv);
355 netdev_err(priv->
dev,
356 "deep sleep: wakeup failed\n");
365 static int lbs_ret_host_sleep_activate(
struct lbs_private *priv,
386 memset(&cmd, 0,
sizeof(cmd));
390 netdev_info(priv->
dev,
391 "Host sleep configuration failed: %d\n",
400 lbs_ret_host_sleep_activate, 0);
402 netdev_info(priv->
dev,
403 "HOST_SLEEP_ACTIVATE failed: %d\n",
411 netdev_err(priv->
dev,
412 "host_sleep_q: timer expired\n");
416 netdev_err(priv->
dev,
"host sleep: already enabled\n");
443 memset(&cmd, 0,
sizeof (cmd));
462 lbs_deb_cmd(
"SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
467 lbs_deb_cmd(
"SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
493 memset(&cmd, 0,
sizeof (cmd));
504 *out_val = cmd.
value[0];
510 lbs_deb_cmd(
"SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
538 memset(&cmd, 0,
sizeof(cmd));
570 memset(&cmd, 0,
sizeof(cmd));
597 memset(&cmd, 0,
sizeof(cmd));
622 static int lbs_get_channel(
struct lbs_private *priv)
629 memset(&cmd, 0,
sizeof(cmd));
652 ret = lbs_get_channel(priv);
679 memset(&cmd, 0,
sizeof(cmd));
689 lbs_deb_cmd(
"channel switch from %d to %d\n", old_channel,
716 memset(&cmd, 0,
sizeof(cmd));
749 u8 num_parsed_chan = 0;
759 memset(&cmd, 0,
sizeof(cmd));
801 if ((ch->
hw_value == next_chan + 1) &&
809 first_channel, num_parsed_chan,
811 t = &domain->
triplet[num_triplet];
822 lbs_deb_11d(
"11D triplet (%d, %d, %d)\n", first_channel,
823 num_parsed_chan, max_pwr);
824 t = &domain->
triplet[num_triplet];
845 sizeof(cmd.
domain.header) +
846 sizeof(cmd.
domain.country_code) +
876 memset(&cmd, 0,
sizeof(cmd));
919 memset(&cmd, 0,
sizeof(cmd));
940 static void lbs_queue_cmd(
struct lbs_private *priv,
952 if (!cmdnode->
cmdbuf->size) {
980 lbs_deb_host(
"QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
987 static void lbs_submit_command(
struct lbs_private *priv,
1005 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1014 lbs_deb_cmd(
"DNLD_CMD: command 0x%04x, seq %d, size %d\n",
1021 netdev_info(priv->
dev,
"DNLD_CMD: hw_host_to_card failed: %d\n",
1047 static void __lbs_cleanup_and_insert_cmd(
struct lbs_private *priv,
1065 static void lbs_cleanup_and_insert_cmd(
struct lbs_private *priv,
1068 unsigned long flags;
1071 __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1072 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1084 list_del_init(&cmd->
list);
1091 __lbs_cleanup_and_insert_cmd(priv, cmd);
1099 unsigned long flags;
1102 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1135 lbs_deb_cmd(
"RADIO_CONTROL: radio %s, preamble %d\n",
1136 radio_on ?
"ON" :
"OFF", preamble);
1197 if (!(cmdarray = kzalloc(bufsize,
GFP_KERNEL))) {
1198 lbs_deb_host(
"ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1207 if (!cmdarray[i].
cmdbuf) {
1208 lbs_deb_host(
"ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1216 lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
1249 if (cmdarray[i].
cmdbuf) {
1250 kfree(cmdarray[i].cmdbuf);
1278 unsigned long flags;
1287 if (!list_empty(&priv->
cmdfreeq)) {
1290 list_del_init(&tempnode->
list);
1292 lbs_deb_host(
"GET_CMD_NODE: cmd_ctrl_node is not available\n");
1296 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1314 unsigned long flags;
1325 netdev_alert(priv->
dev,
1326 "EXEC_NEXT_CMD: already processing command!\n");
1327 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1337 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1346 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1353 "0x%04x in psstate %d\n",
1392 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1397 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1407 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1416 "EXEC_NEXT_CMD: sending EXIT_PS\n");
1420 list_del_init(&cmdnode->
list);
1421 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1422 lbs_deb_host(
"EXEC_NEXT_CMD: sending command 0x%04x\n",
1424 lbs_submit_command(priv, cmdnode);
1442 lbs_mesh_connected(priv))) {
1443 if (priv->secinfo.WPAenabled ||
1444 priv->secinfo.WPA2enabled) {
1446 if (priv->wpa_mcast_key.len ||
1447 priv->wpa_unicast_key.len) {
1449 "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1450 " go back to PS_SLEEP");
1457 "EXEC_NEXT_CMD: cmdpendingq empty, "
1458 "go back to PS_SLEEP");
1472 static void lbs_send_confirmsleep(
struct lbs_private *priv)
1474 unsigned long flags;
1484 netdev_alert(priv->
dev,
"confirm_sleep failed\n");
1502 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1518 unsigned long flags =0;
1540 spin_unlock_irqrestore(&priv->
driver_lock, flags);
1544 lbs_send_confirmsleep(priv);
1571 memset(&cmd, 0,
sizeof(cmd));
1603 memset(&cmd, 0,
sizeof(cmd));
1628 cmdnode = ERR_PTR(-
ENOENT);
1637 lbs_deb_cmd(
"command not allowed in deep sleep\n");
1638 cmdnode = ERR_PTR(-
EBUSY);
1643 cmdnode = lbs_get_free_cmd_node(priv);
1644 if (cmdnode ==
NULL) {
1662 cmdnode->
cmdbuf->result = 0;
1667 lbs_queue_cmd(priv, cmdnode);
1680 lbs_cmd_async_callback, 0);
1690 unsigned long flags;
1697 if (IS_ERR(cmdnode)) {
1698 ret = PTR_ERR(cmdnode);
1714 netdev_info(priv->
dev,
"PREP_CMD: command 0x%04x failed: %d\n",
1717 __lbs_cleanup_and_insert_cmd(priv, cmdnode);
1718 spin_unlock_irqrestore(&priv->
driver_lock, flags);