1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * MLO link handling 4 * 5 * Copyright (C) 2022 Intel Corporation 6 */ 7 #include <linux/slab.h> 8 #include <linux/kernel.h> 9 #include <net/mac80211.h> 10 #include "ieee80211_i.h" 11 #include "driver-ops.h" 12 13 void ieee80211_link_setup(struct ieee80211_link_data *link) 14 { 15 if (link->sdata->vif.type == NL80211_IFTYPE_STATION) 16 ieee80211_mgd_setup_link(link); 17 } 18 19 void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, 20 int link_id, 21 struct ieee80211_link_data *link, 22 struct ieee80211_bss_conf *link_conf) 23 { 24 bool deflink = link_id < 0; 25 26 if (link_id < 0) 27 link_id = 0; 28 29 rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); 30 rcu_assign_pointer(sdata->link[link_id], link); 31 32 link->sdata = sdata; 33 link->link_id = link_id; 34 link->conf = link_conf; 35 link_conf->link_id = link_id; 36 37 INIT_WORK(&link->csa_finalize_work, 38 ieee80211_csa_finalize_work); 39 INIT_WORK(&link->color_change_finalize_work, 40 ieee80211_color_change_finalize_work); 41 INIT_LIST_HEAD(&link->assigned_chanctx_list); 42 INIT_LIST_HEAD(&link->reserved_chanctx_list); 43 INIT_DELAYED_WORK(&link->dfs_cac_timer_work, 44 ieee80211_dfs_cac_timer_work); 45 46 if (!deflink) { 47 switch (sdata->vif.type) { 48 case NL80211_IFTYPE_AP: 49 ether_addr_copy(link_conf->addr, 50 sdata->wdev.links[link_id].addr); 51 link_conf->bssid = link_conf->addr; 52 WARN_ON(!(sdata->wdev.valid_links & BIT(link_id))); 53 break; 54 case NL80211_IFTYPE_STATION: 55 /* station sets the bssid in ieee80211_mgd_setup_link */ 56 break; 57 default: 58 WARN_ON(1); 59 } 60 } 61 } 62 63 void ieee80211_link_stop(struct ieee80211_link_data *link) 64 { 65 if (link->sdata->vif.type == NL80211_IFTYPE_STATION) 66 ieee80211_mgd_stop_link(link); 67 68 ieee80211_link_release_channel(link); 69 } 70 71 struct link_container { 72 struct ieee80211_link_data data; 73 struct ieee80211_bss_conf conf; 74 }; 75 76 static void ieee80211_free_links(struct ieee80211_sub_if_data *sdata, 77 struct link_container **links) 78 { 79 LIST_HEAD(keys); 80 unsigned int link_id; 81 82 for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { 83 if (!links[link_id]) 84 continue; 85 ieee80211_remove_link_keys(&links[link_id]->data, &keys); 86 } 87 88 synchronize_rcu(); 89 90 ieee80211_free_key_list(sdata->local, &keys); 91 92 for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { 93 if (!links[link_id]) 94 continue; 95 ieee80211_link_stop(&links[link_id]->data); 96 kfree(links[link_id]); 97 } 98 } 99 100 static int ieee80211_check_dup_link_addrs(struct ieee80211_sub_if_data *sdata) 101 { 102 unsigned int i, j; 103 104 for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { 105 struct ieee80211_link_data *link1; 106 107 link1 = sdata_dereference(sdata->link[i], sdata); 108 if (!link1) 109 continue; 110 for (j = i + 1; j < IEEE80211_MLD_MAX_NUM_LINKS; j++) { 111 struct ieee80211_link_data *link2; 112 113 link2 = sdata_dereference(sdata->link[j], sdata); 114 if (!link2) 115 continue; 116 117 if (ether_addr_equal(link1->conf->addr, 118 link2->conf->addr)) 119 return -EALREADY; 120 } 121 } 122 123 return 0; 124 } 125 126 static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, 127 struct link_container **to_free, 128 u16 new_links) 129 { 130 u16 old_links = sdata->vif.valid_links; 131 unsigned long add = new_links & ~old_links; 132 unsigned long rem = old_links & ~new_links; 133 unsigned int link_id; 134 int ret; 135 struct link_container *links[IEEE80211_MLD_MAX_NUM_LINKS] = {}, *link; 136 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]; 137 struct ieee80211_link_data *old_data[IEEE80211_MLD_MAX_NUM_LINKS]; 138 bool use_deflink = old_links == 0; /* set for error case */ 139 140 sdata_assert_lock(sdata); 141 142 memset(to_free, 0, sizeof(links)); 143 144 if (old_links == new_links) 145 return 0; 146 147 /* if there were no old links, need to clear the pointers to deflink */ 148 if (!old_links) 149 rem |= BIT(0); 150 151 /* allocate new link structures first */ 152 for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { 153 link = kzalloc(sizeof(*link), GFP_KERNEL); 154 if (!link) { 155 ret = -ENOMEM; 156 goto free; 157 } 158 links[link_id] = link; 159 } 160 161 /* keep track of the old pointers for the driver */ 162 BUILD_BUG_ON(sizeof(old) != sizeof(sdata->vif.link_conf)); 163 memcpy(old, sdata->vif.link_conf, sizeof(old)); 164 /* and for us in error cases */ 165 BUILD_BUG_ON(sizeof(old_data) != sizeof(sdata->link)); 166 memcpy(old_data, sdata->link, sizeof(old_data)); 167 168 /* grab old links to free later */ 169 for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) { 170 if (rcu_access_pointer(sdata->link[link_id]) != &sdata->deflink) { 171 /* 172 * we must have allocated the data through this path so 173 * we know we can free both at the same time 174 */ 175 to_free[link_id] = container_of(rcu_access_pointer(sdata->link[link_id]), 176 typeof(*links[link_id]), 177 data); 178 } 179 180 RCU_INIT_POINTER(sdata->link[link_id], NULL); 181 RCU_INIT_POINTER(sdata->vif.link_conf[link_id], NULL); 182 } 183 184 /* link them into data structures */ 185 for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { 186 WARN_ON(!use_deflink && 187 rcu_access_pointer(sdata->link[link_id]) == &sdata->deflink); 188 189 link = links[link_id]; 190 ieee80211_link_init(sdata, link_id, &link->data, &link->conf); 191 ieee80211_link_setup(&link->data); 192 } 193 194 if (new_links == 0) 195 ieee80211_link_init(sdata, -1, &sdata->deflink, 196 &sdata->vif.bss_conf); 197 198 sdata->vif.valid_links = new_links; 199 200 ret = ieee80211_check_dup_link_addrs(sdata); 201 if (!ret) { 202 /* tell the driver */ 203 ret = drv_change_vif_links(sdata->local, sdata, 204 old_links, new_links, 205 old); 206 } 207 208 if (ret) { 209 /* restore config */ 210 memcpy(sdata->link, old_data, sizeof(old_data)); 211 memcpy(sdata->vif.link_conf, old, sizeof(old)); 212 sdata->vif.valid_links = old_links; 213 /* and free (only) the newly allocated links */ 214 memset(to_free, 0, sizeof(links)); 215 goto free; 216 } 217 218 /* use deflink/bss_conf again if and only if there are no more links */ 219 use_deflink = new_links == 0; 220 221 goto deinit; 222 free: 223 /* if we failed during allocation, only free all */ 224 for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { 225 kfree(links[link_id]); 226 links[link_id] = NULL; 227 } 228 deinit: 229 if (use_deflink) 230 ieee80211_link_init(sdata, -1, &sdata->deflink, 231 &sdata->vif.bss_conf); 232 return ret; 233 } 234 235 int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata, 236 u16 new_links) 237 { 238 struct link_container *links[IEEE80211_MLD_MAX_NUM_LINKS]; 239 int ret; 240 241 ret = ieee80211_vif_update_links(sdata, links, new_links); 242 ieee80211_free_links(sdata, links); 243 244 return ret; 245 } 246 247 void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata) 248 { 249 struct link_container *links[IEEE80211_MLD_MAX_NUM_LINKS]; 250 251 /* 252 * The locking here is different because when we free links 253 * in the station case we need to be able to cancel_work_sync() 254 * something that also takes the lock. 255 */ 256 257 sdata_lock(sdata); 258 ieee80211_vif_update_links(sdata, links, 0); 259 sdata_unlock(sdata); 260 261 ieee80211_free_links(sdata, links); 262 } 263