From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1BE57362138 for ; Thu, 30 Apr 2026 04:57:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.173 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777525030; cv=none; b=idqxH8C5kaveNG88IA3eoZYVV3SwgICSs9JrJXyHYU5uItwufyixPSRcab4TUCRtBA2ZxakP5wDzVbj+p0HacWO7y5HDXRrSqm0DMTRSnj8TBJFWuitn6TSXj8HmuIe7lZ94ScGeZ1TJ35HY4Lu4RAK0KRoPRKAmHJvF/9mk7Ww= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777525030; c=relaxed/simple; bh=BOfLnJTWFY5/yt0txp1ZWj13yS0HWhij74+DubKV2Ow=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OQ8syG5bdMvt5EOKk9QBUUZssGnX3l25nzjFCDrvWrN71wedG1eqWSoYIXPqayM0ZTjy9Xgq4ie8fOfOQ9Tqsba6d9qfhGY8WhS/CvFSEf/T8bbRChFyJZMzszL4xXz17zDdiBMBMv7IqiKSK9EFyKphzMawYN3UH7etakN8uII= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=morsemicro.com; spf=pass smtp.mailfrom=morsemicro.com; dkim=pass (2048-bit key) header.d=morsemicro-com.20251104.gappssmtp.com header.i=@morsemicro-com.20251104.gappssmtp.com header.b=S/RwDGyo; arc=none smtp.client-ip=209.85.210.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=morsemicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=morsemicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=morsemicro-com.20251104.gappssmtp.com header.i=@morsemicro-com.20251104.gappssmtp.com header.b="S/RwDGyo" Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-82f0884bcfaso377945b3a.1 for ; Wed, 29 Apr 2026 21:57:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=morsemicro-com.20251104.gappssmtp.com; s=20251104; t=1777525028; x=1778129828; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6ZvEjFvVe7SCxEgVzCtRC6KzFyis4B4ziBUKypetjHU=; b=S/RwDGyoV7PjCFisr2Lyw7Pm7UOGmIDkOMdndXMnSEqCdm7bQKw50a94n6jbvo9PVd fI7XUaINlvlPZHO3ToMabV1yMe2j5vrNnwh8pgZnJX1VnmUeqKXYKzrFenxIXuQTYNUq 9j8DUVFQfxbfHQHeyw/G5AmhQmDuTVgps36tkgU9NWM7hMTsf9zRhvgzhYLM8qYKKj7u 5DUDbue5/VzPPHLdS1t8hy/BfC9bBux5VM5DdZWpV5FTlGJsHU9GNg7fXKZrH9V4fDf5 i0LRCyDbT+D7Xl9i2P0/Vagq24cHEAnIkzC6lLDgLAl1R9vxuHOeuO8feV8HaMi8DbnG xMAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777525028; x=1778129828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=6ZvEjFvVe7SCxEgVzCtRC6KzFyis4B4ziBUKypetjHU=; b=hCo/hrtkIs6fEB61WBGFA31XMvQLq7ZFYSoIjTuD8XHzqmp0X8UEEDO+qe3M5XJsRI 67t43wB0aJZhk1+Ws2kATBhTB7m8QhOcNhOa690WH5xUxgR2QzuHsE/0yI7SG2ri2kiB jW1FJDYyC/HaiSfgo9+3lFalu2zvHh4rKLLesBkSYIjAyYAiWshIQxarI/p8PVMkHnmj uf8VP5+IHyvOqe+XiGUUcOTd5Fe+AAFlAR12vygInKLPMyqcJVn8i7fV029IqVYAu8QH EhMnJNRjIozHKbgSckuDZTNgP3II1UW9MVFX9AAmq74UeCjuyhaNtswJwkV6+OQjHftL g4NA== X-Forwarded-Encrypted: i=1; AFNElJ+4lRt5KhCcOAozT6yNS5WfLXkKWfH+jFy+B7qo/ya81k8/KnxyCX/0bJWeucHA/VI0GXDvEpBkO+Faawp+yg==@vger.kernel.org X-Gm-Message-State: AOJu0Yyzh83Shg7nM6rmtf4z6w2BfBKhTRyzjnhIKIhPSgzAXoCPAXnA +WX1irS8vbE4XNzXOpmu1atn9rroScWbER72w2rOFtKQwtUPDJ3QioNbTZbkBPdm4hN3XILNIYO j0AW8 X-Gm-Gg: AeBDiev+4Z171GTWc9YcydWKfQIa8DqX2B/evrzEEOAmIoFybZBHR8aDIHVB1PJ25XQ 6ULj4dQ1BCpCF/YONWT8wXaEmW3WiyhYfvZlyRUdysislp7RYXH3H5AdiBtJ+gIZbNx7X91+MGo CXgHubFLhwrIWXjKKeeK6C2wCu4AS7cX14hOBuAbJmsncz32itRVMm3JkMaFTcLORtcFyuE6fdT i4ceW4MFmLAtzYvEVSFybBmb3o1bY50XwrjMygw59i9jULgLJ9RNGXRt92qVR16vXmTf1aHhtWn SFW0gPF0OjSP+YgBfFhAd9xgzJDFAlAZc9H/DkjOpYuoESDyuZRKusXCgvPKpSPU4olF82HPRfM xHxidLSERKP4BovdAZ297wQ5Hwj9IoRb3T10pYCPBABxVp60rTIr4MfQi707jCgVC1wcdQECF6G 7FY/awT/18cdLLyYXQIekBMLHok1MXDJktZPNY+Ljs5nUKpWNen+B4IeAZkk3u/iFe7dyUEzUkd bPzt1JgwVtCnygFKCBQP3Phna5DPN9vVx9GGZb74w== X-Received: by 2002:a05:6a00:b86:b0:82f:6e9:d1c3 with SMTP id d2e1a72fcca58-834fdbe66c0mr1875701b3a.29.1777525028408; Wed, 29 Apr 2026 21:57:08 -0700 (PDT) Received: from mma-H9MHD44.lan (60-242-93-14.static.tpgi.com.au. [60.242.93.14]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-834ed80df96sm3595073b3a.54.2026.04.29.21.57.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2026 21:57:07 -0700 (PDT) From: Lachlan Hodges To: johannes@sipsolutions.net, Lachlan Hodges , Dan Callaghan , Arien Judge Cc: ayman.grais@morsemicro.com, linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH wireless-next v2 06/31] wifi: mm81x: add core.h Date: Thu, 30 Apr 2026 14:55:32 +1000 Message-ID: <20260430045615.334669-7-lachlan.hodges@morsemicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260430045615.334669-1-lachlan.hodges@morsemicro.com> References: <20260430045615.334669-1-lachlan.hodges@morsemicro.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit (Patches split per file for review, will be a single commit alongside SDIO ids once review is complete. See cover letter for more information) Signed-off-by: Lachlan Hodges --- drivers/net/wireless/morsemicro/mm81x/core.h | 478 +++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 drivers/net/wireless/morsemicro/mm81x/core.h diff --git a/drivers/net/wireless/morsemicro/mm81x/core.h b/drivers/net/wireless/morsemicro/mm81x/core.h new file mode 100644 index 000000000000..698353006865 --- /dev/null +++ b/drivers/net/wireless/morsemicro/mm81x/core.h @@ -0,0 +1,478 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2017-2026 Morse Micro + */ + +#ifndef _MM81X_CORE_H_ +#define _MM81X_CORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "yaps.h" +#include "yaps_hw.h" +#include "hw.h" +#include "fw.h" +#include "rc.h" + +#define MM81X_DRIVER_SEMVER_MAJOR 56 +#define MM81X_DRIVER_SEMVER_MINOR 3 +#define MM81X_DRIVER_SEMVER_PATCH 0 + +#define MM81X_SEMVER_GET_MAJOR(x) (((x) >> 22) & 0x3FF) +#define MM81X_SEMVER_GET_MINOR(x) (((x) >> 10) & 0xFFF) +#define MM81X_SEMVER_GET_PATCH(x) ((x) & 0x3FF) + +#define DRV_VERSION __stringify(MM81X_VERSION) + +#define MM8108_FW_BASE "mm8108" + +#define BCF_SIZE_MAX 48 + +/* Generate a device ID from chip ID, revision, and chip type */ +#define MM81X_DEVICE_ID(chip_id, chip_rev, chip_type) \ + ((chip_id) | ((chip_rev) << 8) | ((chip_type) << 12)) + +/* Get constituents of the device ID */ +#define MM81X_DEVICE_GET_CHIP_ID(device_id) ((device_id) & 0xff) +#define MM81X_DEVICE_GET_CHIP_REV(device_id) ((((device_id) >> 8) & 0xf)) +#define MM81X_DEVICE_GET_CHIP_TYPE(device_id) ((((device_id) >> 12) & 0xf)) + +#define KHZ_TO_HZ(x) ((x) * 1000) +#define KHZ100_TO_MHZ(x) ((x) / 10) +#define KHZ100_TO_KHZ(freq) ((freq) * 100) +#define KHZ100_TO_HZ(freq) ((freq) * 100000) + +#define QDBM_TO_MBM(gain) (((gain) * 100) >> 2) +#define MBM_TO_QDBM(gain) (((gain) << 2) / 100) +#define QDBM_TO_DBM(gain) ((gain) / 4) + +#define BPS_TO_KBPS(x) ((x) / 1000) + +#define NSS_IDX_TO_NSS(x) ((x) + 1) +#define NSS_TO_NSS_IDX(x) ((x) - 1) + +#define ROUND_BYTES_TO_WORD(_nbytes) \ + (((_nbytes) + 3) & ~((typeof(_nbytes))0x03)) + +static inline u32 mm81x_fle32_to_cpu(u32 v) +{ + return le32_to_cpu((__force __le32)v); +} + +static inline u16 mm81x_fle16_to_cpu(u16 v) +{ + return le16_to_cpu((__force __le16)v); +} + +struct mm81x_bus_ops; +struct mm81x_hif_ops; + +/* modparam variables */ +extern char board_config_file[]; + +#define MM81X_CAPS_MAX_FW_VAL (128) + +/* Max number of interfaces */ +#define MM81X_MAX_IF (2) + +enum mm81x_caps_flags { + MM81X_CAPS_FW_START = 0, + MM81X_CAPS_2MHZ = MM81X_CAPS_FW_START, + MM81X_CAPS_4MHZ, + MM81X_CAPS_8MHZ, + MM81X_CAPS_16MHZ, + MM81X_CAPS_SGI, + MM81X_CAPS_S1G_LONG, + MM81X_CAPS_TRAVELING_PILOT_ONE_STREAM, + MM81X_CAPS_TRAVELING_PILOT_TWO_STREAM, + MM81X_CAPS_MU_BEAMFORMEE, + MM81X_CAPS_MU_BEAMFORMER, + MM81X_CAPS_RD_RESPONDER, + MM81X_CAPS_STA_TYPE_SENSOR, + MM81X_CAPS_STA_TYPE_NON_SENSOR, + MM81X_CAPS_GROUP_AID, + MM81X_CAPS_NON_TIM, + MM81X_CAPS_TIM_ADE, + MM81X_CAPS_BAT, + MM81X_CAPS_DYNAMIC_AID, + MM81X_CAPS_UPLINK_SYNC, + MM81X_CAPS_FLOW_CONTROL, + MM81X_CAPS_AMPDU, + MM81X_CAPS_AMSDU, + MM81X_CAPS_1MHZ_CONTROL_RESPONSE_PREAMBLE, + MM81X_CAPS_PAGE_SLICING, + MM81X_CAPS_RAW, + MM81X_CAPS_MCS8, + MM81X_CAPS_MCS9, + MM81X_CAPS_ASYMMETRIC_BA_SUPPORT, + MM81X_CAPS_DAC, + MM81X_CAPS_CAC, + MM81X_CAPS_TXOP_SHARING_IMPLICIT_ACK, + MM81X_CAPS_NDP_PSPOLL, + MM81X_CAPS_FRAGMENT_BA, + MM81X_CAPS_OBSS_MITIGATION, + MM81X_CAPS_TMP_PS_MODE_SWITCH, + MM81X_CAPS_SECTOR_TRAINING, + MM81X_CAPS_UNSOLICIT_DYNAMIC_AID, + MM81X_CAPS_NDP_BEAMFORMING_REPORT, + MM81X_CAPS_MCS_NEGOTIATION, + MM81X_CAPS_DUPLICATE_1MHZ, + MM81X_CAPS_TACK_AS_PSPOLL, + MM81X_CAPS_PV1, + MM81X_CAPS_TWT_RESPONDER, + MM81X_CAPS_TWT_REQUESTER, + MM81X_CAPS_BDT, + MM81X_CAPS_TWT_GROUPING, + MM81X_CAPS_LINK_ADAPTATION_WO_NDP_CMAC, + MM81X_CAPS_LONG_MPDU, + MM81X_CAPS_TXOP_SECTORIZATION, + MM81X_CAPS_GROUP_SECTORIZATION, + MM81X_CAPS_HTC_VHT, + MM81X_CAPS_HTC_VHT_MFB, + MM81X_CAPS_HTC_VHT_MRQ, + MM81X_CAPS_2SS, + MM81X_CAPS_3SS, + MM81X_CAPS_4SS, + MM81X_CAPS_SU_BEAMFORMEE, + MM81X_CAPS_SU_BEAMFORMER, + MM81X_CAPS_RX_STBC, + MM81X_CAPS_TX_STBC, + MM81X_CAPS_RX_LDPC, + MM81X_CAPS_HW_FRAGMENT, + + MM81X_CAPS_FW_END = MM81X_CAPS_MAX_FW_VAL, + MM81X_CAPS_LAST = MM81X_CAPS_FW_END, +}; + +struct mm81x_fw_caps { + u32 flags[FW_CAPABILITIES_FLAGS_WIDTH]; + u8 ampdu_mss; + u8 beamformee_sts_capability; + u8 number_sounding_dimensions; + u8 maximum_ampdu_length_exponent; + u8 mm81x_mmss_offset; +}; + +#define MM81X_FW_SUPP(MM81X_CAPS, CAPABILITY) \ + mm81x_caps_supported(MM81X_CAPS, MM81X_CAPS_##CAPABILITY) + +static inline bool mm81x_caps_supported(struct mm81x_fw_caps *caps, + enum mm81x_caps_flags flag) +{ + const unsigned long *flags_ptr = (unsigned long *)caps->flags; + + return test_bit(flag, flags_ptr); +} + +struct mm81x_ps { + u32 wakers; + bool enable; + bool suspended; + /* PS state lock */ + struct mutex lock; + struct delayed_work delayed_eval_work; +}; + +enum mm81x_page_aci { + MM81X_ACI_BE = 0, + MM81X_ACI_BK = 1, + MM81X_ACI_VI = 2, + MM81X_ACI_VO = 3, +}; + +enum mm81x_qos_tid_up_index { + MM81X_QOS_TID_UP_BK = 1, + MM81X_QOS_TID_UP_XX = 2, + MM81X_QOS_TID_UP_BE = 0, + MM81X_QOS_TID_UP_EE = 3, + MM81X_QOS_TID_UP_CL = 4, + MM81X_QOS_TID_UP_VI = 5, + MM81X_QOS_TID_UP_VO = 6, + MM81X_QOS_TID_UP_NC = 7, + + MM81X_QOS_TID_UP_LOWEST = MM81X_QOS_TID_UP_BK, + MM81X_QOS_TID_UP_HIGHEST = MM81X_QOS_TID_UP_NC +}; + +struct mm81x_sw_version { + u8 major; + u8 minor; + u8 patch; +}; + +struct mm81x_sta { + const struct ieee80211_vif *vif; + u8 addr[ETH_ALEN]; + enum ieee80211_sta_state state; + bool tid_tx[IEEE80211_NUM_TIDS]; + bool tid_start_tx[IEEE80211_NUM_TIDS]; + u8 tid_params[IEEE80211_NUM_TIDS]; + int max_bw_mhz; + struct mm81x_rc_sta rc; + struct mmrc_rate last_sta_tx_rate; + s16 avg_rssi; + bool tx_ps_filter_en; +}; + +struct mm81x_vif { + struct mm81x *mors; + u16 id; + + union { + struct { + bool is_assoc; + } sta; + struct { + u32 num_stas; + struct tasklet_struct beacon_tasklet; + bool beaconing_enabled; + } ap; + } u; +}; + +struct mm81x_stale_tx_status { + /* Stale Tx lock */ + spinlock_t lock; + struct timer_list timer; +}; + +struct mcast_filter { + u8 count; + /* + * Integer representation of the last four bytes of a multicast MAC + * address. The first two bytes are always 0x0100 (IPv4) or 0x3333 + * (IPv6). + */ + __le32 addr_list[]; +}; + +enum mm81x_hw_scan_op { + MM81X_HW_SCAN_OP_START, + MM81X_HW_SCAN_OP_STOP, +}; + +struct mm81x_hw_scan_params { + struct ieee80211_hw *hw; + + /* vif which initiated the scan */ + struct ieee80211_vif *vif; + bool has_directed_ssid; + u32 dwell_time_ms; + u32 dwell_on_home_ms; + enum mm81x_hw_scan_op operation; + bool store; + struct sk_buff *probe_req; + u16 num_chans; + u16 allocated_chans; + + struct { + struct ieee80211_channel *channel; + /* Index into @ref powers_qdbm for the power of this channel */ + u8 power_idx; + } *channels; + + s32 *powers_qdbm; + u8 n_powers; + bool use_1mhz_probes; +}; + +enum mm81x_hw_scan_state { + HW_SCAN_STATE_IDLE, + HW_SCAN_STATE_RUNNING, + HW_SCAN_STATE_ABORTING, +}; + +struct mm81x_hw_scan { + enum mm81x_hw_scan_state state; + struct completion scan_done; + struct mm81x_hw_scan_params *params; + struct delayed_work timeout; + u32 home_dwell_ms; +}; + +enum mm81x_hif_event_flags { + MM81X_HIF_EVT_RX_PEND, + MM81X_HIF_EVT_PAGE_RETURN_PEND, + MM81X_HIF_EVT_TX_COMMAND_PEND, + MM81X_HIF_EVT_TX_BEACON_PEND, + MM81X_HIF_EVT_TX_MGMT_PEND, + MM81X_HIF_EVT_TX_DATA_PEND, + MM81X_HIF_EVT_TX_PACKET_FREED_UP_PEND, + MM81X_HIF_EVT_DATA_TRAFFIC_PAUSE_PEND, + MM81X_HIF_EVT_DATA_TRAFFIC_RESUME_PEND, + MM81X_HIF_EVT_UPDATE_HW_CLOCK_REFERENCE, +}; + +enum mm81x_state_flags { + MM81X_STATE_CHIP_UNRESPONSIVE, + MM81X_STATE_DATA_QS_STOPPED, + MM81X_STATE_DATA_TX_STOPPED, + MM81X_STATE_REGDOM_SET_BY_USER, + MM81X_STATE_REGDOM_SET_BY_OTP, + MM81X_STATE_RELOAD_FW_AFTER_START, + MM81X_STATE_HOST_TO_CHIP_TX_BLOCKED, + MM81X_STATE_HOST_TO_CHIP_CMD_BLOCKED, +}; + +#define MM81X_COUNTRY_LEN (3) +#define INVALID_VIF_INDEX 0xFF + +struct mm81x { + u32 chip_id; + u32 host_table_ptr; + + /* Refer to @enum mm81x_bus_type */ + u32 bus_type; + u32 bcf_address; + + /* + * Parsed from the release tag, which should be in the format + * 'rel___'. If the tag is not in this format + * then corresponding version field will be 0. + */ + struct mm81x_sw_version sw_ver; + u8 macaddr[ETH_ALEN]; + u8 country[MM81X_COUNTRY_LEN]; + + /* Mask of type @enum host_table_firmware_flags */ + u32 firmware_flags; + struct mm81x_fw_caps fw_caps; + bool started; + bool chip_was_reset; + struct wiphy *wiphy; + struct mm81x_hw_scan hw_scan; + struct ieee80211_hw *hw; + struct device *dev; + + struct ieee80211_vif __rcu *vifs[MM81X_MAX_IF]; + + /* @mm81x_state_flags */ + unsigned long state_flags; + + u16 cmd_seq; + struct completion *cmd_comp; + /* Serialises commands */ + struct mutex cmd_lock; + + /* Serialises command completion */ + struct mutex cmd_wait; + + const struct mm81x_regs *regs; + + struct { + union { + struct mm81x_yaps yaps; + } u; + const struct mm81x_hif_ops *ops; + /* See @enum mm81x_hif_event_flags for values */ + unsigned long event_flags; + bool validate_skb_checksum; + } hif; + + struct workqueue_struct *chip_wq; + struct work_struct hif_work; + struct work_struct usb_irq_work; + struct mm81x_stale_tx_status stale_status; + bool config_ps; + struct mm81x_ps ps; + + /* Tx power in mBm received from the FW before association */ + s32 tx_power_mbm; + s32 tx_max_power_mbm; + + const struct mm81x_bus_ops *bus_ops; + struct mm81x_rc mrc; + int rts_threshold; + struct workqueue_struct *net_wq; + struct work_struct tx_stale_work; + + struct cfg80211_chan_def chandef; + struct mcast_filter *mcast_filter; + atomic_t num_bcn_vifs; + unsigned long beacon_irqs_enabled; + u8 drv_priv[] __aligned(sizeof(void *)); +}; + +/* Map from mac80211 queue to Morse ACI value for page metadata */ +static inline u8 map_mac80211q_2_mm81x_aci(u16 mac80211queue) +{ + switch (mac80211queue) { + case IEEE80211_AC_VO: + return MM81X_ACI_VO; + case IEEE80211_AC_VI: + return MM81X_ACI_VI; + case IEEE80211_AC_BK: + return MM81X_ACI_BK; + default: + return MM81X_ACI_BE; + } +} + +static inline enum mm81x_page_aci +dot11_tid_to_ac(enum mm81x_qos_tid_up_index tid) +{ + switch (tid) { + case MM81X_QOS_TID_UP_BK: + case MM81X_QOS_TID_UP_XX: + return MM81X_ACI_BK; + case MM81X_QOS_TID_UP_CL: + case MM81X_QOS_TID_UP_VI: + return MM81X_ACI_VI; + case MM81X_QOS_TID_UP_VO: + case MM81X_QOS_TID_UP_NC: + return MM81X_ACI_VO; + case MM81X_QOS_TID_UP_BE: + case MM81X_QOS_TID_UP_EE: + default: + return MM81X_ACI_BE; + } +} + +static inline bool mm81x_is_data_tx_allowed(struct mm81x *mors) +{ + return !test_bit(MM81X_STATE_DATA_TX_STOPPED, &mors->state_flags) && + !test_bit(MM81X_HIF_EVT_DATA_TRAFFIC_PAUSE_PEND, + &mors->hif.event_flags); +} + +static inline struct ieee80211_vif * +mm81x_vif_to_ieee80211_vif(struct mm81x_vif *mors_vif) +{ + return container_of((void *)mors_vif, struct ieee80211_vif, drv_priv); +} + +static inline struct mm81x_vif * +ieee80211_vif_to_mors_vif(struct ieee80211_vif *vif) +{ + return (struct mm81x_vif *)vif->drv_priv; +} + +static inline struct mm81x *mm81x_vif_to_mors(struct mm81x_vif *mors_vif) +{ + return mors_vif->mors; +} + +static inline u32 mm81x_generate_cssid(const u8 *ssid, u8 len) +{ + return ~crc32(~0, ssid, len); +} + +int mm81x_beacon_init(struct mm81x_vif *mors_vif); +void mm81x_beacon_finish(struct mm81x_vif *mors_vif); +void mm81x_beacon_irq_handle(struct mm81x *mors, u32 status); +char *mm81x_core_get_fw_path(u32 chip_id); +struct mm81x *mm81x_core_alloc(size_t priv_size, struct device *dev); +int mm81x_core_init(struct mm81x *mors); +int mm81x_core_register(struct mm81x *mors); +void mm81x_core_unregister(struct mm81x *mors); +void mm81x_core_deinit(struct mm81x *mors); +void mm81x_core_free(struct mm81x *mors); + +#endif /* !_MM81X_MM81X_H_ */ -- 2.43.0