Skip to content

Commit

Permalink
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kva…
Browse files Browse the repository at this point in the history
…lo/ath.git

ath.git patches for v5.20. Major changes:

ath10k

* 802.3 frame format support
  • Loading branch information
Kalle Valo committed Jun 15, 2022
2 parents fbb89d0 + cc2609e commit 8092a0e
Show file tree
Hide file tree
Showing 24 changed files with 298 additions and 86 deletions.
11 changes: 7 additions & 4 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ EXPORT_SYMBOL(ath10k_debug_mask);
static unsigned int ath10k_cryptmode_param;
static bool uart_print;
static bool skip_otp;
static bool rawmode;
static bool fw_diag_log;

/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;

unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);

Expand All @@ -44,15 +46,16 @@ module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
module_param(uart_print, bool, 0644);
module_param(skip_otp, bool, 0644);
module_param(rawmode, bool, 0644);
module_param(fw_diag_log, bool, 0644);
module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);

MODULE_PARM_DESC(debug_mask, "Debugging mask");
MODULE_PARM_DESC(uart_print, "Uart target debugging");
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
MODULE_PARM_DESC(frame_mode,
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");

Expand Down Expand Up @@ -2599,7 +2602,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;

if (rawmode) {
if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
fw_file->fw_features)) {
ath10k_err(ar, "rawmode = 1 requires support from firmware");
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,7 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
return false;
}

extern unsigned int ath10k_frame_mode;
extern unsigned long ath10k_coredump_mask;

void ath10k_core_napi_sync_disable(struct ath10k *ar);
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/wireless/ath/ath10k/htt_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3563,7 +3563,7 @@ static void ath10k_htt_rx_tx_mode_switch_ind(struct ath10k *ar,
threshold = MS(info1, HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD);

ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt rx tx mode switch ind info0 0x%04hx info1 0x%04x enable %d num records %zd mode %d threshold %u\n",
"htt rx tx mode switch ind info0 0x%04x info1 0x%04x enable %d num records %zd mode %d threshold %u\n",
info0, info1, enable, num_records, mode, threshold);

len += sizeof(resp->tx_mode_switch_ind.records[0]) * num_records;
Expand Down Expand Up @@ -3884,6 +3884,10 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
arsta->tx_info.status.rates[0].flags |=
IEEE80211_TX_RC_80_MHZ_WIDTH;
break;
case RATE_INFO_BW_160:
arsta->tx_info.status.rates[0].flags |=
IEEE80211_TX_RC_160_MHZ_WIDTH;
break;
}

if (peer_stats->succ_pkts) {
Expand Down
61 changes: 35 additions & 26 deletions drivers/net/wireless/ath/ath10k/htt_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,6 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
struct ath10k *ar = htt->ar;
int res, data_len;
struct htt_cmd_hdr *cmd_hdr;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
struct htt_data_tx_desc *tx_desc;
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct sk_buff *tmp_skb;
Expand All @@ -1286,11 +1285,15 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
u16 flags1 = 0;
u16 msdu_id = 0;

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
if (!is_eth) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
}

data_len = msdu->len;
Expand Down Expand Up @@ -1387,7 +1390,6 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
Expand Down Expand Up @@ -1419,15 +1421,19 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
txbuf_paddr = htt->txbuf.paddr +
(sizeof(struct ath10k_htt_txbuf_32) * msdu_id);

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
if (!is_eth) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
}

skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
Expand Down Expand Up @@ -1589,7 +1595,6 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
{
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
struct ath10k_hif_sg_item sg_items[2];
Expand Down Expand Up @@ -1621,15 +1626,19 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
txbuf_paddr = htt->txbuf.paddr +
(sizeof(struct ath10k_htt_txbuf_64) * msdu_id);

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
if (!is_eth) {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;

if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
txmode == ATH10K_HW_TXRX_RAW &&
ieee80211_has_protected(hdr->frame_control)) {
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
}
}

skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
Expand Down
70 changes: 56 additions & 14 deletions drivers/net/wireless/ath/ath10k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -3713,6 +3713,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
__le16 fc = hdr->frame_control;

if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
return ATH10K_HW_TXRX_ETHERNET;

if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
return ATH10K_HW_TXRX_RAW;

Expand Down Expand Up @@ -3873,6 +3876,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
bool noack = false;

cb->flags = 0;

if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
cb->flags |= ATH10K_SKB_F_QOS; /* Assume data frames are QoS */
goto finish_cb_fill;
}

if (!ath10k_tx_h_use_hwcrypto(vif, skb))
cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;

Expand Down Expand Up @@ -3911,6 +3920,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
cb->flags |= ATH10K_SKB_F_RAW_TX;
}

finish_cb_fill:
cb->vif = vif;
cb->txq = txq;
cb->airtime_est = airtime;
Expand Down Expand Up @@ -4034,7 +4044,11 @@ static int ath10k_mac_tx(struct ath10k *ar,
ath10k_tx_h_seq_no(vif, skb);
break;
case ATH10K_HW_TXRX_ETHERNET:
ath10k_tx_h_8023(skb);
/* Convert 802.11->802.3 header only if the frame was erlier
* encapsulated to 802.11 by mac80211. Otherwise pass it as is.
*/
if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
ath10k_tx_h_8023(skb);
break;
case ATH10K_HW_TXRX_RAW:
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
Expand Down Expand Up @@ -4645,12 +4659,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif = info->control.vif;
struct ieee80211_sta *sta = control->sta;
struct ieee80211_txq *txq = NULL;
struct ieee80211_hdr *hdr = (void *)skb->data;
enum ath10k_hw_txrx_mode txmode;
enum ath10k_mac_tx_path txpath;
bool is_htt;
bool is_mgmt;
bool is_presp;
int ret;
u16 airtime;

Expand All @@ -4664,8 +4676,14 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);

