diff --git a/otus/freebsd/src/sys/dev/athp/ath10k/htt_rx.c b/otus/freebsd/src/sys/dev/athp/ath10k/htt_rx.c index 1b7a0436..fc1d88e9 100644 --- a/otus/freebsd/src/sys/dev/athp/ath10k/htt_rx.c +++ b/otus/freebsd/src/sys/dev/athp/ath10k/htt_rx.c @@ -1473,7 +1473,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, */ if (!rx_status->freq) { - ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); + //ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); return false; } diff --git a/otus/freebsd/src/sys/dev/athp/hal/wmi.h b/otus/freebsd/src/sys/dev/athp/hal/wmi.h index 62fb95e3..ebda87c5 100644 --- a/otus/freebsd/src/sys/dev/athp/hal/wmi.h +++ b/otus/freebsd/src/sys/dev/athp/hal/wmi.h @@ -1973,6 +1973,7 @@ struct wmi_10x_service_ready_event { #define WMI_SERVICE_READY_TIMEOUT_MSEC (5000) #define WMI_UNIFIED_READY_TIMEOUT_MSEC (5000) +#define WMI_TX_BEACONS_READY_TIMEOUT_MSEC (3000) struct wmi_ready_event { __le32 sw_version; diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_core.c b/otus/freebsd/src/sys/dev/athp/if_athp_core.c index 0c8fda55..4e2cf8ca 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_core.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_core.c @@ -1342,6 +1342,7 @@ ath10k_core_init_firmware_features(struct ath10k *ar) int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) { + //ath10k_compl_init(&ar->wmi.tx_beacons_ready); int status; ATHP_CONF_LOCK_ASSERT(ar); @@ -1470,6 +1471,12 @@ ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) goto err_hif_stop; } + status = ath10k_wmi_wait_for_tx_beacons_ready(ar); + if (status) { + ath10k_err(ar, "wmi tx beacons ready event not received\n"); + goto err_hif_stop; + } + status = ath10k_wmi_wait_for_unified_ready(ar); if (status) { ath10k_err(ar, "wmi unified ready event not received\n"); @@ -1481,7 +1488,10 @@ ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) */ ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)); - + /* + * added ath10k_wmi_wait_for_tx_beacons_ready above to wait for cmd_Send to basically finish so we don't have to locks trying to be held at the same time, + * causing a crash. + */ status = ath10k_htt_rx_ring_refill(ar); if (status) { ath10k_err(ar, "failed to refill htt rx ring: %d\n", status); @@ -1710,7 +1720,7 @@ attempt_ath10k_core_probe_fw(struct ath10k *ar, int anum) { int status = ath10k_core_probe_fw(ar); if (status) { - ath10k_err(ar, "could not probe fw, clean up allocations and memory and retry. (%d)\n", status); + ath10k_err(ar, "could not probe fw, clean up allocations, memory and retry. (%d)\n", status); tsleep(ar, 1, "pausing to wait for the ath cpu to be ready.", 250); if(anum < ATH10K_FW_PROBE_RETRIES) { clean_ath10k_core_probe_fw(ar); diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_fwlog.c b/otus/freebsd/src/sys/dev/athp/if_athp_fwlog.c index d819984f..8d5cf6ec 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_fwlog.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_fwlog.c @@ -1550,18 +1550,23 @@ ath10k_fwlog_print_work(void *arg, int npending) void ath10k_handle_fwlog_msg(struct ath10k *ar, struct athp_buf *skb) { - ATHP_FWLOG_LOCK(ar); + if(ar != NULL && mtx_initialized(&ar->fwlog_mtx) != 0) { + ATHP_FWLOG_LOCK(ar); - if (ar->fwlog_tx_queue_len > ATH10K_FWLOG_MAX_EVT_QUEUE) { - ath10k_warn(ar, "reached fwlog queue limit\n"); - athp_freebuf(ar, &ar->buf_rx, skb); - return; - } + if (ar->fwlog_tx_queue_len > ATH10K_FWLOG_MAX_EVT_QUEUE) { + ath10k_warn(ar, "reached fwlog queue limit\n"); + athp_freebuf(ar, &ar->buf_rx, skb); + return; + } - TAILQ_INSERT_TAIL(&ar->fwlog_tx_queue, skb, next); - ar->fwlog_tx_queue_len++; - taskqueue_enqueue(ar->workqueue, &ar->fwlog_tx_work); - ATHP_FWLOG_UNLOCK(ar); + TAILQ_INSERT_TAIL(&ar->fwlog_tx_queue, skb, next); + ar->fwlog_tx_queue_len++; + taskqueue_enqueue(ar->workqueue, &ar->fwlog_tx_work); + ATHP_FWLOG_UNLOCK(ar); + } + else { + //log that mutext is being locked upon and has never been initialized. + } } void ath10k_fwlog_register(struct ath10k *ar) diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_htt_rx.c b/otus/freebsd/src/sys/dev/athp/if_athp_htt_rx.c index 44595428..8a20b1a2 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_htt_rx.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_htt_rx.c @@ -2034,7 +2034,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, */ if (!rx_status->c_ieee) { - ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); + //ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); return false; } diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_mac.c b/otus/freebsd/src/sys/dev/athp/if_athp_mac.c index a97be686..61c57a90 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_mac.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_mac.c @@ -5357,7 +5357,6 @@ ath10k_add_interface(struct ath10k *ar, struct ieee80211vap *vif, #if 0 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; #endif - ATHP_CONF_LOCK(ar); arvif->ar = ar; @@ -5441,6 +5440,8 @@ ath10k_add_interface(struct ath10k *ar, struct ieee80211vap *vif, break; case IEEE80211_M_HOSTAP: arvif->vdev_type = WMI_VDEV_TYPE_AP; + /* Need to setup the dma buffer for hostap mode since we allocate it in the power on state 'athp_parent' */ + arvif->beacon_buf = ar->beacon_buf; break; default: ath10k_warn(ar, "%s: unsupported opmode (%d)\n", __func__, opmode); @@ -5476,6 +5477,10 @@ ath10k_add_interface(struct ath10k *ar, struct ieee80211vap *vif, * beacon tx commands. Worst case for this approach is some beacons may * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap. */ + /* + This is being moved to: + athp_parent + instead were it should be at otherwise we have to deal with locking that could possibly messup the entire add interface call. if (opmode == IEEE80211_M_IBSS || opmode == IEEE80211_M_HOSTAP) { ret = athp_descdma_alloc(ar, &arvif->beacon_buf, @@ -5485,7 +5490,7 @@ ath10k_add_interface(struct ath10k *ar, struct ieee80211vap *vif, "%s: TODO: beacon_buf failed to allocate\n", __func__); goto err; } - } + }*/ if (test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags)) arvif->nohwcrypt = true; @@ -5649,7 +5654,8 @@ ath10k_add_interface(struct ath10k *ar, struct ieee80211vap *vif, arvif->vdev_id = 0; err: - athp_descdma_free(ar, &arvif->beacon_buf); + /* This is no longer happening here check athp_parent */ + //athp_descdma_free(ar, &arvif->beacon_buf); ATHP_CONF_UNLOCK(ar); diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_main.c b/otus/freebsd/src/sys/dev/athp/if_athp_main.c index 4653513d..fb48618e 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_main.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_main.c @@ -535,17 +535,22 @@ athp_parent(struct ieee80211com *ic, int attempts) /* Power up */ ret = ath10k_start(ar); - if (ret != 0) { - ath10k_err(ar, - "%s: ath10k_start failed; ret=%d\n", - __func__, ret); + while(ret != 0) { + ret = ath10k_start(ar); + if (ret != 0) { + ath10k_err(ar, + "%s: ath10k_start failed; ret=%d\n", + __func__, ret); if (attempts < 6) { ath10k_err(ar, "%s: ath10k_start failed, trying again; ret=%d\n", __func__, ret); - athp_parent(ic, attempts++); } - return; + else { + break; + } + attempts++; + } } ath10k_warn(ar, "%s: not yet running; start\n", __func__); @@ -586,7 +591,6 @@ athp_parent(struct ieee80211com *ic, int attempts) uvp->is_setup = 0; ATHP_CONF_UNLOCK(ar); } - /* Everything is shutdown; power off the chip */ ath10k_warn(ar, "%s: powering down\n", __func__); ath10k_stop(ar); @@ -2366,7 +2370,6 @@ athp_attach_11ac(struct ath10k *ar) __func__, m, ar->vht_cap_info); #endif } - /* * Attach time setup. * @@ -2425,7 +2428,7 @@ athp_attach_net80211(struct ath10k *ar) ic->ic_channels); IEEE80211_ADDR_COPY(ic->ic_macaddr, ar->mac_addr); - + printf("%s: called; ieee80211_ifattach\n", __func__); ieee80211_ifattach(ic); /* required 802.11 methods */ @@ -2458,11 +2461,15 @@ athp_attach_net80211(struct ath10k *ar) /* Initial 11n state; capabilities */ if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) { + printf("%s: called; athp_attach_11n\n", __func__); athp_attach_11n(ar); athp_attach_11ac(ar); } + //athp_dma_allocate(ar); + /* radiotap attach */ + printf("%s: called; ieee80211_radiotap_attach\n", __func__); ieee80211_radiotap_attach(ic, &ar->sc_txtapu.th.wt_ihdr, sizeof(ar->sc_txtapu), ATH10K_TX_RADIOTAP_PRESENT, @@ -2470,11 +2477,13 @@ athp_attach_net80211(struct ath10k *ar) ATH10K_RX_RADIOTAP_PRESENT); // if (bootverbose) - ieee80211_announce(ic); + printf("%s: called; ieee80211_announce\n", __func__); + ieee80211_announce(ic); /* Deferring work (eg crypto key updates) into net80211 taskqueue */ + printf("%s: called; athp_taskq_init\n", __func__); (void) athp_taskq_init(ar); - + printf("%s: called; is returning\n", __func__); return (0); } @@ -2490,7 +2499,7 @@ athp_detach_net80211(struct ath10k *ar) /* stop/drain taskq entries */ athp_taskq_flush(ar, 0); athp_taskq_free(ar); - + //athp_dma_deallocate(ar); if (ic->ic_softc == ar) ieee80211_ifdetach(ic); diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_pci.c b/otus/freebsd/src/sys/dev/athp/if_athp_pci.c index 4e0371a7..c5da1712 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_pci.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_pci.c @@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$"); #include "if_athp_buf.h" #include "if_athp_trace.h" #include "if_athp_ioctl.h" +#include "if_athp_mac.h" static device_probe_t athp_pci_probe; static device_attach_t athp_pci_attach; @@ -696,6 +697,31 @@ athp_attach_preinit(void *arg) ath10k_core_destroy(ar); } +/* +* Remove the allocation of the beacon buffer one time +*/ +static void +athp_dma_deallocate_beacon(struct ath10k * ar) { + athp_descdma_free(ar, &ar->beacon_buf); +} +/* +* Handle the dma allocations for the power up of the wifi card +*/ +static int +athp_dma_allocate_beacon(struct ath10k * ar) +{ + int ret = athp_descdma_alloc(ar, &ar->beacon_buf, + "beacon buf", 4, ATH10K_BEACON_BUF_LEN); + if (ret != 0) { + ath10k_warn(ar, + "%s: TODO: beacon_buf failed to allocate\n", __func__); + + athp_descdma_free(ar, &ar->beacon_buf); + return 0; + } + return 1; +} + static int athp_pci_attach(device_t dev) { @@ -778,6 +804,9 @@ athp_pci_attach(device_t dev) goto bad0; } + /* setup the dma beacon allocations here */ + athp_dma_allocate_beacon(ar); + /* * Initialise HTT descriptors/memory. */ @@ -974,7 +1003,6 @@ athp_pci_attach(device_t dev) "%s: couldn't establish preinit hook\n", __func__); goto bad4; } - return (0); /* Fallthrough for setup failure */ @@ -1025,7 +1053,7 @@ athp_pci_detach(device_t dev) ATHP_LOCK(ar); ar->sc_invalid = 1; ATHP_UNLOCK(ar); - + athp_dma_deallocate_beacon(ar); /* Shutdown ioctl handler */ athp_ioctl_teardown(ar); diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_var.h b/otus/freebsd/src/sys/dev/athp/if_athp_var.h index dda41a74..14650280 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_var.h +++ b/otus/freebsd/src/sys/dev/athp/if_athp_var.h @@ -138,6 +138,7 @@ struct ath10k_wmi { enum ath10k_htc_ep_id eid; struct ath10k_compl service_ready; struct ath10k_compl unified_ready; + struct ath10k_compl tx_beacons_ready; struct ath10k_wait tx_credits_wq; int is_init; DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); @@ -399,6 +400,7 @@ struct ath10k { unsigned long long free_vdev_map; struct ath10k_vif *monitor_arvif; + struct athp_descdma beacon_buf; bool monitor; int monitor_vdev_id; bool monitor_started; diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_wmi.c b/otus/freebsd/src/sys/dev/athp/if_athp_wmi.c index 6a249ae4..305b33f8 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_wmi.c +++ b/otus/freebsd/src/sys/dev/athp/if_athp_wmi.c @@ -1667,6 +1667,19 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) return 0; } +int ath10k_wmi_wait_for_tx_beacons_ready(struct ath10k *ar) +{ + unsigned long time_left; + + time_left = ath10k_compl_wait(&ar->wmi.tx_beacons_ready, + "wmi_tx_beacons_ready", &ar->sc_conf_mtx, + WMI_TX_BEACONS_READY_TIMEOUT_MSEC); + if (!time_left) + return -ETIMEDOUT; + return 0; +} + + int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) { unsigned long time_left; @@ -1806,6 +1819,7 @@ static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) ath10k_wmi_tx_beacon_nowait(vif); } ATHP_CONF_UNLOCK(ar); + ath10k_compl_wakeup_one(&ar->wmi.tx_beacons_ready); } static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) @@ -6998,7 +7012,7 @@ int ath10k_wmi_attach(struct ath10k *ar) ath10k_compl_init(&ar->wmi.service_ready); ath10k_compl_init(&ar->wmi.unified_ready); - + ath10k_compl_init(&ar->wmi.tx_beacons_ready); if (! ar->wmi.is_init) { TASK_INIT(&ar->svc_rdy_work, 0, ath10k_wmi_event_service_ready_work, ar); } diff --git a/otus/freebsd/src/sys/dev/athp/if_athp_wmi.h b/otus/freebsd/src/sys/dev/athp/if_athp_wmi.h index d3f91c39..1ed86390 100644 --- a/otus/freebsd/src/sys/dev/athp/if_athp_wmi.h +++ b/otus/freebsd/src/sys/dev/athp/if_athp_wmi.h @@ -28,6 +28,7 @@ int ath10k_wmi_attach(struct ath10k *ar); void ath10k_wmi_detach(struct ath10k *ar); void ath10k_wmi_detach_drain(struct ath10k *ar); int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); +int ath10k_wmi_wait_for_tx_beacons_ready(struct ath10k *ar); int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); struct athp_buf *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);