return ret;
 }
 
-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
-                           void *buf, size_t buf_len, int index, u32 rates)
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+                           u16 template_id, void *buf, size_t buf_len,
+                           int index, u32 rates)
 {
        struct wl1271_cmd_template_set *cmd;
        int ret = 0;
                goto out;
        }
 
+       /* during initialization wlvif is NULL */
+       cmd->role_id = role_id;
        cmd->len = cpu_to_le16(buf_len);
        cmd->template_type = template_id;
        cmd->enabled_rates = cpu_to_le32(rates);
                ptr = skb->data;
        }
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_NULL_DATA, ptr, size, 0,
                                      wlvif->basic_rate);
 
 out:
        if (!skb)
                goto out;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
                                      skb->data, skb->len,
                                      CMD_TEMPL_KLV_IDX_NULL_DATA,
                                      wlvif->basic_rate);
        if (!skb)
                goto out;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_PS_POLL, skb->data,
                                      skb->len, 0, wlvif->basic_rate_set);
 
 out:
        return ret;
 }
 
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                              u8 role_id, u8 band,
                               const u8 *ssid, size_t ssid_len,
-                              const u8 *ie, size_t ie_len, u8 band)
+                              const u8 *ie, size_t ie_len)
 {
        struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
        struct sk_buff *skb;
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
        if (band == IEEE80211_BAND_2GHZ)
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+               ret = wl1271_cmd_template_set(wl, role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_2_4,
                                              skb->data, skb->len, 0, rate);
        else
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+               ret = wl1271_cmd_template_set(wl, role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_5,
                                              skb->data, skb->len, 0, rate);
 
 out:
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
        if (wlvif->band == IEEE80211_BAND_2GHZ)
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_2_4,
                                              skb->data, skb->len, 0, rate);
        else
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                             CMD_TEMPL_CFG_PROBE_REQ_5,
                                              skb->data, skb->len, 0, rate);
 
        if (ret < 0)
        memcpy(tmpl.sender_hw, vif->addr, ETH_ALEN);
        tmpl.sender_ip = ip_addr;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP,
                                      &tmpl, sizeof(tmpl), 0,
                                      wlvif->basic_rate);
 
        /* FIXME: not sure what priority to use here */
        template.qos_ctrl = cpu_to_le16(0);
 
-       return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
+       return wl1271_cmd_template_set(wl, wlvif->role_id,
+                                      CMD_TEMPL_QOS_NULL_DATA, &template,
                                       sizeof(template), 0,
                                       wlvif->basic_rate);
 }
 
                       u8 ps_mode);
 int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
                           size_t len);
-int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
-                           void *buf, size_t buf_len, int index, u32 rates);
+int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
+                           u16 template_id, void *buf, size_t buf_len,
+                           int index, u32 rates);
 int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
                             u16 aid);
-int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+                              u8 role_id, u8 band,
                               const u8 *ssid, size_t ssid_len,
-                              const u8 *ie, size_t ie_len, u8 band);
+                              const u8 *ie, size_t ie_len);
 struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
                                              struct wl12xx_vif *wlvif,
                                              struct sk_buff *skb);
 /* unit ms */
 #define WL1271_COMMAND_TIMEOUT     2000
 #define WL1271_CMD_TEMPL_DFLT_SIZE 252
-#define WL1271_CMD_TEMPL_MAX_SIZE  548
+#define WL1271_CMD_TEMPL_MAX_SIZE  512
 #define WL1271_EVENT_TIMEOUT       750
 
 struct wl1271_cmd_header {
 struct wl1271_cmd_template_set {
        struct wl1271_cmd_header header;
 
-       __le16 len;
+       u8 role_id;
        u8 template_type;
+       __le16 len;
        u8 index;  /* relevant only for KLV_TEMPLATE type */
+       u8 padding[3];
+
        __le32 enabled_rates;
        u8 short_retry_limit;
        u8 long_retry_limit;
        u8 aflags;
        u8 reserved;
+
        u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
 } __packed;
 
 
        int ret, i;
 
        /* send empty templates for fw memory reservation */
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
                                      WL1271_CMD_TEMPL_DFLT_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_CFG_PROBE_REQ_5,
                                      NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0,
                                      WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_NULL_DATA, NULL,
                                      sizeof(struct wl12xx_null_data_template),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_PS_POLL, NULL,
                                      sizeof(struct wl12xx_ps_poll_template),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_QOS_NULL_DATA, NULL,
                                      sizeof
                                      (struct ieee80211_qos_hdr),
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_PROBE_RESPONSE, NULL,
                                      WL1271_CMD_TEMPL_DFLT_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_BEACON, NULL,
                                      WL1271_CMD_TEMPL_DFLT_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_ARP_RSP, NULL,
                                      sizeof
                                      (struct wl12xx_arp_rsp_template),
                                      0, WL1271_RATE_AUTOMATIC);
         * Put very large empty placeholders for all templates. These
         * reserve memory for later.
         */
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_AP_PROBE_RESPONSE, NULL,
                                      WL1271_CMD_TEMPL_MAX_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_AP_BEACON, NULL,
                                      WL1271_CMD_TEMPL_MAX_SIZE,
                                      0, WL1271_RATE_AUTOMATIC);
        if (ret < 0)
                return ret;
 
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL,
+       ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                     CMD_TEMPL_DEAUTH_AP, NULL,
                                      sizeof
                                      (struct wl12xx_disconn_template),
                                      0, WL1271_RATE_AUTOMATIC);
                return ret;
 
        for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) {
-               ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL,
+               ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID,
+                                             CMD_TEMPL_KLV, NULL,
                                              sizeof(struct ieee80211_qos_hdr),
                                              i, WL1271_RATE_AUTOMATIC);
                if (ret < 0)
                                             IEEE80211_STYPE_DEAUTH);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_DEAUTH_AP,
                                      tmpl, sizeof(*tmpl), 0, rate);
 
 out:
        memcpy(nullfunc->addr3, vif->addr, ETH_ALEN);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_NULL_DATA, nullfunc,
                                      sizeof(*nullfunc), 0, rate);
 
 out:
        memcpy(qosnull->addr3, vif->addr, ETH_ALEN);
 
        rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