if (is_htt) {
bool is_presp = false;

spin_lock_bh(&ar->htt.tx_lock);
is_presp = ieee80211_is_probe_resp(hdr->frame_control);
if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
struct ieee80211_hdr *hdr = (void *)skb->data;

is_presp = ieee80211_is_probe_resp(hdr->frame_control);
}

ret = ath10k_htt_tx_inc_pending(htt);
if (ret) {
Expand Down Expand Up @@ -5465,6 +5483,30 @@ static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
ar->wmi.vdev_param->txbf, value);
}

static void ath10k_update_vif_offload(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct ath10k_vif *arvif = (void *)vif->drv_priv;
struct ath10k *ar = hw->priv;
u32 vdev_param;
int ret;

if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||
ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||
(vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_AP))
vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;

vdev_param = ar->wmi.vdev_param->tx_encap_type;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
ATH10K_HW_TXRX_NATIVE_WIFI);
/* 10.X firmware does not support this VDEV parameter. Do not warn */
if (ret && ret != -EOPNOTSUPP) {
ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
arvif->vdev_id, ret);
}
}

/*
* TODO:
* Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
Expand Down Expand Up @@ -5674,15 +5716,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,

arvif->def_wep_key_idx = -1;

vdev_param = ar->wmi.vdev_param->tx_encap_type;
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
ATH10K_HW_TXRX_NATIVE_WIFI);
/* 10.X firmware does not support this VDEV parameter. Do not warn */
if (ret && ret != -EOPNOTSUPP) {
ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
arvif->vdev_id, ret);
goto err_vdev_delete;
}
ath10k_update_vif_offload(hw, vif);

/* Configuring number of spatial stream for monitor interface is causing
* target assert in qca9888 and qca6174.
Expand Down Expand Up @@ -9375,6 +9409,7 @@ static const struct ieee80211_ops ath10k_ops = {
.stop = ath10k_stop,
.config = ath10k_config,
.add_interface = ath10k_add_interface,
.update_vif_offload = ath10k_update_vif_offload,
.remove_interface = ath10k_remove_interface,
.configure_filter = ath10k_configure_filter,
.bss_info_changed = ath10k_bss_info_changed,
Expand Down Expand Up @@ -10044,6 +10079,12 @@ int ath10k_mac_register(struct ath10k *ar)
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);

if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {
if (ar->wmi.vdev_param->tx_encap_type !=
WMI_VDEV_PARAM_UNSUPPORTED)
ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
}

ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
ar->hw->wiphy->max_remain_on_channel_duration = 5000;
Expand Down Expand Up @@ -10229,7 +10270,8 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_AP_VLAN);
}

if (!ath_is_world_regd(&ar->ath_common.regulatory)) {
if (!ath_is_world_regd(&ar->ath_common.reg_world_copy) &&
!ath_is_world_regd(&ar->ath_common.regulatory)) {
ret = regulatory_hint(ar->hw->wiphy,
ar->ath_common.regulatory.alpha2);
if (ret)
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath10k/qmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,12 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)

if (resp->fw_version_info_valid) {
qmi->fw_version = resp->fw_version_info.fw_version;
strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp,
strscpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp,
sizeof(qmi->fw_build_timestamp));
}

if (resp->fw_build_id_valid)
strlcpy(qmi->fw_build_id, resp->fw_build_id,
strscpy(qmi->fw_build_id, resp->fw_build_id,
MAX_BUILD_ID_LEN + 1);

if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) {
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/ath/ath10k/snoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1249,13 +1249,12 @@ static void ath10k_snoc_init_napi(struct ath10k *ar)
static int ath10k_snoc_request_irq(struct ath10k *ar)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
int irqflags = IRQF_TRIGGER_RISING;
int ret, id;

for (id = 0; id < CE_COUNT_MAX; id++) {
ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
ath10k_snoc_per_engine_handler,
irqflags, ce_name[id], ar);
ath10k_snoc_per_engine_handler, 0,
ce_name[id], ar);
if (ret) {
ath10k_err(ar,
"failed to register IRQ handler for CE %d: %d\n",
Expand Down
15 changes: 14 additions & 1 deletion drivers/net/wireless/ath/ath10k/txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
const struct htt_tx_done *tx_done)
{
struct ieee80211_tx_status status;
struct ath10k *ar = htt->ar;
struct device *dev = ar->dev;
struct ieee80211_tx_info *info;
Expand Down Expand Up @@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
info->status.flags |= IEEE80211_TX_STATUS_ACK_SIGNAL_VALID;
}

ieee80211_tx_status(htt->ar->hw, msdu);
memset(&status, 0, sizeof(status));
status.skb = msdu;
status.info = info;

rcu_read_lock();

if (txq)
status.sta = txq->sta;

ieee80211_tx_status_ext(htt->ar->hw, &status);

rcu_read_unlock();

/* we do not own the msdu anymore */

return 0;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath11k/ahb.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,11 +976,11 @@ static int ath11k_ahb_probe(struct platform_device *pdev)
ab->hw_rev = hw_rev;
platform_set_drvdata(pdev, ab);

ret = ath11k_ahb_setup_resources(ab);
ret = ath11k_core_pre_init(ab);
if (ret)
goto err_core_free;

ret = ath11k_core_pre_init(ab);
ret = ath11k_ahb_setup_resources(ab);
if (ret)
goto err_core_free;

Expand Down
Loading

0 comments on commit 8092a0e

Please sign in to comment.