#define PORT_DATA_OFFSET 4
 #define H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN 12
-#define H2C_LEN_CXDRVINFO_ROLE (4 + 12 * RTW89_PORT_NUM + H2C_LEN_CXDRVHDR)
-#define H2C_LEN_CXDRVINFO_ROLE_V1 (4 + 16 * RTW89_PORT_NUM + \
-                                  H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + \
-                                  H2C_LEN_CXDRVHDR)
+#define H2C_LEN_CXDRVINFO_ROLE_SIZE(max_role_num) \
+       (4 + 12 * (max_role_num) + H2C_LEN_CXDRVHDR)
+
 int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev)
 {
        struct rtw89_btc *btc = &rtwdev->btc;
+       const struct rtw89_btc_ver *ver = btc->ver;
        struct rtw89_btc_wl_info *wl = &btc->cx.wl;
        struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
        struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
        struct rtw89_btc_wl_active_role *active = role_info->active_role;
        struct sk_buff *skb;
+       u32 len;
        u8 offset = 0;
        u8 *cmd;
        int ret;
        int i;
 
-       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE);
+       len = H2C_LEN_CXDRVINFO_ROLE_SIZE(ver->max_role_num);
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
        if (!skb) {
                rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
                return -ENOMEM;
        }
-       skb_put(skb, H2C_LEN_CXDRVINFO_ROLE);
+       skb_put(skb, len);
        cmd = skb->data;
 
        RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
-       RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE - H2C_LEN_CXDRVHDR);
+       RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
 
        RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
        RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
                              H2C_CAT_OUTSRC, BTFC_SET,
                              SET_DRV_INFO, 0, 0,
-                             H2C_LEN_CXDRVINFO_ROLE);
+                             len);
 
        ret = rtw89_h2c_tx(rtwdev, skb, false);
        if (ret) {
        return ret;
 }
 
+#define H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(max_role_num) \
+       (4 + 16 * (max_role_num) + H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN + H2C_LEN_CXDRVHDR)
+
 int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev)
 {
        struct rtw89_btc *btc = &rtwdev->btc;
+       const struct rtw89_btc_ver *ver = btc->ver;
        struct rtw89_btc_wl_info *wl = &btc->cx.wl;
        struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
        struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
        struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
        struct sk_buff *skb;
+       u32 len;
        u8 *cmd, offset;
        int ret;
        int i;
 
-       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_LEN_CXDRVINFO_ROLE_V1);
+       len = H2C_LEN_CXDRVINFO_ROLE_SIZE_V1(ver->max_role_num);
+
+       skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
        if (!skb) {
                rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
                return -ENOMEM;
        }
-       skb_put(skb, H2C_LEN_CXDRVINFO_ROLE_V1);
+       skb_put(skb, len);
        cmd = skb->data;
 
        RTW89_SET_FWCMD_CXHDR_TYPE(cmd, CXDRVINFO_ROLE);
-       RTW89_SET_FWCMD_CXHDR_LEN(cmd, H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVHDR);
+       RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
 
        RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
        RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
                RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
        }
 
-       offset = H2C_LEN_CXDRVINFO_ROLE_V1 - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
+       offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
        RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
        RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
        RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
        rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
                              H2C_CAT_OUTSRC, BTFC_SET,
                              SET_DRV_INFO, 0, 0,
-                             H2C_LEN_CXDRVINFO_ROLE_V1);
+                             len);
 
        ret = rtw89_h2c_tx(rtwdev, skb, false);
        if (ret) {