libertas: support mesh for various firmware versions
authorBing Zhao <bzhao@marvell.com>
Wed, 25 Mar 2009 16:51:16 +0000 (09:51 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 22 Apr 2009 20:54:26 +0000 (16:54 -0400)
CMD_MESH_CONFIG command ID and a couple of structure members in TxPD,
RxPD have been changed in firmware version 10.x.y.z and newer.

Signed-off-by: Kiran Divekar <dkiran@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/host.h
drivers/net/wireless/libertas/hostcmd.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/types.h

index 8c3605c..c455b9a 100644 (file)
@@ -119,6 +119,19 @@ int lbs_update_hw_spec(struct lbs_private *priv)
        lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
                    cmd.hwifversion, cmd.version);
 
+       /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+       /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+       /* 5.110.22 have mesh command with 0xa3 command id */
+       /* 10.0.0.p0 FW brings in mesh config command with different id */
+       /* Check FW version MSB and initialize mesh_fw_ver */
+       if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
+               priv->mesh_fw_ver = MESH_FW_OLD;
+       else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+               (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
+               priv->mesh_fw_ver = MESH_FW_NEW;
+       else
+               priv->mesh_fw_ver = MESH_NONE;
+
        /* Clamp region code to 8-bit since FW spec indicates that it should
         * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
         * returns non-zero high 8 bits here.
@@ -1036,17 +1049,26 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
                                  uint16_t action, uint16_t type)
 {
        int ret;
+       u16 command = CMD_MESH_CONFIG_OLD;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
+       /*
+        * Command id is 0xac for v10 FW along with mesh interface
+        * id in bits 14-13-12.
+        */
+       if (priv->mesh_fw_ver == MESH_FW_NEW)
+               command = CMD_MESH_CONFIG |
+                         (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+       cmd->hdr.command = cpu_to_le16(command);
        cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
        cmd->hdr.result = 0;
 
        cmd->type = cpu_to_le16(type);
        cmd->action = cpu_to_le16(action);
 
-       ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+       ret = lbs_cmd_with_response(priv, command, cmd);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return ret;
index e8dfde3..48da157 100644 (file)
@@ -227,6 +227,20 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define TxPD_CONTROL_WDS_FRAME (1<<17)
 #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
 
+/** Mesh interface ID */
+#define MESH_IFACE_ID                                  0x0001
+/** Mesh id should be in bits 14-13-12 */
+#define MESH_IFACE_BIT_OFFSET                          0x000c
+/** Mesh enable bit in FW capability */
+#define MESH_CAPINFO_ENABLE_MASK                       (1<<16)
+
+/** FW definition from Marvell v5 */
+#define MRVL_FW_V5                                     (0x05)
+/** FW definition from Marvell v10 */
+#define MRVL_FW_V10                                    (0x0a)
+/** FW major revision definition */
+#define MRVL_FW_MAJOR_REV(x)                           ((x)>>24)
+
 /** RxPD status */
 
 #define MRVDRV_RXPD_STATUS_OK                0x0001
@@ -380,6 +394,13 @@ enum KEY_INFO_WPA {
        KEY_INFO_WPA_ENABLED = 0x04
 };
 
+/** mesh_fw_ver */
+enum _mesh_fw_ver {
+       MESH_NONE = 0, /* MESH is not supported */
+       MESH_FW_OLD,   /* MESH is supported in FW V5 */
+       MESH_FW_NEW,   /* MESH is supported in FW V10 and newer */
+};
+
 /* Default values for fwt commands. */
 #define FWT_DEFAULT_METRIC 0
 #define FWT_DEFAULT_DIR 1
index 27e81fd..cbaafa6 100644 (file)
@@ -101,6 +101,7 @@ struct lbs_mesh_stats {
 /** Private structure for the MV device */
 struct lbs_private {
        int mesh_open;
+       int mesh_fw_ver;
        int infra_open;
        int mesh_autostart_enabled;
 
index d4457ef..8ff8ac9 100644 (file)
@@ -83,7 +83,8 @@
 #define CMD_FWT_ACCESS                         0x0095
 #define CMD_802_11_MONITOR_MODE                        0x0098
 #define CMD_MESH_ACCESS                                0x009b
-#define CMD_MESH_CONFIG                                0x00a3
+#define CMD_MESH_CONFIG_OLD                    0x00a3
+#define CMD_MESH_CONFIG                                0x00ac
 #define        CMD_SET_BOOT2_VER                       0x00a5
 #define CMD_802_11_BEACON_CTRL                 0x00b0
 
Simple merge
Simple merge
Simple merge
Simple merge