Loading drivers/net/wireless/ath/ath10k/core.h +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/pci.h> #include <linux/uuid.h> #include <linux/time.h> #include <linux/inetdevice.h> #include <soc/qcom/socinfo.h> #include "htt.h" Loading Loading @@ -430,6 +431,8 @@ struct ath10k_vif { struct work_struct ap_csa_work; struct delayed_work connection_loss_work; struct cfg80211_bitrate_mask bitrate_mask; struct wmi_ns_arp_offload_req arp_offload; struct wmi_ns_arp_offload_req ns_offload; }; struct ath10k_vif_iter { Loading drivers/net/wireless/ath/ath10k/mac.c +4 −0 Original line number Diff line number Diff line Loading @@ -1387,6 +1387,10 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); /* Clear arp and ns offload cache */ memset(&arvif->arp_offload, 0, sizeof(arvif->arp_offload)); memset(&arvif->ns_offload, 0, sizeof(arvif->ns_offload)); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); Loading drivers/net/wireless/ath/ath10k/wmi-ops.h +19 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ struct wmi_ops { u32 num_ac); struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar, const struct wmi_sta_keepalive_arg *arg); struct sk_buff *(*gen_set_arp_ns_offload)(struct ath10k *ar, struct ath10k_vif *arvif); struct sk_buff *(*gen_wow_enable)(struct ath10k *ar); struct sk_buff *(*gen_wow_add_wakeup_event)(struct ath10k *ar, u32 vdev_id, enum wmi_wow_wakeup_event event, Loading Loading @@ -1186,6 +1188,23 @@ ath10k_wmi_sta_keepalive(struct ath10k *ar, return ath10k_wmi_cmd_send(ar, skb, cmd_id); } static inline int ath10k_wmi_set_arp_ns_offload(struct ath10k *ar, struct ath10k_vif *arvif) { struct sk_buff *skb; u32 cmd_id; if (!ar->wmi.ops->gen_set_arp_ns_offload) return -EOPNOTSUPP; skb = ar->wmi.ops->gen_set_arp_ns_offload(ar, arvif); if (IS_ERR(skb)) return PTR_ERR(skb); cmd_id = ar->wmi.cmd->set_arp_ns_offload_cmdid; return ath10k_wmi_cmd_send(ar, skb, cmd_id); } static inline int ath10k_wmi_wow_enable(struct ath10k *ar) { Loading drivers/net/wireless/ath/ath10k/wmi-tlv.c +77 −0 Original line number Diff line number Diff line Loading @@ -3009,6 +3009,82 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar, return skb; } static struct sk_buff * ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar, struct ath10k_vif *arvif) { struct wmi_tlv_arp_ns_offload_cmd *cmd; struct wmi_tlv *tlv; struct sk_buff *skb; size_t len; void *ptr; int i; struct wmi_ns_arp_offload_req *arp = &arvif->arp_offload; struct wmi_ns_offload *ns_tuple[WMI_MAX_NS_OFFLOADS]; struct wmi_arp_offload *arp_tuple[WMI_MAX_ARP_OFFLOADS]; len = sizeof(*cmd) + sizeof(*tlv) + sizeof(*tlv) + WMI_MAX_NS_OFFLOADS * (sizeof(struct wmi_ns_offload) + sizeof(*tlv)) + sizeof(*tlv) + WMI_MAX_ARP_OFFLOADS * (sizeof(struct wmi_arp_offload) + sizeof(*tlv)); skb = ath10k_wmi_alloc_skb(ar, len); if (!skb) return ERR_PTR(-ENOMEM); ptr = (void *)skb->data; tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SET_ARP_NS_OFFLOAD_CMD); tlv->len = __cpu_to_le16(sizeof(*cmd)); cmd = (struct wmi_tlv_arp_ns_offload_cmd *)tlv->value; cmd->flags = __cpu_to_le32(0); cmd->vdev_id = __cpu_to_le32(arvif->vdev_id); ptr += (sizeof(*tlv) + sizeof(*cmd)); tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); tlv->len = __cpu_to_le16(WMI_MAX_NS_OFFLOADS * (sizeof(struct wmi_ns_offload) + sizeof(*tlv))); ptr += sizeof(*tlv); tlv = ptr; for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_ns_offload)); ns_tuple[i] = (struct wmi_ns_offload *)tlv->value; ns_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); ptr += (sizeof(*tlv) + sizeof(struct wmi_ns_offload)); tlv = ptr; } tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); tlv->len = __cpu_to_le16(WMI_MAX_ARP_OFFLOADS * (sizeof(struct wmi_arp_offload) + sizeof(*tlv))); ptr += sizeof(*tlv); tlv = ptr; for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_arp_offload)); arp_tuple[i] = (struct wmi_arp_offload *)tlv->value; if (arp->enable_offload && (i == 0)) { arp_tuple[i]->flags |= __cpu_to_le32(WMI_ARPOFF_FLAGS_VALID); memcpy(&arp_tuple[i]->target_ipaddr, &arp->params.ipv4_addr, 4); } else { arp_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); } ptr += (sizeof(*tlv) + sizeof(struct wmi_arp_offload)); tlv = ptr; } ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set arp ns offload\n"); return skb; } static struct sk_buff * ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar) { Loading Loading @@ -3695,6 +3771,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, .gen_set_arp_ns_offload = ath10k_wmi_tlv_op_gen_set_arp_ns_offload, .gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable, .gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event, .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, Loading drivers/net/wireless/ath/ath10k/wmi-tlv.h +6 −0 Original line number Diff line number Diff line Loading @@ -1557,6 +1557,12 @@ struct wmi_tlv_wow_enable_cmd { __le32 pause_iface_config; } __packed; struct wmi_tlv_arp_ns_offload_cmd { __le32 flags; __le32 vdev_id; __le32 num_ns_ext_tuples; } __packed; struct wmi_tlv_wow_host_wakeup_ind { __le32 reserved; } __packed; Loading Loading
drivers/net/wireless/ath/ath10k/core.h +3 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <linux/pci.h> #include <linux/uuid.h> #include <linux/time.h> #include <linux/inetdevice.h> #include <soc/qcom/socinfo.h> #include "htt.h" Loading Loading @@ -430,6 +431,8 @@ struct ath10k_vif { struct work_struct ap_csa_work; struct delayed_work connection_loss_work; struct cfg80211_bitrate_mask bitrate_mask; struct wmi_ns_arp_offload_req arp_offload; struct wmi_ns_arp_offload_req ns_offload; }; struct ath10k_vif_iter { Loading
drivers/net/wireless/ath/ath10k/mac.c +4 −0 Original line number Diff line number Diff line Loading @@ -1387,6 +1387,10 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); /* Clear arp and ns offload cache */ memset(&arvif->arp_offload, 0, sizeof(arvif->arp_offload)); memset(&arvif->ns_offload, 0, sizeof(arvif->ns_offload)); reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); Loading
drivers/net/wireless/ath/ath10k/wmi-ops.h +19 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ struct wmi_ops { u32 num_ac); struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar, const struct wmi_sta_keepalive_arg *arg); struct sk_buff *(*gen_set_arp_ns_offload)(struct ath10k *ar, struct ath10k_vif *arvif); struct sk_buff *(*gen_wow_enable)(struct ath10k *ar); struct sk_buff *(*gen_wow_add_wakeup_event)(struct ath10k *ar, u32 vdev_id, enum wmi_wow_wakeup_event event, Loading Loading @@ -1186,6 +1188,23 @@ ath10k_wmi_sta_keepalive(struct ath10k *ar, return ath10k_wmi_cmd_send(ar, skb, cmd_id); } static inline int ath10k_wmi_set_arp_ns_offload(struct ath10k *ar, struct ath10k_vif *arvif) { struct sk_buff *skb; u32 cmd_id; if (!ar->wmi.ops->gen_set_arp_ns_offload) return -EOPNOTSUPP; skb = ar->wmi.ops->gen_set_arp_ns_offload(ar, arvif); if (IS_ERR(skb)) return PTR_ERR(skb); cmd_id = ar->wmi.cmd->set_arp_ns_offload_cmdid; return ath10k_wmi_cmd_send(ar, skb, cmd_id); } static inline int ath10k_wmi_wow_enable(struct ath10k *ar) { Loading
drivers/net/wireless/ath/ath10k/wmi-tlv.c +77 −0 Original line number Diff line number Diff line Loading @@ -3009,6 +3009,82 @@ ath10k_wmi_tlv_op_gen_tdls_peer_update(struct ath10k *ar, return skb; } static struct sk_buff * ath10k_wmi_tlv_op_gen_set_arp_ns_offload(struct ath10k *ar, struct ath10k_vif *arvif) { struct wmi_tlv_arp_ns_offload_cmd *cmd; struct wmi_tlv *tlv; struct sk_buff *skb; size_t len; void *ptr; int i; struct wmi_ns_arp_offload_req *arp = &arvif->arp_offload; struct wmi_ns_offload *ns_tuple[WMI_MAX_NS_OFFLOADS]; struct wmi_arp_offload *arp_tuple[WMI_MAX_ARP_OFFLOADS]; len = sizeof(*cmd) + sizeof(*tlv) + sizeof(*tlv) + WMI_MAX_NS_OFFLOADS * (sizeof(struct wmi_ns_offload) + sizeof(*tlv)) + sizeof(*tlv) + WMI_MAX_ARP_OFFLOADS * (sizeof(struct wmi_arp_offload) + sizeof(*tlv)); skb = ath10k_wmi_alloc_skb(ar, len); if (!skb) return ERR_PTR(-ENOMEM); ptr = (void *)skb->data; tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SET_ARP_NS_OFFLOAD_CMD); tlv->len = __cpu_to_le16(sizeof(*cmd)); cmd = (struct wmi_tlv_arp_ns_offload_cmd *)tlv->value; cmd->flags = __cpu_to_le32(0); cmd->vdev_id = __cpu_to_le32(arvif->vdev_id); ptr += (sizeof(*tlv) + sizeof(*cmd)); tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); tlv->len = __cpu_to_le16(WMI_MAX_NS_OFFLOADS * (sizeof(struct wmi_ns_offload) + sizeof(*tlv))); ptr += sizeof(*tlv); tlv = ptr; for (i = 0; i < WMI_MAX_NS_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_ns_offload)); ns_tuple[i] = (struct wmi_ns_offload *)tlv->value; ns_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); ptr += (sizeof(*tlv) + sizeof(struct wmi_ns_offload)); tlv = ptr; } tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); tlv->len = __cpu_to_le16(WMI_MAX_ARP_OFFLOADS * (sizeof(struct wmi_arp_offload) + sizeof(*tlv))); ptr += sizeof(*tlv); tlv = ptr; for (i = 0; i < WMI_MAX_ARP_OFFLOADS; i++) { tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE); tlv->len = __cpu_to_le16(sizeof(struct wmi_arp_offload)); arp_tuple[i] = (struct wmi_arp_offload *)tlv->value; if (arp->enable_offload && (i == 0)) { arp_tuple[i]->flags |= __cpu_to_le32(WMI_ARPOFF_FLAGS_VALID); memcpy(&arp_tuple[i]->target_ipaddr, &arp->params.ipv4_addr, 4); } else { arp_tuple[i]->flags |= __cpu_to_le32(WMI_ARP_NS_OFFLOAD_DISABLE); } ptr += (sizeof(*tlv) + sizeof(struct wmi_arp_offload)); tlv = ptr; } ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set arp ns offload\n"); return skb; } static struct sk_buff * ath10k_wmi_tlv_op_gen_wow_enable(struct ath10k *ar) { Loading Loading @@ -3695,6 +3771,7 @@ static const struct wmi_ops wmi_tlv_ops = { .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, .gen_set_arp_ns_offload = ath10k_wmi_tlv_op_gen_set_arp_ns_offload, .gen_wow_enable = ath10k_wmi_tlv_op_gen_wow_enable, .gen_wow_add_wakeup_event = ath10k_wmi_tlv_op_gen_wow_add_wakeup_event, .gen_wow_host_wakeup_ind = ath10k_wmi_tlv_gen_wow_host_wakeup_ind, Loading
drivers/net/wireless/ath/ath10k/wmi-tlv.h +6 −0 Original line number Diff line number Diff line Loading @@ -1557,6 +1557,12 @@ struct wmi_tlv_wow_enable_cmd { __le32 pause_iface_config; } __packed; struct wmi_tlv_arp_ns_offload_cmd { __le32 flags; __le32 vdev_id; __le32 num_ns_ext_tuples; } __packed; struct wmi_tlv_wow_host_wakeup_ind { __le32 reserved; } __packed; Loading