Lines Matching refs:wdev

158 bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor)  in wfx_api_older_than()  argument
160 if (wdev->hw_caps.api_version_major < major) in wfx_api_older_than()
162 if (wdev->hw_caps.api_version_major > major) in wfx_api_older_than()
164 if (wdev->hw_caps.api_version_minor < minor) in wfx_api_older_than()
176 int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len) in wfx_send_pds() argument
181 dev_err(wdev->dev, "PDS: malformed file (legacy format?)\n"); in wfx_send_pds()
188 dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num); in wfx_send_pds()
192 dev_info(wdev->dev, "PDS:%d: skip unknown data\n", chunk_num); in wfx_send_pds()
196 dev_warn(wdev->dev, "PDS:%d: unexpectedly large chunk\n", chunk_num); in wfx_send_pds()
198 dev_warn(wdev->dev, "PDS:%d: unexpected content\n", chunk_num); in wfx_send_pds()
200 ret = wfx_hif_configuration(wdev, buf + 4, chunk_len - 4); in wfx_send_pds()
202 dev_err(wdev->dev, "PDS:%d: invalid data (unsupported options?)\n", chunk_num); in wfx_send_pds()
206 dev_err(wdev->dev, "PDS:%d: chip didn't reply (corrupted file?)\n", chunk_num); in wfx_send_pds()
210 dev_err(wdev->dev, "PDS:%d: chip returned an unknown error\n", chunk_num); in wfx_send_pds()
221 static int wfx_send_pdata_pds(struct wfx_dev *wdev) in wfx_send_pdata_pds() argument
227 ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev); in wfx_send_pdata_pds()
229 dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n", in wfx_send_pdata_pds()
230 wdev->pdata.file_pds); in wfx_send_pdata_pds()
238 ret = wfx_send_pds(wdev, tmp_buf, pds->size); in wfx_send_pdata_pds()
247 struct wfx_dev *wdev = data; in wfx_free_common() local
249 mutex_destroy(&wdev->tx_power_loop_info_lock); in wfx_free_common()
250 mutex_destroy(&wdev->rx_stats_lock); in wfx_free_common()
251 mutex_destroy(&wdev->scan_lock); in wfx_free_common()
252 mutex_destroy(&wdev->conf_mutex); in wfx_free_common()
253 ieee80211_free_hw(wdev->hw); in wfx_free_common()
260 struct wfx_dev *wdev; in wfx_init_common() local
306 wdev = hw->priv; in wfx_init_common()
307 wdev->hw = hw; in wfx_init_common()
308 wdev->dev = dev; in wfx_init_common()
309 wdev->hwbus_ops = hwbus_ops; in wfx_init_common()
310 wdev->hwbus_priv = hwbus_priv; in wfx_init_common()
311 memcpy(&wdev->pdata, pdata, sizeof(*pdata)); in wfx_init_common()
312 of_property_read_string(dev->of_node, "silabs,antenna-config-file", &wdev->pdata.file_pds); in wfx_init_common()
313 wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW); in wfx_init_common()
314 if (IS_ERR(wdev->pdata.gpio_wakeup)) in wfx_init_common()
317 if (wdev->pdata.gpio_wakeup) in wfx_init_common()
318 gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); in wfx_init_common()
320 mutex_init(&wdev->conf_mutex); in wfx_init_common()
321 mutex_init(&wdev->scan_lock); in wfx_init_common()
322 mutex_init(&wdev->rx_stats_lock); in wfx_init_common()
323 mutex_init(&wdev->tx_power_loop_info_lock); in wfx_init_common()
324 init_completion(&wdev->firmware_ready); in wfx_init_common()
325 INIT_DELAYED_WORK(&wdev->cooling_timeout_work, wfx_cooling_timeout_work); in wfx_init_common()
326 skb_queue_head_init(&wdev->tx_pending); in wfx_init_common()
327 init_waitqueue_head(&wdev->tx_dequeue); in wfx_init_common()
328 wfx_init_hif_cmd(&wdev->hif_cmd); in wfx_init_common()
330 if (devm_add_action_or_reset(dev, wfx_free_common, wdev)) in wfx_init_common()
333 return wdev; in wfx_init_common()
340 int wfx_probe(struct wfx_dev *wdev) in wfx_probe() argument
349 gpio_saved = wdev->pdata.gpio_wakeup; in wfx_probe()
350 wdev->pdata.gpio_wakeup = NULL; in wfx_probe()
351 wdev->poll_irq = true; in wfx_probe()
353 wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI, 0); in wfx_probe()
354 if (!wdev->bh_wq) in wfx_probe()
357 wfx_bh_register(wdev); in wfx_probe()
359 err = wfx_init_device(wdev); in wfx_probe()
363 wfx_bh_poll_irq(wdev); in wfx_probe()
364 err = wait_for_completion_timeout(&wdev->firmware_ready, 1 * HZ); in wfx_probe()
366 dev_err(wdev->dev, "timeout while waiting for startup indication\n"); in wfx_probe()
372 dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n", in wfx_probe()
373 wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor, in wfx_probe()
374 wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label, in wfx_probe()
375 wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor, in wfx_probe()
376 wdev->keyset, wdev->hw_caps.link_mode); in wfx_probe()
377 snprintf(wdev->hw->wiphy->fw_version, in wfx_probe()
378 sizeof(wdev->hw->wiphy->fw_version), in wfx_probe()
380 wdev->hw_caps.firmware_major, in wfx_probe()
381 wdev->hw_caps.firmware_minor, in wfx_probe()
382 wdev->hw_caps.firmware_build); in wfx_probe()
384 if (wfx_api_older_than(wdev, 1, 0)) { in wfx_probe()
385 dev_err(wdev->dev, "unsupported firmware API version (expect 1 while firmware returns %d)\n", in wfx_probe()
386 wdev->hw_caps.api_version_major); in wfx_probe()
391 if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) { in wfx_probe()
392 dev_err(wdev->dev, "chip require secure_link, but can't negotiate it\n"); in wfx_probe()
396 if (wdev->hw_caps.region_sel_mode) { in wfx_probe()
397 wdev->hw->wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS; in wfx_probe()
398 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |= in wfx_probe()
400 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |= in wfx_probe()
402 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |= in wfx_probe()
406 dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds); in wfx_probe()
407 err = wfx_send_pdata_pds(wdev); in wfx_probe()
411 wdev->poll_irq = false; in wfx_probe()
412 err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv); in wfx_probe()
416 err = wfx_hif_use_multi_tx_conf(wdev, true); in wfx_probe()
418 dev_err(wdev->dev, "misconfigured IRQ?\n"); in wfx_probe()
420 wdev->pdata.gpio_wakeup = gpio_saved; in wfx_probe()
421 if (wdev->pdata.gpio_wakeup) { in wfx_probe()
422 dev_dbg(wdev->dev, "enable 'quiescent' power mode with wakeup GPIO and PDS file %s\n", in wfx_probe()
423 wdev->pdata.file_pds); in wfx_probe()
424 gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); in wfx_probe()
425 wfx_control_reg_write(wdev, 0); in wfx_probe()
426 wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_QUIESCENT); in wfx_probe()
428 wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_DOZE); in wfx_probe()
431 for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) { in wfx_probe()
432 eth_zero_addr(wdev->addresses[i].addr); in wfx_probe()
433 err = of_get_mac_address(wdev->dev->of_node, wdev->addresses[i].addr); in wfx_probe()
435 wdev->addresses[i].addr[ETH_ALEN - 1] += i; in wfx_probe()
437 ether_addr_copy(wdev->addresses[i].addr, wdev->hw_caps.mac_addr[i]); in wfx_probe()
438 if (!is_valid_ether_addr(wdev->addresses[i].addr)) { in wfx_probe()
439 dev_warn(wdev->dev, "using random MAC address\n"); in wfx_probe()
440 eth_random_addr(wdev->addresses[i].addr); in wfx_probe()
442 dev_info(wdev->dev, "MAC address %d: %pM\n", i, wdev->addresses[i].addr); in wfx_probe()
444 wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses); in wfx_probe()
445 wdev->hw->wiphy->addresses = wdev->addresses; in wfx_probe()
447 if (!wfx_api_older_than(wdev, 3, 8)) in wfx_probe()
448 wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; in wfx_probe()
450 err = ieee80211_register_hw(wdev->hw); in wfx_probe()
454 err = wfx_debug_init(wdev); in wfx_probe()
461 ieee80211_unregister_hw(wdev->hw); in wfx_probe()
463 wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); in wfx_probe()
465 wfx_bh_unregister(wdev); in wfx_probe()
466 destroy_workqueue(wdev->bh_wq); in wfx_probe()
470 void wfx_release(struct wfx_dev *wdev) in wfx_release() argument
472 ieee80211_unregister_hw(wdev->hw); in wfx_release()
473 wfx_hif_shutdown(wdev); in wfx_release()
474 wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); in wfx_release()
475 wfx_bh_unregister(wdev); in wfx_release()
476 destroy_workqueue(wdev->bh_wq); in wfx_release()