Lines Matching +full:firmware +full:- +full:initialized

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
9 #include <linux/firmware.h>
21 #define WILC1000_FW_PREFIX "atmel/wilc1000_wifi_firmware-"
29 if (wilc->close) { in isr_uh_routine()
40 if (wilc->close) { in isr_bh_routine()
53 struct wilc *wl = vif->wilc; in init_irq()
56 ret = request_threaded_irq(wl->dev_irq_num, isr_uh_routine, in init_irq()
64 netdev_dbg(dev, "IRQ request succeeded IRQ-NUM= %d\n", wl->dev_irq_num); in init_irq()
72 struct wilc *wilc = vif->wilc; in deinit_irq()
75 if (wilc->dev_irq_num) in deinit_irq()
76 free_irq(wilc->dev_irq_num, wilc); in deinit_irq()
84 if (wilc->mac_status == WILC_MAC_STATUS_INIT) { in wilc_mac_indicate()
85 wilc->mac_status = status; in wilc_mac_indicate()
86 complete(&wilc->sync_event); in wilc_mac_indicate()
88 wilc->mac_status = status; in wilc_mac_indicate()
98 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { in get_if_handler()
99 if (vif->mode == WILC_STATION_MODE) in get_if_handler()
100 if (ether_addr_equal_unaligned(h->addr2, vif->bssid)) { in get_if_handler()
101 ndev = vif->ndev; in get_if_handler()
104 if (vif->mode == WILC_AP_MODE) in get_if_handler()
105 if (ether_addr_equal_unaligned(h->addr1, vif->bssid)) { in get_if_handler()
106 ndev = vif->ndev; in get_if_handler()
119 ether_addr_copy(vif->bssid, bssid); in wilc_wlan_set_bssid()
121 eth_zero_addr(vif->bssid); in wilc_wlan_set_bssid()
123 vif->mode = mode; in wilc_wlan_set_bssid()
132 srcu_idx = srcu_read_lock(&wilc->srcu); in wilc_wlan_get_num_conn_ifcs()
133 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { in wilc_wlan_get_num_conn_ifcs()
134 if (!is_zero_ether_addr(vif->bssid)) in wilc_wlan_get_num_conn_ifcs()
137 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_wlan_get_num_conn_ifcs()
147 complete(&wl->txq_thread_started); in wilc_txq_task()
149 wait_for_completion(&wl->txq_event); in wilc_txq_task()
151 if (wl->close) { in wilc_txq_task()
152 complete(&wl->txq_thread_started); in wilc_txq_task()
164 srcu_idx = srcu_read_lock(&wl->srcu); in wilc_txq_task()
165 list_for_each_entry_rcu(ifc, &wl->vif_list, in wilc_txq_task()
167 if (ifc->mac_opened && ifc->ndev) in wilc_txq_task()
168 netif_wake_queue(ifc->ndev); in wilc_txq_task()
170 srcu_read_unlock(&wl->srcu, srcu_idx); in wilc_txq_task()
172 } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close); in wilc_txq_task()
180 struct wilc *wilc = vif->wilc; in wilc_wlan_get_firmware()
182 const struct firmware *wilc_fw; in wilc_wlan_get_firmware()
187 netdev_info(dev, "ChipID [%x] loading firmware [%s]\n", chip_id, in wilc_wlan_get_firmware()
191 wilc->dev); in wilc_wlan_get_firmware()
193 netdev_err(dev, "%s - firmware not available\n", in wilc_wlan_get_firmware()
195 return -EINVAL; in wilc_wlan_get_firmware()
197 wilc->firmware = wilc_fw; in wilc_wlan_get_firmware()
205 struct wilc *wilc = vif->wilc; in wilc_start_firmware()
212 if (!wait_for_completion_timeout(&wilc->sync_event, in wilc_start_firmware()
214 return -ETIME; in wilc_start_firmware()
222 struct wilc *wilc = vif->wilc; in wilc1000_firmware_download()
225 if (!wilc->firmware) { in wilc1000_firmware_download()
226 netdev_err(dev, "Firmware buffer is NULL\n"); in wilc1000_firmware_download()
227 return -ENOBUFS; in wilc1000_firmware_download()
230 ret = wilc_wlan_firmware_download(wilc, wilc->firmware->data, in wilc1000_firmware_download()
231 wilc->firmware->size); in wilc1000_firmware_download()
235 release_firmware(wilc->firmware); in wilc1000_firmware_download()
236 wilc->firmware = NULL; in wilc1000_firmware_download()
245 struct wilc_priv *priv = &vif->priv; in wilc_init_fw_config()
251 netdev_dbg(dev, "Start configuring Firmware\n"); in wilc_init_fw_config()
252 hif_drv = (struct host_if_drv *)priv->hif_drv; in wilc_init_fw_config()
255 w = vif->iftype; in wilc_init_fw_config()
411 return -EINVAL; in wilc_init_fw_config()
417 struct wilc *wl = vif->wilc; in wlan_deinitialize_threads()
419 wl->close = 1; in wlan_deinitialize_threads()
421 complete(&wl->txq_event); in wlan_deinitialize_threads()
423 if (wl->txq_thread) { in wlan_deinitialize_threads()
424 kthread_stop(wl->txq_thread); in wlan_deinitialize_threads()
425 wl->txq_thread = NULL; in wlan_deinitialize_threads()
432 struct wilc *wl = vif->wilc; in wilc_wlan_deinitialize()
439 if (wl->initialized) { in wilc_wlan_deinitialize()
442 if (!wl->dev_irq_num && in wilc_wlan_deinitialize()
443 wl->hif_func->disable_interrupt) { in wilc_wlan_deinitialize()
444 mutex_lock(&wl->hif_cs); in wilc_wlan_deinitialize()
445 wl->hif_func->disable_interrupt(wl); in wilc_wlan_deinitialize()
446 mutex_unlock(&wl->hif_cs); in wilc_wlan_deinitialize()
448 complete(&wl->txq_event); in wilc_wlan_deinitialize()
456 wl->initialized = false; in wilc_wlan_deinitialize()
460 netdev_dbg(dev, "wilc1000 is not initialized\n"); in wilc_wlan_deinitialize()
467 struct wilc *wilc = vif->wilc; in wlan_initialize_threads()
469 wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc, in wlan_initialize_threads()
471 if (IS_ERR(wilc->txq_thread)) { in wlan_initialize_threads()
473 wilc->close = 0; in wlan_initialize_threads()
474 return PTR_ERR(wilc->txq_thread); in wlan_initialize_threads()
476 wait_for_completion(&wilc->txq_thread_started); in wlan_initialize_threads()
484 struct wilc *wl = vif->wilc; in wilc_wlan_initialize()
486 if (!wl->initialized) { in wilc_wlan_initialize()
487 wl->mac_status = WILC_MAC_STATUS_INIT; in wilc_wlan_initialize()
488 wl->close = 0; in wilc_wlan_initialize()
498 if (wl->dev_irq_num && init_irq(dev)) { in wilc_wlan_initialize()
499 ret = -EIO; in wilc_wlan_initialize()
503 if (!wl->dev_irq_num && in wilc_wlan_initialize()
504 wl->hif_func->enable_interrupt && in wilc_wlan_initialize()
505 wl->hif_func->enable_interrupt(wl)) { in wilc_wlan_initialize()
506 ret = -EIO; in wilc_wlan_initialize()
530 netdev_dbg(dev, "Firmware Ver = %s\n", firmware_ver); in wilc_wlan_initialize()
535 netdev_err(dev, "Failed to configure firmware\n"); in wilc_wlan_initialize()
538 wl->initialized = true; in wilc_wlan_initialize()
545 if (!wl->dev_irq_num && in wilc_wlan_initialize()
546 wl->hif_func->disable_interrupt) in wilc_wlan_initialize()
547 wl->hif_func->disable_interrupt(wl); in wilc_wlan_initialize()
549 if (wl->dev_irq_num) in wilc_wlan_initialize()
557 netdev_dbg(dev, "wilc1000 already initialized\n"); in wilc_wlan_initialize()
573 struct wilc *wl = vif->wilc; in wilc_mac_open()
577 if (!wl || !wl->dev) { in wilc_mac_open()
579 return -ENODEV; in wilc_mac_open()
594 wilc_set_operation_mode(vif, wilc_get_vif_idx(vif), vif->iftype, in wilc_mac_open()
595 vif->idx); in wilc_mac_open()
597 if (is_valid_ether_addr(ndev->dev_addr)) in wilc_mac_open()
598 wilc_set_mac_address(vif, ndev->dev_addr); in wilc_mac_open()
600 wilc_get_mac_address(vif, ndev->dev_addr); in wilc_mac_open()
601 netdev_dbg(ndev, "Mac address: %pM\n", ndev->dev_addr); in wilc_mac_open()
603 if (!is_valid_ether_addr(ndev->dev_addr)) { in wilc_mac_open()
607 return -EINVAL; in wilc_mac_open()
610 mgmt_regs.interface_stypes = vif->mgmt_reg_stypes; in wilc_mac_open()
612 vif->mgmt_reg_stypes = 0; in wilc_mac_open()
613 wilc_update_mgmt_frame_registrations(vif->ndev->ieee80211_ptr->wiphy, in wilc_mac_open()
614 vif->ndev->ieee80211_ptr, in wilc_mac_open()
617 wl->open_ifcs++; in wilc_mac_open()
618 vif->mac_opened = 1; in wilc_mac_open()
626 return &vif->netstats; in mac_stats()
633 struct wilc *wilc = vif->wilc; in wilc_set_mac_addr()
639 if (!is_valid_ether_addr(addr->sa_data)) in wilc_set_mac_addr()
640 return -EADDRNOTAVAIL; in wilc_set_mac_addr()
642 if (!vif->mac_opened) { in wilc_set_mac_addr()
649 srcu_idx = srcu_read_lock(&wilc->srcu); in wilc_set_mac_addr()
650 list_for_each_entry_rcu(tmp_vif, &wilc->vif_list, list) { in wilc_set_mac_addr()
652 if (ether_addr_equal(addr->sa_data, mac_addr)) { in wilc_set_mac_addr()
654 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_set_mac_addr()
655 return -EADDRNOTAVAIL; in wilc_set_mac_addr()
657 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_set_mac_addr()
661 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_set_mac_addr()
663 result = wilc_set_mac_address(vif, (u8 *)addr->sa_data); in wilc_set_mac_addr()
679 if (dev->flags & IFF_PROMISC) in wilc_set_multicast_list()
682 if (dev->flags & IFF_ALLMULTI || in wilc_set_multicast_list()
683 dev->mc.count > WILC_MULTICAST_TABLE_SIZE) { in wilc_set_multicast_list()
688 if (dev->mc.count == 0) { in wilc_set_multicast_list()
693 mc_list = kmalloc_array(dev->mc.count, ETH_ALEN, GFP_ATOMIC); in wilc_set_multicast_list()
700 memcpy(cur_mc, ha->addr, ETH_ALEN); in wilc_set_multicast_list()
706 if (wilc_setup_multicast_filter(vif, 1, dev->mc.count, mc_list)) in wilc_set_multicast_list()
714 dev_kfree_skb(pv_data->skb); in wilc_tx_complete()
721 struct wilc *wilc = vif->wilc; in wilc_mac_xmit()
725 if (skb->dev != ndev) { in wilc_mac_xmit()
737 tx_data->buff = skb->data; in wilc_mac_xmit()
738 tx_data->size = skb->len; in wilc_mac_xmit()
739 tx_data->skb = skb; in wilc_mac_xmit()
741 vif->netstats.tx_packets++; in wilc_mac_xmit()
742 vif->netstats.tx_bytes += tx_data->size; in wilc_mac_xmit()
744 tx_data->buff, tx_data->size, in wilc_mac_xmit()
751 srcu_idx = srcu_read_lock(&wilc->srcu); in wilc_mac_xmit()
752 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { in wilc_mac_xmit()
753 if (vif->mac_opened) in wilc_mac_xmit()
754 netif_stop_queue(vif->ndev); in wilc_mac_xmit()
756 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_mac_xmit()
765 struct wilc *wl = vif->wilc; in wilc_mac_close()
769 if (wl->open_ifcs > 0) in wilc_mac_close()
770 wl->open_ifcs--; in wilc_mac_close()
774 if (vif->ndev) { in wilc_mac_close()
775 netif_stop_queue(vif->ndev); in wilc_mac_close()
777 wilc_deinit_host_int(vif->ndev); in wilc_mac_close()
780 if (wl->open_ifcs == 0) { in wilc_mac_close()
782 wl->close = 1; in wilc_mac_close()
786 vif->mac_opened = 0; in wilc_mac_close()
819 skb->dev = wilc_netdev; in wilc_frmw_to_host()
823 skb->protocol = eth_type_trans(skb, wilc_netdev); in wilc_frmw_to_host()
824 vif->netstats.rx_packets++; in wilc_frmw_to_host()
825 vif->netstats.rx_bytes += frame_len; in wilc_frmw_to_host()
826 skb->ip_summed = CHECKSUM_UNNECESSARY; in wilc_frmw_to_host()
837 srcu_idx = srcu_read_lock(&wilc->srcu); in wilc_wfi_mgmt_rx()
838 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { in wilc_wfi_mgmt_rx()
842 if (vif->priv.p2p_listen_state && in wilc_wfi_mgmt_rx()
843 vif->mgmt_reg_stypes & type_bit) in wilc_wfi_mgmt_rx()
846 if (vif->monitor_flag) in wilc_wfi_mgmt_rx()
847 wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size); in wilc_wfi_mgmt_rx()
849 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_wfi_mgmt_rx()
870 if (wilc->firmware) { in wilc_netdev_cleanup()
871 release_firmware(wilc->firmware); in wilc_netdev_cleanup()
872 wilc->firmware = NULL; in wilc_netdev_cleanup()
875 srcu_idx = srcu_read_lock(&wilc->srcu); in wilc_netdev_cleanup()
876 list_for_each_entry_rcu(vif, &wilc->vif_list, list) { in wilc_netdev_cleanup()
877 if (vif->ndev) in wilc_netdev_cleanup()
878 unregister_netdev(vif->ndev); in wilc_netdev_cleanup()
880 srcu_read_unlock(&wilc->srcu, srcu_idx); in wilc_netdev_cleanup()
883 flush_workqueue(wilc->hif_workqueue); in wilc_netdev_cleanup()
884 destroy_workqueue(wilc->hif_workqueue); in wilc_netdev_cleanup()
887 mutex_lock(&wilc->vif_mutex); in wilc_netdev_cleanup()
888 if (wilc->vif_num <= 0) { in wilc_netdev_cleanup()
889 mutex_unlock(&wilc->vif_mutex); in wilc_netdev_cleanup()
894 list_del_rcu(&vif->list); in wilc_netdev_cleanup()
896 wilc->vif_num--; in wilc_netdev_cleanup()
897 mutex_unlock(&wilc->vif_mutex); in wilc_netdev_cleanup()
898 synchronize_srcu(&wilc->srcu); in wilc_netdev_cleanup()
904 kfree(wilc->bus_data); in wilc_netdev_cleanup()
905 wiphy_unregister(wilc->wiphy); in wilc_netdev_cleanup()
906 wiphy_free(wilc->wiphy); in wilc_netdev_cleanup()
916 srcu_idx = srcu_read_lock(&wl->srcu); in wilc_get_available_idx()
917 list_for_each_entry_rcu(vif, &wl->vif_list, list) { in wilc_get_available_idx()
918 if (vif->idx == 0) in wilc_get_available_idx()
923 srcu_read_unlock(&wl->srcu, srcu_idx); in wilc_get_available_idx()
937 return ERR_PTR(-ENOMEM); in wilc_netdev_ifc_init()
940 ndev->ieee80211_ptr = &vif->priv.wdev; in wilc_netdev_ifc_init()
941 strcpy(ndev->name, name); in wilc_netdev_ifc_init()
942 vif->wilc = wl; in wilc_netdev_ifc_init()
943 vif->ndev = ndev; in wilc_netdev_ifc_init()
944 ndev->ml_priv = vif; in wilc_netdev_ifc_init()
946 ndev->netdev_ops = &wilc_netdev_ops; in wilc_netdev_ifc_init()
948 SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy)); in wilc_netdev_ifc_init()
950 vif->priv.wdev.wiphy = wl->wiphy; in wilc_netdev_ifc_init()
951 vif->priv.wdev.netdev = ndev; in wilc_netdev_ifc_init()
952 vif->priv.wdev.iftype = type; in wilc_netdev_ifc_init()
953 vif->priv.dev = ndev; in wilc_netdev_ifc_init()
962 return ERR_PTR(-EFAULT); in wilc_netdev_ifc_init()
965 ndev->needs_free_netdev = true; in wilc_netdev_ifc_init()
966 vif->iftype = vif_type; in wilc_netdev_ifc_init()
967 vif->idx = wilc_get_available_idx(wl); in wilc_netdev_ifc_init()
968 vif->mac_opened = 0; in wilc_netdev_ifc_init()
969 mutex_lock(&wl->vif_mutex); in wilc_netdev_ifc_init()
970 list_add_tail_rcu(&vif->list, &wl->vif_list); in wilc_netdev_ifc_init()
971 wl->vif_num += 1; in wilc_netdev_ifc_init()
972 mutex_unlock(&wl->vif_mutex); in wilc_netdev_ifc_init()
973 synchronize_srcu(&wl->srcu); in wilc_netdev_ifc_init()