bool ieee80211_operating_class_to_band(u8 operating_class,
                                       enum ieee80211_band *band);
 
+/**
+ * ieee80211_chandef_to_operating_class - convert chandef to operation class
+ *
+ * @chandef: the chandef to convert
+ * @op_class: a pointer to the resulting operating class
+ *
+ * Returns %true if the conversion was successful, %false otherwise.
+ */
+bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
+                                         u8 *op_class);
+
 /*
  * cfg80211_tdls_oper_request - request userspace to perform TDLS operation
  * @dev: the device on which the operation is requested
 
        *pos = 2 * subband_cnt;
 }
 
+static void ieee80211_tdls_add_oper_classes(struct ieee80211_sub_if_data *sdata,
+                                           struct sk_buff *skb)
+{
+       u8 *pos;
+       u8 op_class;
+
+       if (!ieee80211_chandef_to_operating_class(&sdata->vif.bss_conf.chandef,
+                                                 &op_class))
+               return;
+
+       pos = skb_put(skb, 4);
+       *pos++ = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
+       *pos++ = 2; /* len */
+
+       *pos++ = op_class;
+       *pos++ = op_class; /* give current operating class as alternate too */
+}
+
 static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb)
 {
        u8 *pos = (void *)skb_put(skb, 3);
                }
        }
 
+       ieee80211_tdls_add_oper_classes(sdata, skb);
+
        /*
         * with TDLS we can switch channels, and HT-caps are not necessarily
         * the same on all bands. The specification limits the setup to a
                               50 + /* supported channels */
                               3 + /* 40/20 BSS coex */
                               4 + /* AID */
+                              4 + /* oper classes */
                               extra_ies_len +
                               sizeof(struct ieee80211_tdls_lnkie));
        if (!skb)
 
 }
 EXPORT_SYMBOL(ieee80211_operating_class_to_band);
 
+bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
+                                         u8 *op_class)
+{
+       u8 vht_opclass;
+       u16 freq = chandef->center_freq1;
+
+       if (freq >= 2412 && freq <= 2472) {
+               if (chandef->width > NL80211_CHAN_WIDTH_40)
+                       return false;
+
+               /* 2.407 GHz, channels 1..13 */
+               if (chandef->width == NL80211_CHAN_WIDTH_40) {
+                       if (freq > chandef->chan->center_freq)
+                               *op_class = 83; /* HT40+ */
+                       else
+                               *op_class = 84; /* HT40- */
+               } else {
+                       *op_class = 81;
+               }
+
+               return true;
+       }
+
+       if (freq == 2484) {
+               if (chandef->width > NL80211_CHAN_WIDTH_40)
+                       return false;
+
+               *op_class = 82; /* channel 14 */
+               return true;
+       }
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_80:
+               vht_opclass = 128;
+               break;
+       case NL80211_CHAN_WIDTH_160:
+               vht_opclass = 129;
+               break;
+       case NL80211_CHAN_WIDTH_80P80:
+               vht_opclass = 130;
+               break;
+       case NL80211_CHAN_WIDTH_10:
+       case NL80211_CHAN_WIDTH_5:
+               return false; /* unsupported for now */
+       default:
+               vht_opclass = 0;
+               break;
+       }
+
+       /* 5 GHz, channels 36..48 */
+       if (freq >= 5180 && freq <= 5240) {
+               if (vht_opclass) {
+                       *op_class = vht_opclass;
+               } else if (chandef->width == NL80211_CHAN_WIDTH_40) {
+                       if (freq > chandef->chan->center_freq)
+                               *op_class = 116;
+                       else
+                               *op_class = 117;
+               } else {
+                       *op_class = 115;
+               }
+
+               return true;
+       }
+
+       /* 5 GHz, channels 52..64 */
+       if (freq >= 5260 && freq <= 5320) {
+               if (vht_opclass) {
+                       *op_class = vht_opclass;
+               } else if (chandef->width == NL80211_CHAN_WIDTH_40) {
+                       if (freq > chandef->chan->center_freq)
+                               *op_class = 119;
+                       else
+                               *op_class = 120;
+               } else {
+                       *op_class = 118;
+               }
+
+               return true;
+       }
+
+       /* 5 GHz, channels 100..144 */
+       if (freq >= 5500 && freq <= 5720) {
+               if (vht_opclass) {
+                       *op_class = vht_opclass;
+               } else if (chandef->width == NL80211_CHAN_WIDTH_40) {
+                       if (freq > chandef->chan->center_freq)
+                               *op_class = 122;
+                       else
+                               *op_class = 123;
+               } else {
+                       *op_class = 121;
+               }
+
+               return true;
+       }
+
+       /* 5 GHz, channels 149..169 */
+       if (freq >= 5745 && freq <= 5845) {
+               if (vht_opclass) {
+                       *op_class = vht_opclass;
+               } else if (chandef->width == NL80211_CHAN_WIDTH_40) {
+                       if (freq > chandef->chan->center_freq)
+                               *op_class = 126;
+                       else
+                               *op_class = 127;
+               } else if (freq <= 5805) {
+                       *op_class = 124;
+               } else {
+                       *op_class = 125;
+               }
+
+               return true;
+       }
+
+       /* 56.16 GHz, channel 1..4 */
+       if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
+               if (chandef->width >= NL80211_CHAN_WIDTH_40)
+                       return false;
+
+               *op_class = 180;
+               return true;
+       }
+
+       /* not supported yet */
+       return false;
+}
+EXPORT_SYMBOL(ieee80211_chandef_to_operating_class);
+
 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
                                 u32 beacon_int)
 {