u8 action_code;
                                        u8 variable[0];
                                } __packed chan_switch;
+                               struct{
+                                       u8 action_code;
+                                       struct ieee80211_ext_chansw_ie data;
+                                       u8 variable[0];
+                               } __packed ext_chan_switch;
                                struct{
                                        u8 action_code;
                                        u8 dialog_token;
 
 /* Public action codes */
 enum ieee80211_pub_actioncode {
+       WLAN_PUB_ACTION_EXT_CHANSW_ANN = 4,
        WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14,
 };
 
 
        enum rx_mgmt_action rma = RX_MGMT_NONE;
        u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
        u16 fc;
+       struct ieee802_11_elems elems;
+       int ies_len;
 
        rx_status = (struct ieee80211_rx_status *) skb->cb;
        mgmt = (struct ieee80211_mgmt *) skb->data;
                break;
        case IEEE80211_STYPE_ACTION:
                if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
-                       struct ieee802_11_elems elems;
-                       int ies_len = skb->len -
-                                     offsetof(struct ieee80211_mgmt,
-                                              u.action.u.chan_switch.variable);
+                       ies_len = skb->len -
+                                 offsetof(struct ieee80211_mgmt,
+                                          u.action.u.chan_switch.variable);
 
                        if (ies_len < 0)
                                break;
                        if (elems.parse_error)
                                break;
 
+                       ieee80211_sta_process_chanswitch(sdata,
+                                                        rx_status->mactime,
+                                                        &elems);
+               } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
+                       ies_len = skb->len -
+                                 offsetof(struct ieee80211_mgmt,
+                                          u.action.u.ext_chan_switch.variable);
+
+                       if (ies_len < 0)
+                               break;
+
+                       ieee802_11_parse_elems(
+                               mgmt->u.action.u.ext_chan_switch.variable,
+                               ies_len, &elems);
+
+                       if (elems.parse_error)
+                               break;
+
+                       /* for the handling code pretend this was also an IE */
+                       elems.ext_chansw_ie =
+                               &mgmt->u.action.u.ext_chan_switch.data;
+
                        ieee80211_sta_process_chanswitch(sdata,
                                                         rx_status->mactime,
                                                         &elems);
 
                }
 
                break;
+       case WLAN_CATEGORY_PUBLIC:
+               if (len < IEEE80211_MIN_ACTION_SIZE + 1)
+                       goto invalid;
+               if (sdata->vif.type != NL80211_IFTYPE_STATION)
+                       break;
+               if (!rx->sta)
+                       break;
+               if (!ether_addr_equal(mgmt->bssid, sdata->u.mgd.bssid))
+                       break;
+               if (mgmt->u.action.u.ext_chan_switch.action_code !=
+                               WLAN_PUB_ACTION_EXT_CHANSW_ANN)
+                       break;
+               if (len < offsetof(struct ieee80211_mgmt,
+                                  u.action.u.ext_chan_switch.variable))
+                       goto invalid;
+               goto queue;
        case WLAN_CATEGORY_VHT:
                if (sdata->vif.type != NL80211_IFTYPE_STATION &&
                    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&