Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac802154: iface: fix order while interface up

This patch moves the hardware setting before calling the driver start
callback which activates the receive handling. The hardware setup
contains settings like address filtering which should be setup before
activate the receive handling on the transceiver. These setting are
protected by ieee802154_check_concurrent_iface check. This means we
need to set these registers once before calling drv_start and can't
be overwritten by other interfaces.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Alexander Aring and committed by
Marcel Holtmann
95c0aa15 52cc9168

+55 -48
+55 -48
net/mac802154/iface.c
··· 135 135 return mac802154_wpan_update_llsec(dev); 136 136 } 137 137 138 + static int ieee802154_setup_hw(struct ieee802154_sub_if_data *sdata) 139 + { 140 + struct ieee802154_local *local = sdata->local; 141 + struct wpan_dev *wpan_dev = &sdata->wpan_dev; 142 + int ret; 143 + 144 + if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { 145 + ret = drv_set_promiscuous_mode(local, 146 + wpan_dev->promiscuous_mode); 147 + if (ret < 0) 148 + return ret; 149 + } 150 + 151 + if (local->hw.flags & IEEE802154_HW_AFILT) { 152 + ret = drv_set_pan_id(local, wpan_dev->pan_id); 153 + if (ret < 0) 154 + return ret; 155 + 156 + ret = drv_set_extended_addr(local, wpan_dev->extended_addr); 157 + if (ret < 0) 158 + return ret; 159 + 160 + ret = drv_set_short_addr(local, wpan_dev->short_addr); 161 + if (ret < 0) 162 + return ret; 163 + } 164 + 165 + if (local->hw.flags & IEEE802154_HW_LBT) { 166 + ret = drv_set_lbt_mode(local, wpan_dev->lbt); 167 + if (ret < 0) 168 + return ret; 169 + } 170 + 171 + if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { 172 + ret = drv_set_csma_params(local, wpan_dev->min_be, 173 + wpan_dev->max_be, 174 + wpan_dev->csma_retries); 175 + if (ret < 0) 176 + return ret; 177 + } 178 + 179 + if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { 180 + ret = drv_set_max_frame_retries(local, wpan_dev->frame_retries); 181 + if (ret < 0) 182 + return ret; 183 + } 184 + 185 + return 0; 186 + } 187 + 138 188 static int mac802154_slave_open(struct net_device *dev) 139 189 { 140 190 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); ··· 196 146 set_bit(SDATA_STATE_RUNNING, &sdata->state); 197 147 198 148 if (!local->open_count) { 149 + res = ieee802154_setup_hw(sdata); 150 + if (res) 151 + goto err; 152 + 199 153 res = drv_start(local); 200 154 if (res) 201 155 goto err; ··· 293 239 { 294 240 int rc; 295 241 struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev); 296 - struct ieee802154_local *local = sdata->local; 297 242 struct wpan_dev *wpan_dev = &sdata->wpan_dev; 298 243 299 244 rc = ieee802154_check_concurrent_iface(sdata, wpan_dev->iftype); 300 245 if (rc < 0) 301 246 return rc; 302 247 303 - rc = mac802154_slave_open(dev); 304 - if (rc < 0) 305 - return rc; 306 - 307 - if (local->hw.flags & IEEE802154_HW_PROMISCUOUS) { 308 - rc = drv_set_promiscuous_mode(local, 309 - wpan_dev->promiscuous_mode); 310 - if (rc < 0) 311 - goto out; 312 - } 313 - 314 - if (local->hw.flags & IEEE802154_HW_AFILT) { 315 - rc = drv_set_pan_id(local, wpan_dev->pan_id); 316 - if (rc < 0) 317 - goto out; 318 - 319 - rc = drv_set_extended_addr(local, wpan_dev->extended_addr); 320 - if (rc < 0) 321 - goto out; 322 - 323 - rc = drv_set_short_addr(local, wpan_dev->short_addr); 324 - if (rc < 0) 325 - goto out; 326 - } 327 - 328 - if (local->hw.flags & IEEE802154_HW_LBT) { 329 - rc = drv_set_lbt_mode(local, wpan_dev->lbt); 330 - if (rc < 0) 331 - goto out; 332 - } 333 - 334 - if (local->hw.flags & IEEE802154_HW_CSMA_PARAMS) { 335 - rc = drv_set_csma_params(local, wpan_dev->min_be, 336 - wpan_dev->max_be, 337 - wpan_dev->csma_retries); 338 - if (rc < 0) 339 - goto out; 340 - } 341 - 342 - if (local->hw.flags & IEEE802154_HW_FRAME_RETRIES) { 343 - rc = drv_set_max_frame_retries(local, wpan_dev->frame_retries); 344 - if (rc < 0) 345 - goto out; 346 - } 347 - 348 - out: 349 - return rc; 248 + return mac802154_slave_open(dev); 350 249 } 351 250 352 251 static int mac802154_slave_close(struct net_device *dev)