aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r--drivers/net/wireless/libertas/cmd.c76
1 files changed, 67 insertions, 9 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index c4b32a05de10..bb940cce3a73 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -11,6 +11,7 @@
11#include "dev.h" 11#include "dev.h"
12#include "join.h" 12#include "join.h"
13#include "wext.h" 13#include "wext.h"
14#include "cmd.h"
14 15
15static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode); 16static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
16struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv); 17struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
@@ -36,18 +37,78 @@ static u8 is_command_allowed_in_ps(u16 cmd)
36 return 0; 37 return 0;
37} 38}
38 39
39static int lbs_cmd_hw_spec(struct lbs_private *priv, struct cmd_ds_command *cmd) 40/**
41 * @brief Updates the hardware details like MAC address and regulatory region
42 *
43 * @param priv A pointer to struct lbs_private structure
44 *
45 * @return 0 on success, error on failure
46 */
47int lbs_update_hw_spec(struct lbs_private *priv)
40{ 48{
41 struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec; 49 struct cmd_ds_get_hw_spec cmd;
50 int ret = -1;
51 u32 i;
52 DECLARE_MAC_BUF(mac);
42 53
43 lbs_deb_enter(LBS_DEB_CMD); 54 lbs_deb_enter(LBS_DEB_CMD);
44 55
45 cmd->command = cpu_to_le16(CMD_GET_HW_SPEC); 56 memset(&cmd, 0, sizeof(cmd));
46 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN); 57 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
47 memcpy(hwspec->permanentaddr, priv->current_addr, ETH_ALEN); 58 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
59 ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, cmd);
60 if (ret)
61 goto out;
62
63 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
64 memcpy(priv->fwreleasenumber, cmd.fwreleasenumber, 4);
65
66 lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
67 priv->fwreleasenumber[2], priv->fwreleasenumber[1],
68 priv->fwreleasenumber[0], priv->fwreleasenumber[3]);
69 lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
70 print_mac(mac, cmd.permanentaddr));
71 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
72 cmd.hwifversion, cmd.version);
73
74 /* Clamp region code to 8-bit since FW spec indicates that it should
75 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
76 * returns non-zero high 8 bits here.
77 */
78 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
79
80 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
81 /* use the region code to search for the index */
82 if (priv->regioncode == lbs_region_code_to_index[i])
83 break;
84 }
48 85
86 /* if it's unidentified region code, use the default (USA) */
87 if (i >= MRVDRV_MAX_REGION_CODE) {
88 priv->regioncode = 0x10;
89 lbs_pr_info("unidentified region code; using the default (USA)\n");
90 }
91
92 if (priv->current_addr[0] == 0xff)
93 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
94
95 memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
96 if (priv->mesh_dev)
97 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
98
99 if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
100 ret = -1;
101 goto out;
102 }
103
104 if (lbs_set_universaltable(priv, 0)) {
105 ret = -1;
106 goto out;
107 }
108
109out:
49 lbs_deb_leave(LBS_DEB_CMD); 110 lbs_deb_leave(LBS_DEB_CMD);
50 return 0; 111 return ret;
51} 112}
52 113
53static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv, 114static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
@@ -1223,9 +1284,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1223 cmdptr->result = 0; 1284 cmdptr->result = 0;
1224 1285
1225 switch (cmd_no) { 1286 switch (cmd_no) {
1226 case CMD_GET_HW_SPEC:
1227 ret = lbs_cmd_hw_spec(priv, cmdptr);
1228 break;
1229 case CMD_802_11_PS_MODE: 1287 case CMD_802_11_PS_MODE:
1230 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); 1288 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
1231 break; 1289 break;