Lines Matching refs:wdev

156 bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor)
158 if (wdev->hw_caps.api_version_major < major)
160 if (wdev->hw_caps.api_version_major > major)
162 if (wdev->hw_caps.api_version_minor < minor)
174 int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len)
179 dev_err(wdev->dev, "PDS: malformed file (legacy format?)\n");
186 dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num);
190 dev_info(wdev->dev, "PDS:%d: skip unknown data\n", chunk_num);
194 dev_warn(wdev->dev, "PDS:%d: unexpectedly large chunk\n", chunk_num);
196 dev_warn(wdev->dev, "PDS:%d: unexpected content\n", chunk_num);
198 ret = wfx_hif_configuration(wdev, buf + 4, chunk_len - 4);
200 dev_err(wdev->dev, "PDS:%d: invalid data (unsupported options?)\n", chunk_num);
204 dev_err(wdev->dev, "PDS:%d: chip didn't reply (corrupted file?)\n", chunk_num);
208 dev_err(wdev->dev, "PDS:%d: chip returned an unknown error\n", chunk_num);
219 static int wfx_send_pdata_pds(struct wfx_dev *wdev)
225 ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev);
227 dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n",
228 wdev->pdata.file_pds);
236 ret = wfx_send_pds(wdev, tmp_buf, pds->size);
245 struct wfx_dev *wdev = data;
247 mutex_destroy(&wdev->tx_power_loop_info_lock);
248 mutex_destroy(&wdev->rx_stats_lock);
249 mutex_destroy(&wdev->conf_mutex);
250 ieee80211_free_hw(wdev->hw);
257 struct wfx_dev *wdev;
302 wdev = hw->priv;
303 wdev->hw = hw;
304 wdev->dev = dev;
305 wdev->hwbus_ops = hwbus_ops;
306 wdev->hwbus_priv = hwbus_priv;
307 memcpy(&wdev->pdata, pdata, sizeof(*pdata));
308 of_property_read_string(dev->of_node, "silabs,antenna-config-file", &wdev->pdata.file_pds);
309 wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW);
310 if (IS_ERR(wdev->pdata.gpio_wakeup))
313 if (wdev->pdata.gpio_wakeup)
314 gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup");
316 mutex_init(&wdev->conf_mutex);
317 mutex_init(&wdev->rx_stats_lock);
318 mutex_init(&wdev->tx_power_loop_info_lock);
319 init_completion(&wdev->firmware_ready);
320 INIT_DELAYED_WORK(&wdev->cooling_timeout_work, wfx_cooling_timeout_work);
321 skb_queue_head_init(&wdev->tx_pending);
322 init_waitqueue_head(&wdev->tx_dequeue);
323 wfx_init_hif_cmd(&wdev->hif_cmd);
325 if (devm_add_action_or_reset(dev, wfx_free_common, wdev))
328 return wdev;
335 int wfx_probe(struct wfx_dev *wdev)
344 gpio_saved = wdev->pdata.gpio_wakeup;
345 wdev->pdata.gpio_wakeup = NULL;
346 wdev->poll_irq = true;
348 wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI, 0);
349 if (!wdev->bh_wq)
352 wfx_bh_register(wdev);
354 err = wfx_init_device(wdev);
358 wfx_bh_poll_irq(wdev);
359 err = wait_for_completion_timeout(&wdev->firmware_ready, 1 * HZ);
361 dev_err(wdev->dev, "timeout while waiting for startup indication\n");
367 dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n",
368 wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor,
369 wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label,
370 wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor,
371 wdev->keyset, wdev->hw_caps.link_mode);
372 snprintf(wdev->hw->wiphy->fw_version,
373 sizeof(wdev->hw->wiphy->fw_version),
375 wdev->hw_caps.firmware_major,
376 wdev->hw_caps.firmware_minor,
377 wdev->hw_caps.firmware_build);
379 if (wfx_api_older_than(wdev, 1, 0)) {
380 dev_err(wdev->dev, "unsupported firmware API version (expect 1 while firmware returns %d)\n",
381 wdev->hw_caps.api_version_major);
386 if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) {
387 dev_err(wdev->dev, "chip require secure_link, but can't negotiate it\n");
391 if (wdev->hw_caps.region_sel_mode) {
392 wdev->hw->wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
393 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |=
395 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |=
397 wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |=
401 dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds);
402 err = wfx_send_pdata_pds(wdev);
406 wdev->poll_irq = false;
407 err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv);
411 err = wfx_hif_use_multi_tx_conf(wdev, true);
413 dev_err(wdev->dev, "misconfigured IRQ?\n");
415 wdev->pdata.gpio_wakeup = gpio_saved;
416 if (wdev->pdata.gpio_wakeup) {
417 dev_dbg(wdev->dev, "enable 'quiescent' power mode with wakeup GPIO and PDS file %s\n",
418 wdev->pdata.file_pds);
419 gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
420 wfx_control_reg_write(wdev, 0);
421 wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_QUIESCENT);
423 wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_DOZE);
426 for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) {
427 eth_zero_addr(wdev->addresses[i].addr);
428 err = of_get_mac_address(wdev->dev->of_node, wdev->addresses[i].addr);
430 wdev->addresses[i].addr[ETH_ALEN - 1] += i;
432 ether_addr_copy(wdev->addresses[i].addr, wdev->hw_caps.mac_addr[i]);
433 if (!is_valid_ether_addr(wdev->addresses[i].addr)) {
434 dev_warn(wdev->dev, "using random MAC address\n");
435 eth_random_addr(wdev->addresses[i].addr);
437 dev_info(wdev->dev, "MAC address %d: %pM\n", i, wdev->addresses[i].addr);
439 wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses);
440 wdev->hw->wiphy->addresses = wdev->addresses;
442 if (!wfx_api_older_than(wdev, 3, 8))
443 wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
445 err = ieee80211_register_hw(wdev->hw);
449 err = wfx_debug_init(wdev);
456 ieee80211_unregister_hw(wdev->hw);
458 wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
460 wfx_bh_unregister(wdev);
461 destroy_workqueue(wdev->bh_wq);
465 void wfx_release(struct wfx_dev *wdev)
467 ieee80211_unregister_hw(wdev->hw);
468 wfx_hif_shutdown(wdev);
469 wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
470 wfx_bh_unregister(wdev);
471 destroy_workqueue(wdev->bh_wq);