-       ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
+                                     CMD_TEMPL_QOS_NULL_DATA, qosnull,
                                      sizeof(*qosnull), 0, rate);
 
 out:
 
         * is added. That is where we will initialize the hardware.
         */
 
-       return 0;
+       wl1271_error("wl12xx is in an ustable state (fw api update is "
+                    "taking place). skip this commit when bisecting");
+       return -EBUSY;
 }
 
 static void wl1271_op_stop(struct ieee80211_hw *hw)
 static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
                                         struct ieee80211_vif *vif)
 {
+       struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
        struct sk_buff *skb;
        int ret;
 
        if (!skb)
                return -EOPNOTSUPP;
 
-       ret = wl1271_cmd_template_set(wl,
+       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
                                      CMD_TEMPL_AP_PROBE_RESPONSE,
                                      skb->data,
                                      skb->len, 0,
 
        /* no need to change probe response if the SSID is set correctly */
        if (wlvif->ssid_len > 0)
-               return wl1271_cmd_template_set(wl,
+               return wl1271_cmd_template_set(wl, wlvif->role_id,
                                               CMD_TEMPL_AP_PROBE_RESPONSE,
                                               probe_rsp_data,
                                               probe_rsp_len, 0,
               ptr, probe_rsp_len - (ptr - probe_rsp_data));
        templ_len += probe_rsp_len - (ptr - probe_rsp_data);
 
-       return wl1271_cmd_template_set(wl,
+       return wl1271_cmd_template_set(wl, wlvif->role_id,
                                       CMD_TEMPL_AP_PROBE_RESPONSE,
                                       probe_rsp_templ,
                                       templ_len, 0,
                min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
                tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
                                  CMD_TEMPL_BEACON;
-               ret = wl1271_cmd_template_set(wl, tmpl_id,
+               ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
                                              beacon->data,
                                              beacon->len, 0,
                                              min_rate);
                                                beacon->len,
                                                min_rate);
                else
-                       ret = wl1271_cmd_template_set(wl,
+                       ret = wl1271_cmd_template_set(wl, wlvif->role_id,
                                                CMD_TEMPL_PROBE_RESPONSE,
                                                beacon->data,
                                                beacon->len, 0,
 
 
        memcpy(cmd->addr, vif->addr, ETH_ALEN);
 
-       ret = wl1271_cmd_build_probe_req(wl, wlvif, wl->scan.ssid,
-                                        wl->scan.ssid_len, wl->scan.req->ie,
-                                        wl->scan.req->ie_len, band);
+       ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                        wlvif->role_id, band,
+                                        wl->scan.ssid, wl->scan.ssid_len,
+                                        wl->scan.req->ie,
+                                        wl->scan.req->ie_len);
        if (ret < 0) {
                wl1271_error("PROBE request template failed");
                goto out;
        }
 
        if (!force_passive && cfg->active[0]) {
-               ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+               u8 band = IEEE80211_BAND_2GHZ;
+               ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                                wlvif->role_id, band,
+                                                req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
-                                                ies->ie[IEEE80211_BAND_2GHZ],
-                                                ies->len[IEEE80211_BAND_2GHZ],
-                                                IEEE80211_BAND_2GHZ);
+                                                ies->ie[band],
+                                                ies->len[band]);
                if (ret < 0) {
                        wl1271_error("2.4GHz PROBE request template failed");
                        goto out;
        }
 
        if (!force_passive && cfg->active[1]) {
-               ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid,
+               u8 band = IEEE80211_BAND_5GHZ;
+               ret = wl12xx_cmd_build_probe_req(wl, wlvif,
+                                                wlvif->role_id, band,
+                                                req->ssids[0].ssid,
                                                 req->ssids[0].ssid_len,
-                                                ies->ie[IEEE80211_BAND_5GHZ],
-                                                ies->len[IEEE80211_BAND_5GHZ],
-                                                IEEE80211_BAND_5GHZ);
+                                                ies->ie[band],
+                                                ies->len[band]);
                if (ret < 0) {
                        wl1271_error("5GHz PROBE request template failed");
                        goto out;
 
 #include "conf.h"
 #include "ini.h"
 
-#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin"
-#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin"
+#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-4-sr.bin"
+#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-4-sr.bin"
 
 /*
  * wl127x and wl128x are using the same NVS file name. However, the