const u8 *prev_bssid;
 };
 
+/**
+ * enum cfg80211_connect_params_changed - Connection parameters being updated
+ *
+ * This enum provides information of all connect parameters that
+ * have to be updated as part of update_connect_params() call.
+ *
+ * @UPDATE_ASSOC_IES: Indicates whether association request IEs are updated
+ */
+enum cfg80211_connect_params_changed {
+       UPDATE_ASSOC_IES                = BIT(0),
+};
+
 /**
  * enum wiphy_params_flags - set_wiphy_params bitfield values
  * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
  *     cases, the result of roaming is indicated with a call to
  *     cfg80211_roamed() or cfg80211_roamed_bss().
  *     (invoked with the wireless_dev mutex held)
+ * @update_connect_params: Update the connect parameters while connected to a
+ *     BSS. The updated parameters can be used by driver/firmware for
+ *     subsequent BSS selection (roaming) decisions and to form the
+ *     Authentication/(Re)Association Request frames. This call does not
+ *     request an immediate disassociation or reassociation with the current
+ *     BSS, i.e., this impacts only subsequent (re)associations. The bits in
+ *     changed are defined in &enum cfg80211_connect_params_changed.
+ *     (invoked with the wireless_dev mutex held)
  * @disconnect: Disconnect from the BSS/ESS or stop connection attempts if
  *      connection is in progress. Once done, call cfg80211_disconnected() in
  *      case connection was already established (invoked with the
 
        int     (*connect)(struct wiphy *wiphy, struct net_device *dev,
                           struct cfg80211_connect_params *sme);
+       int     (*update_connect_params)(struct wiphy *wiphy,
+                                        struct net_device *dev,
+                                        struct cfg80211_connect_params *sme,
+                                        u32 changed);
        int     (*disconnect)(struct wiphy *wiphy, struct net_device *dev,
                              u16 reason_code);
 
 
  *     This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
  *     %NL80211_ATTR_COOKIE.
  *
+ * @NL80211_CMD_UPDATE_CONNECT_PARAMS: Update one or more connect parameters
+ *     for subsequent roaming cases if the driver or firmware uses internal
+ *     BSS selection. This command can be issued only while connected and it
+ *     does not result in a change for the current association. Currently,
+ *     only the %NL80211_ATTR_IE data is used and updated with this command.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
 
        NL80211_CMD_SET_MULTICAST_TO_UNICAST,
 
+       NL80211_CMD_UPDATE_CONNECT_PARAMS,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
 
                                        NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
                                CMD(add_tx_ts, ADD_TX_TS);
                        CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
+                       CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
                }
 #undef CMD
 
        return err;
 }
 
+static int nl80211_update_connect_params(struct sk_buff *skb,
+                                        struct genl_info *info)
+{
+       struct cfg80211_connect_params connect = {};
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       u32 changed = 0;
+       int ret;
+
+       if (!rdev->ops->update_connect_params)
+               return -EOPNOTSUPP;
+
+       if (info->attrs[NL80211_ATTR_IE]) {
+               if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+                       return -EINVAL;
+               connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+               connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+               changed |= UPDATE_ASSOC_IES;
+       }
+
+       wdev_lock(dev->ieee80211_ptr);
+       if (!wdev->current_bss)
+               ret = -ENOLINK;
+       else
+               ret = rdev_update_connect_params(rdev, dev, &connect, changed);
+       wdev_unlock(dev->ieee80211_ptr);
+
+       return ret;
+}
+
 static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
+       {
+               .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
+               .doit = nl80211_update_connect_params,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
        {
                .cmd = NL80211_CMD_DISCONNECT,
                .doit = nl80211_disconnect,
 
        return ret;
 }
 
+static inline int
+rdev_update_connect_params(struct cfg80211_registered_device *rdev,
+                          struct net_device *dev,
+                          struct cfg80211_connect_params *sme, u32 changed)
+{
+       int ret;
+       trace_rdev_update_connect_params(&rdev->wiphy, dev, sme, changed);
+       ret = rdev->ops->update_connect_params(&rdev->wiphy, dev, sme, changed);
+       trace_rdev_return_int(&rdev->wiphy, ret);
+       return ret;
+}
+
 static inline int rdev_disconnect(struct cfg80211_registered_device *rdev,
                                  struct net_device *dev, u16 reason_code)
 {
 
                  __entry->wpa_versions, __entry->flags, MAC_PR_ARG(prev_bssid))
 );
 
+TRACE_EVENT(rdev_update_connect_params,
+       TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+                struct cfg80211_connect_params *sme, u32 changed),
+       TP_ARGS(wiphy, netdev, sme, changed),
+       TP_STRUCT__entry(
+               WIPHY_ENTRY
+               NETDEV_ENTRY
+               __field(u32, changed)
+       ),
+       TP_fast_assign(
+               WIPHY_ASSIGN;
+               NETDEV_ASSIGN;
+               __entry->changed = changed;
+       ),
+       TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", parameters changed: %u",
+                 WIPHY_PR_ARG, NETDEV_PR_ARG,  __entry->changed)
+);
+
 TRACE_EVENT(rdev_set_cqm_rssi_config,
        TP_PROTO(struct wiphy *wiphy,
                 struct net_device *netdev, s32 rssi_thold,