Patch rx_desc memory layout #1

Open
Franciman wants to merge 3 commits from patch into master
5 changed files with 258 additions and 211 deletions
Showing only changes of commit 9b476c95a5 - Show all commits

63
htt.c
View File

@ -136,16 +136,16 @@ const struct ath10k_htt_rx_desc_ops qca988x_rx_desc_ops = {
.rx_desc_msdu_payload_offset = offsetof(struct htt_rx_desc_old_qca, msdu_payload) .rx_desc_msdu_payload_offset = offsetof(struct htt_rx_desc_old_qca, msdu_payload)
}; };
static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(void *rxd) static int ath10k_qca99x0_rx_desc_get_l3_pad_bytes(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd; struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return MS(__le32_to_cpu(rx_desc->msdu_end.qca99x0.info1), return MS(__le32_to_cpu(rx_desc->msdu_end.qca99x0.info1),
RX_MSDU_END_INFO1_L3_HDR_PAD); RX_MSDU_END_INFO1_L3_HDR_PAD);
} }
static bool ath10k_qca99x0_rx_desc_msdu_limit_error(void *rxd) static bool ath10k_qca99x0_rx_desc_msdu_limit_error(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd; struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return !!(rx_desc->msdu_end.common.info0 & return !!(rx_desc->msdu_end.common.info0 &
__cpu_to_le32(RX_MSDU_END_INFO0_MSDU_LIMIT_ERR)); __cpu_to_le32(RX_MSDU_END_INFO0_MSDU_LIMIT_ERR));
} }
@ -160,7 +160,7 @@ const struct ath10k_htt_rx_desc_ops qca99x0_rx_desc_ops = {
static void ath10k_rx_desc_wcn3990_get_offsets(struct htt_rx_ring_rx_desc_offsets *off) static void ath10k_rx_desc_wcn3990_get_offsets(struct htt_rx_ring_rx_desc_offsets *off)
{ {
#define desc_offset(x) (offsetof(struct htt_rx_desc, x) / 4) #define desc_offset(x) (offsetof(struct htt_rx_desc_new, x) / 4)
off->mac80211_hdr_offset = __cpu_to_le16(desc_offset(rx_hdr_status)); off->mac80211_hdr_offset = __cpu_to_le16(desc_offset(rx_hdr_status));
off->msdu_payload_offset = __cpu_to_le16(desc_offset(msdu_payload)); off->msdu_payload_offset = __cpu_to_le16(desc_offset(msdu_payload));
off->ppdu_start_offset = __cpu_to_le16(desc_offset(ppdu_start)); off->ppdu_start_offset = __cpu_to_le16(desc_offset(ppdu_start));
@ -176,80 +176,87 @@ static void ath10k_rx_desc_wcn3990_get_offsets(struct htt_rx_ring_rx_desc_offset
#undef desc_offset #undef desc_offset
} }
static struct rx_attention * static struct htt_rx_desc *
ath10k_rx_desc_wcn3990_get_attention(void *rxd) ath10k_rx_desc_wcn3990_from_raw_buffer(void *buff)
{ {
struct htt_rx_desc *rx_desc = rxd; return &((struct htt_rx_desc_new*)buff)->base;
}
static struct rx_attention *
ath10k_rx_desc_wcn3990_get_attention(struct htt_rx_desc *rxd)
{
struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->attention; return &rx_desc->attention;
} }
static struct rx_frag_info_common * static struct rx_frag_info_common *
ath10k_rx_desc_wcn3990_get_frag_info(void *rxd) ath10k_rx_desc_wcn3990_get_frag_info(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->frag_info.common; return &rx_desc->frag_info.common;
} }
static struct rx_mpdu_start * static struct rx_mpdu_start *
ath10k_rx_desc_wcn3990_get_mpdu_start(void *rxd) ath10k_rx_desc_wcn3990_get_mpdu_start(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->mpdu_start; return &rx_desc->mpdu_start;
} }
static struct rx_mpdu_end * static struct rx_mpdu_end *
ath10k_rx_desc_wcn3990_get_mpdu_end(void *rxd) ath10k_rx_desc_wcn3990_get_mpdu_end(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->mpdu_end; return &rx_desc->mpdu_end;
} }
static struct rx_msdu_start_common * static struct rx_msdu_start_common *
ath10k_rx_desc_wcn3990_get_msdu_start(void *rxd) ath10k_rx_desc_wcn3990_get_msdu_start(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->msdu_start.common; return &rx_desc->msdu_start.common;
} }
static struct rx_msdu_end_common * static struct rx_msdu_end_common *
ath10k_rx_desc_wcn3990_get_msdu_end(void *rxd) ath10k_rx_desc_wcn3990_get_msdu_end(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->msdu_end.common; return &rx_desc->msdu_end.common;
} }
static struct rx_ppdu_start * static struct rx_ppdu_start *
ath10k_rx_desc_wcn3990_get_ppdu_start(void *rxd) ath10k_rx_desc_wcn3990_get_ppdu_start(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->ppdu_start; return &rx_desc->ppdu_start;
} }
static struct rx_ppdu_end_common * static struct rx_ppdu_end_common *
ath10k_rx_desc_wcn3990_get_ppdu_end(void *rxd) ath10k_rx_desc_wcn3990_get_ppdu_end(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return &rx_desc->ppdu_end.common; return &rx_desc->ppdu_end.common;
} }
static u8 * static u8 *
ath10k_rx_desc_wcn3990_get_rx_hdr_status(void *rxd) ath10k_rx_desc_wcn3990_get_rx_hdr_status(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return rx_desc->rx_hdr_status; return rx_desc->rx_hdr_status;
} }
static u8 * static u8 *
ath10k_rx_desc_wcn3990_get_msdu_payload(void *rxd) ath10k_rx_desc_wcn3990_get_msdu_payload(struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc *rx_desc = rxd; struct htt_rx_desc_new *rx_desc = container_of(rxd, struct htt_rx_desc_new, base);
return rx_desc->msdu_payload; return rx_desc->msdu_payload;
} }
const struct ath10k_htt_rx_desc_ops wcn3990_rx_desc_ops = { const struct ath10k_htt_rx_desc_ops wcn3990_rx_desc_ops = {
.rx_desc_size = sizeof(struct htt_rx_desc), .rx_desc_size = sizeof(struct htt_rx_desc_new),
.rx_desc_msdu_payload_offset = offsetof(struct htt_rx_desc, msdu_payload), .rx_desc_msdu_payload_offset = offsetof(struct htt_rx_desc_new, msdu_payload),
.rx_desc_from_raw_buffer = ath10k_rx_desc_wcn3990_from_raw_buffer,
.rx_desc_get_offsets = ath10k_rx_desc_wcn3990_get_offsets, .rx_desc_get_offsets = ath10k_rx_desc_wcn3990_get_offsets,
.rx_desc_get_attention = ath10k_rx_desc_wcn3990_get_attention, .rx_desc_get_attention = ath10k_rx_desc_wcn3990_get_attention,
.rx_desc_get_frag_info = ath10k_rx_desc_wcn3990_get_frag_info, .rx_desc_get_frag_info = ath10k_rx_desc_wcn3990_get_frag_info,

222
htt.h
View File

@ -2183,16 +2183,15 @@ static inline bool ath10k_htt_rx_proc_rx_frag_ind(struct ath10k_htt *htt,
/* The rx descriptor structure layout is programmed via rx ring setup /* The rx descriptor structure layout is programmed via rx ring setup
* so that FW knows how to transfer the rx descriptor to the host. * so that FW knows how to transfer the rx descriptor to the host.
* Buffers like this are placed on the rx ring.
* Unfortunately, though, QCA6174's firmware doesn't currently behave correctly * Unfortunately, though, QCA6174's firmware doesn't currently behave correctly
* when modifying the structure layout of the rx descriptor * when modifying the structure layout of the rx descriptor beyond what it expects
* (even if it correctly programmed during the rx ring setup). * (even if it correctly programmed during the rx ring setup).
* Therefore we must keep two different memory layouts, abstract the rx descriptor * Therefore we must keep two different memory layouts, abstract the rx descriptor
* representation and use ath10k_rx_desc_ops * representation and use ath10k_rx_desc_ops
* for correctly accessing rx descriptor data. * for correctly accessing rx descriptor data.
*/ */
/* rx descriptor for wcn3990 and possibly extensible for newer cards */ /* base struct used for abstracting the rx descritor representation */
struct htt_rx_desc { struct htt_rx_desc {
union { union {
/* This field is filled on the host using the msdu buffer /* This field is filled on the host using the msdu buffer
@ -2201,6 +2200,13 @@ struct htt_rx_desc {
struct fw_rx_desc_base fw_desc; struct fw_rx_desc_base fw_desc;
u32 pad; u32 pad;
} __packed; } __packed;
} __packed;
/* rx descriptor for wcn3990 and possibly extensible for newer cards
* Buffers like this are placed on the rx ring.
*/
struct htt_rx_desc_new {
struct htt_rx_desc base;
struct { struct {
struct rx_attention attention; struct rx_attention attention;
struct rx_frag_info frag_info; struct rx_frag_info frag_info;
@ -2217,15 +2223,10 @@ struct htt_rx_desc {
/* QCA6174, QCA988x, QCA99x0 dedicated rx descriptor to make sure their firmware /* QCA6174, QCA988x, QCA99x0 dedicated rx descriptor to make sure their firmware
* works correctly. * works correctly.
* Buffers like this are placed on the rx ring.
*/ */
struct htt_rx_desc_old_qca { struct htt_rx_desc_old_qca {
union { struct htt_rx_desc base;
/* This field is filled on the host using the msdu buffer
* from htt_rx_indication
*/
struct fw_rx_desc_base fw_desc;
u32 pad;
} __packed;
struct { struct {
struct rx_attention attention; struct rx_attention attention;
struct rx_frag_info_old_qca frag_info; struct rx_frag_info_old_qca frag_info;
@ -2254,19 +2255,25 @@ struct ath10k_htt_rx_desc_ops {
* When a field is not provided the default implementation gets used * When a field is not provided the default implementation gets used
* (see the ath10k_rx_desc_* operations below for more info about the defaults) * (see the ath10k_rx_desc_* operations below for more info about the defaults)
*/ */
bool (*rx_desc_get_msdu_limit_error)(void *rxd); bool (*rx_desc_get_msdu_limit_error)(struct htt_rx_desc *rxd);
int (*rx_desc_get_l3_pad_bytes)(void *rxd); int (*rx_desc_get_l3_pad_bytes)(struct htt_rx_desc *rxd);
/* Safely cast from a void* buffer containing an rx descriptor
* to the proper rx_desc structure
*/
struct htt_rx_desc *(*rx_desc_from_raw_buffer)(void *buff);
void (*rx_desc_get_offsets)(struct htt_rx_ring_rx_desc_offsets *offs); void (*rx_desc_get_offsets)(struct htt_rx_ring_rx_desc_offsets *offs);
struct rx_attention *(*rx_desc_get_attention)(void *rxd); struct rx_attention *(*rx_desc_get_attention)(struct htt_rx_desc *rxd);
struct rx_frag_info_common *(*rx_desc_get_frag_info)(void *rxd); struct rx_frag_info_common *(*rx_desc_get_frag_info)(struct htt_rx_desc *rxd);
struct rx_mpdu_start *(*rx_desc_get_mpdu_start)(void *rxd); struct rx_mpdu_start *(*rx_desc_get_mpdu_start)(struct htt_rx_desc *rxd);
struct rx_mpdu_end *(*rx_desc_get_mpdu_end)(void *rxd); struct rx_mpdu_end *(*rx_desc_get_mpdu_end)(struct htt_rx_desc *rxd);
struct rx_msdu_start_common *(*rx_desc_get_msdu_start)(void *rxd); struct rx_msdu_start_common *(*rx_desc_get_msdu_start)(struct htt_rx_desc *rxd);
struct rx_msdu_end_common *(*rx_desc_get_msdu_end)(void *rxd); struct rx_msdu_end_common *(*rx_desc_get_msdu_end)(struct htt_rx_desc *rxd);
struct rx_ppdu_start *(*rx_desc_get_ppdu_start)(void *rxd); struct rx_ppdu_start *(*rx_desc_get_ppdu_start)(struct htt_rx_desc *rxd);
struct rx_ppdu_end_common *(*rx_desc_get_ppdu_end)(void *rxd); struct rx_ppdu_end_common *(*rx_desc_get_ppdu_end)(struct htt_rx_desc *rxd);
u8 *(*rx_desc_get_rx_hdr_status)(void *rxd); u8 *(*rx_desc_get_rx_hdr_status)(struct htt_rx_desc *rxd);
u8 *(*rx_desc_get_msdu_payload)(void *rxd); u8 *(*rx_desc_get_msdu_payload)(struct htt_rx_desc *rxd);
}; };
extern const struct ath10k_htt_rx_desc_ops qca988x_rx_desc_ops; extern const struct ath10k_htt_rx_desc_ops qca988x_rx_desc_ops;
@ -2274,8 +2281,8 @@ extern const struct ath10k_htt_rx_desc_ops qca99x0_rx_desc_ops;
extern const struct ath10k_htt_rx_desc_ops wcn3990_rx_desc_ops; extern const struct ath10k_htt_rx_desc_ops wcn3990_rx_desc_ops;
static inline int static inline int
ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
if (hw->rx_desc_ops->rx_desc_get_l3_pad_bytes) if (hw->rx_desc_ops->rx_desc_get_l3_pad_bytes)
return hw->rx_desc_ops->rx_desc_get_l3_pad_bytes(rxd); return hw->rx_desc_ops->rx_desc_get_l3_pad_bytes(rxd);
@ -2283,8 +2290,8 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
} }
static inline bool static inline bool
ath10k_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
if (hw->rx_desc_ops->rx_desc_get_msdu_limit_error) if (hw->rx_desc_ops->rx_desc_get_msdu_limit_error)
return hw->rx_desc_ops->rx_desc_get_msdu_limit_error(rxd); return hw->rx_desc_ops->rx_desc_get_msdu_limit_error(rxd);
@ -2297,9 +2304,18 @@ ath10k_rx_desc_msdu_limit_error(struct ath10k_hw_params *hw,
* to switch the default implementation to the new rx_desc, since this would * to switch the default implementation to the new rx_desc, since this would
* make the extension easier . * make the extension easier .
*/ */
static inline struct htt_rx_desc *
ath10k_htt_rx_desc_from_raw_buffer(struct ath10k_hw_params *hw, void *buff)
{
if(hw->rx_desc_ops->rx_desc_from_raw_buffer)
return hw->rx_desc_ops->rx_desc_from_raw_buffer(buff);
return &((struct htt_rx_desc_old_qca*)buff)->base;
}
static inline void static inline void
ath10k_rx_desc_get_offsets(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_offsets(struct ath10k_hw_params *hw,
struct htt_rx_ring_rx_desc_offsets *off) struct htt_rx_ring_rx_desc_offsets *off)
{ {
if(hw->rx_desc_ops->rx_desc_get_offsets) if(hw->rx_desc_ops->rx_desc_get_offsets)
{ {
@ -2323,123 +2339,153 @@ ath10k_rx_desc_get_offsets(struct ath10k_hw_params *hw,
} }
static inline struct rx_attention * static inline struct rx_attention *
ath10k_rx_desc_get_attention(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_attention(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_attention) if(hw->rx_desc_ops->rx_desc_get_attention)
{
return hw->rx_desc_ops->rx_desc_get_attention(rxd); return hw->rx_desc_ops->rx_desc_get_attention(rxd);
}
return &rx_desc->attention; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->attention;
}
} }
static inline struct rx_frag_info_common * static inline struct rx_frag_info_common *
ath10k_rx_desc_get_frag_info(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_frag_info(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_frag_info) if(hw->rx_desc_ops->rx_desc_get_frag_info)
{
return hw->rx_desc_ops->rx_desc_get_frag_info(rxd); return hw->rx_desc_ops->rx_desc_get_frag_info(rxd);
}
return &rx_desc->frag_info.common; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->frag_info.common;
}
} }
static inline struct rx_mpdu_start * static inline struct rx_mpdu_start *
ath10k_rx_desc_get_mpdu_start(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_mpdu_start(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_mpdu_start) if(hw->rx_desc_ops->rx_desc_get_mpdu_start)
{
return hw->rx_desc_ops->rx_desc_get_mpdu_start(rxd); return hw->rx_desc_ops->rx_desc_get_mpdu_start(rxd);
}
return &rx_desc->mpdu_start; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->mpdu_start;
}
} }
static inline struct rx_mpdu_end * static inline struct rx_mpdu_end *
ath10k_rx_desc_get_mpdu_end(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_mpdu_end(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_mpdu_end) if(hw->rx_desc_ops->rx_desc_get_mpdu_end)
{
return hw->rx_desc_ops->rx_desc_get_mpdu_end(rxd); return hw->rx_desc_ops->rx_desc_get_mpdu_end(rxd);
}
return &rx_desc->mpdu_end; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->mpdu_end;
}
} }
static inline struct rx_msdu_start_common * static inline struct rx_msdu_start_common *
ath10k_rx_desc_get_msdu_start(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_msdu_start(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_msdu_start) if(hw->rx_desc_ops->rx_desc_get_msdu_start)
{
return hw->rx_desc_ops->rx_desc_get_msdu_start(rxd); return hw->rx_desc_ops->rx_desc_get_msdu_start(rxd);
}
return &rx_desc->msdu_start.common; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->msdu_start.common;
}
} }
static inline struct rx_msdu_end_common * static inline struct rx_msdu_end_common *
ath10k_rx_desc_get_msdu_end(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_msdu_end(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_msdu_end) if(hw->rx_desc_ops->rx_desc_get_msdu_end)
{
return hw->rx_desc_ops->rx_desc_get_msdu_end(rxd); return hw->rx_desc_ops->rx_desc_get_msdu_end(rxd);
}
return &rx_desc->msdu_end.common; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->msdu_end.common;
}
} }
static inline struct rx_ppdu_start * static inline struct rx_ppdu_start *
ath10k_rx_desc_get_ppdu_start(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_ppdu_start(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_ppdu_start) if(hw->rx_desc_ops->rx_desc_get_ppdu_start)
{
return hw->rx_desc_ops->rx_desc_get_ppdu_start(rxd); return hw->rx_desc_ops->rx_desc_get_ppdu_start(rxd);
}
return &rx_desc->ppdu_start; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->ppdu_start;
}
} }
static inline struct rx_ppdu_end_common * static inline struct rx_ppdu_end_common *
ath10k_rx_desc_get_ppdu_end(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_ppdu_end(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_ppdu_end) if(hw->rx_desc_ops->rx_desc_get_ppdu_end)
{
return hw->rx_desc_ops->rx_desc_get_ppdu_end(rxd); return hw->rx_desc_ops->rx_desc_get_ppdu_end(rxd);
}
return &rx_desc->ppdu_end.common; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return &rx_desc->ppdu_end.common;
}
} }
static inline u8 * static inline u8 *
ath10k_rx_desc_get_rx_hdr_status(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_rx_hdr_status(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_rx_hdr_status) if(hw->rx_desc_ops->rx_desc_get_rx_hdr_status)
{
return hw->rx_desc_ops->rx_desc_get_rx_hdr_status(rxd); return hw->rx_desc_ops->rx_desc_get_rx_hdr_status(rxd);
}
return rx_desc->rx_hdr_status; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return rx_desc->rx_hdr_status;
}
} }
static inline u8 * static inline u8 *
ath10k_rx_desc_get_msdu_payload(struct ath10k_hw_params *hw, ath10k_htt_rx_desc_get_msdu_payload(struct ath10k_hw_params *hw,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct htt_rx_desc_old_qca *rx_desc = rxd;
if(hw->rx_desc_ops->rx_desc_get_msdu_payload) if(hw->rx_desc_ops->rx_desc_get_msdu_payload)
{
return hw->rx_desc_ops->rx_desc_get_msdu_payload(rxd); return hw->rx_desc_ops->rx_desc_get_msdu_payload(rxd);
}
return rx_desc->msdu_payload; else
{
struct htt_rx_desc_old_qca *rx_desc = container_of(rxd, struct htt_rx_desc_old_qca, base);
return rx_desc->msdu_payload;
}
} }
#define HTT_RX_DESC_HL_INFO_SEQ_NUM_MASK 0x00000fff #define HTT_RX_DESC_HL_INFO_SEQ_NUM_MASK 0x00000fff

173
htt_rx.c
View File

@ -129,7 +129,7 @@ static void *ath10k_htt_get_vaddr_ring_64(struct ath10k_htt *htt)
static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
{ {
struct ath10k_hw_params *hw = &htt->ar->hw_params; struct ath10k_hw_params *hw = &htt->ar->hw_params;
void *rx_desc; struct htt_rx_desc *rx_desc;
struct ath10k_skb_rxcb *rxcb; struct ath10k_skb_rxcb *rxcb;
struct sk_buff *skb; struct sk_buff *skb;
dma_addr_t paddr; dma_addr_t paddr;
@ -164,8 +164,8 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
skb->data); skb->data);
/* Clear rx_desc attention word before posting to Rx ring */ /* Clear rx_desc attention word before posting to Rx ring */
rx_desc = skb->data; rx_desc = ath10k_htt_rx_desc_from_raw_buffer(hw, skb->data);
ath10k_rx_desc_get_attention(hw, rx_desc)->flags = __cpu_to_le32(0); ath10k_htt_rx_desc_get_attention(hw, rx_desc)->flags = __cpu_to_le32(0);
paddr = dma_map_single(htt->ar->dev, skb->data, paddr = dma_map_single(htt->ar->dev, skb->data,
skb->len + skb_tailroom(skb), skb->len + skb_tailroom(skb),
@ -347,7 +347,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
int msdu_len, msdu_chaining = 0; int msdu_len, msdu_chaining = 0;
struct sk_buff *msdu; struct sk_buff *msdu;
void *rx_desc; struct htt_rx_desc *rx_desc;
struct rx_attention *rx_desc_attention; struct rx_attention *rx_desc_attention;
struct rx_frag_info_common *rx_desc_frag_info_common; struct rx_frag_info_common *rx_desc_frag_info_common;
struct rx_msdu_start_common *rx_desc_msdu_start_common; struct rx_msdu_start_common *rx_desc_msdu_start_common;
@ -366,11 +366,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
__skb_queue_tail(amsdu, msdu); __skb_queue_tail(amsdu, msdu);
rx_desc = msdu->data; rx_desc = ath10k_htt_rx_desc_from_raw_buffer(hw, msdu->data);
rx_desc_attention = ath10k_rx_desc_get_attention(hw, rx_desc); rx_desc_attention = ath10k_htt_rx_desc_get_attention(hw, rx_desc);
rx_desc_msdu_start_common = ath10k_rx_desc_get_msdu_start(hw, rx_desc); rx_desc_msdu_start_common = ath10k_htt_rx_desc_get_msdu_start(hw, rx_desc);
rx_desc_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rx_desc); rx_desc_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rx_desc);
rx_desc_frag_info_common = ath10k_rx_desc_get_frag_info(hw, rx_desc); rx_desc_frag_info_common = ath10k_htt_rx_desc_get_frag_info(hw, rx_desc);
/* FIXME: we must report msdu payload since this is what caller /* FIXME: we must report msdu payload since this is what caller
* expects now * expects now
@ -424,10 +424,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
last_msdu = __le32_to_cpu(rx_desc_msdu_end_common->info0) & last_msdu = __le32_to_cpu(rx_desc_msdu_end_common->info0) &
RX_MSDU_END_INFO0_LAST_MSDU; RX_MSDU_END_INFO0_LAST_MSDU;
// FIXME: why are we skipping the first part of the rx_desc? /* FIXME: why are we skipping the first part of the rx_desc? */
// Note that here we are making assumptions about the internal
// layout of rx_desc, as things are now this works correctly
// in all cases, but FIXME!
trace_ath10k_htt_rx_desc(ar, rx_desc + sizeof(u32), trace_ath10k_htt_rx_desc(ar, rx_desc + sizeof(u32),
hw->rx_desc_ops->rx_desc_size - sizeof(u32)); hw->rx_desc_ops->rx_desc_size - sizeof(u32));
@ -500,10 +497,10 @@ static int ath10k_htt_rx_handle_amsdu_mon_32(struct ath10k_htt *htt,
struct sk_buff *prev_frag_buf; struct sk_buff *prev_frag_buf;
u8 last_frag; u8 last_frag;
struct htt_rx_in_ord_msdu_desc *ind_desc = *msdu_desc; struct htt_rx_in_ord_msdu_desc *ind_desc = *msdu_desc;
void *rxd; struct htt_rx_desc *rxd;
int amsdu_len = __le16_to_cpu(ind_desc->msdu_len); int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
rxd = msdu->data; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, msdu->data);
trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size); trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size);
skb_put(msdu, hw->rx_desc_ops->rx_desc_size); skb_put(msdu, hw->rx_desc_ops->rx_desc_size);
@ -577,10 +574,10 @@ ath10k_htt_rx_handle_amsdu_mon_64(struct ath10k_htt *htt,
struct sk_buff *prev_frag_buf; struct sk_buff *prev_frag_buf;
u8 last_frag; u8 last_frag;
struct htt_rx_in_ord_msdu_desc_ext *ind_desc = *msdu_desc; struct htt_rx_in_ord_msdu_desc_ext *ind_desc = *msdu_desc;
void *rxd; struct htt_rx_desc *rxd;
int amsdu_len = __le16_to_cpu(ind_desc->msdu_len); int amsdu_len = __le16_to_cpu(ind_desc->msdu_len);
rxd = msdu->data; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, msdu->data);
trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size); trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size);
skb_put(msdu, hw->rx_desc_ops->rx_desc_size); skb_put(msdu, hw->rx_desc_ops->rx_desc_size);
@ -649,7 +646,7 @@ static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32; struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs32;
void *rxd; struct htt_rx_desc *rxd;
struct rx_attention *rxd_attention; struct rx_attention *rxd_attention;
struct sk_buff *msdu; struct sk_buff *msdu;
int msdu_count, ret; int msdu_count, ret;
@ -685,8 +682,8 @@ static int ath10k_htt_rx_pop_paddr32_list(struct ath10k_htt *htt,
__skb_queue_tail(list, msdu); __skb_queue_tail(list, msdu);
if (!is_offload) { if (!is_offload) {
rxd = msdu->data; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, msdu->data);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size); trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size);
@ -714,7 +711,7 @@ static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
struct ath10k *ar = htt->ar; struct ath10k *ar = htt->ar;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64; struct htt_rx_in_ord_msdu_desc_ext *msdu_desc = ev->msdu_descs64;
void *rxd; struct htt_rx_desc *rxd;
struct rx_attention *rxd_attention; struct rx_attention *rxd_attention;
struct sk_buff *msdu; struct sk_buff *msdu;
int msdu_count, ret; int msdu_count, ret;
@ -749,8 +746,8 @@ static int ath10k_htt_rx_pop_paddr64_list(struct ath10k_htt *htt,
__skb_queue_tail(list, msdu); __skb_queue_tail(list, msdu);
if (!is_offload) { if (!is_offload) {
rxd = msdu->data; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, msdu->data);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size); trace_ath10k_htt_rx_desc(ar, rxd, hw->rx_desc_ops->rx_desc_size);
@ -964,16 +961,16 @@ static inline u8 ath10k_bw_to_mac80211_bw(u8 bw)
static void ath10k_htt_rx_h_rates(struct ath10k *ar, static void ath10k_htt_rx_h_rates(struct ath10k *ar,
struct ieee80211_rx_status *status, struct ieee80211_rx_status *status,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct rx_attention *rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); struct rx_attention *rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
struct rx_mpdu_start *rxd_mpdu_start = ath10k_rx_desc_get_mpdu_start(hw, rxd); struct rx_mpdu_start *rxd_mpdu_start = ath10k_htt_rx_desc_get_mpdu_start(hw, rxd);
struct rx_mpdu_end *rxd_mpdu_end = ath10k_rx_desc_get_mpdu_end(hw, rxd); struct rx_mpdu_end *rxd_mpdu_end = ath10k_htt_rx_desc_get_mpdu_end(hw, rxd);
struct rx_msdu_start_common *rxd_msdu_start_common = ath10k_rx_desc_get_msdu_start(hw, rxd); struct rx_msdu_start_common *rxd_msdu_start_common = ath10k_htt_rx_desc_get_msdu_start(hw, rxd);
struct rx_msdu_end_common *rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); struct rx_msdu_end_common *rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
struct rx_ppdu_start *rxd_ppdu_start = ath10k_rx_desc_get_ppdu_start(hw, rxd); struct rx_ppdu_start *rxd_ppdu_start = ath10k_htt_rx_desc_get_ppdu_start(hw, rxd);
u8 *rxd_msdu_payload = ath10k_rx_desc_get_msdu_payload(hw, rxd); u8 *rxd_msdu_payload = ath10k_htt_rx_desc_get_msdu_payload(hw, rxd);
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
u8 cck, rate, bw, sgi, mcs, nss; u8 cck, rate, bw, sgi, mcs, nss;
u8 preamble = 0; u8 preamble = 0;
@ -1087,12 +1084,12 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
} }
static struct ieee80211_channel * static struct ieee80211_channel *
ath10k_htt_rx_h_peer_channel(struct ath10k *ar, void *rxd) ath10k_htt_rx_h_peer_channel(struct ath10k *ar, struct htt_rx_desc *rxd)
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct rx_attention *rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); struct rx_attention *rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
struct rx_msdu_end_common *rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); struct rx_msdu_end_common *rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
struct rx_mpdu_start *rxd_mpdu_start = ath10k_rx_desc_get_mpdu_start(hw, rxd); struct rx_mpdu_start *rxd_mpdu_start = ath10k_htt_rx_desc_get_mpdu_start(hw, rxd);
struct ath10k_peer *peer; struct ath10k_peer *peer;
struct ath10k_vif *arvif; struct ath10k_vif *arvif;
struct cfg80211_chan_def def; struct cfg80211_chan_def def;
@ -1169,7 +1166,7 @@ ath10k_htt_rx_h_any_channel(struct ath10k *ar)
static bool ath10k_htt_rx_h_channel(struct ath10k *ar, static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
struct ieee80211_rx_status *status, struct ieee80211_rx_status *status,
void *rxd, struct htt_rx_desc *rxd,
u32 vdev_id) u32 vdev_id)
{ {
struct ieee80211_channel *ch; struct ieee80211_channel *ch;
@ -1199,10 +1196,10 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
static void ath10k_htt_rx_h_signal(struct ath10k *ar, static void ath10k_htt_rx_h_signal(struct ath10k *ar,
struct ieee80211_rx_status *status, struct ieee80211_rx_status *status,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct rx_ppdu_start *rxd_ppdu_start = ath10k_rx_desc_get_ppdu_start(hw, rxd); struct rx_ppdu_start *rxd_ppdu_start = ath10k_htt_rx_desc_get_ppdu_start(hw, rxd);
int i; int i;
for (i = 0; i < IEEE80211_MAX_CHAINS ; i++) { for (i = 0; i < IEEE80211_MAX_CHAINS ; i++) {
@ -1224,10 +1221,10 @@ static void ath10k_htt_rx_h_signal(struct ath10k *ar,
static void ath10k_htt_rx_h_mactime(struct ath10k *ar, static void ath10k_htt_rx_h_mactime(struct ath10k *ar,
struct ieee80211_rx_status *status, struct ieee80211_rx_status *status,
void *rxd) struct htt_rx_desc *rxd)
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct rx_ppdu_end_common *rxd_ppdu_end_common = ath10k_rx_desc_get_ppdu_end(hw, rxd); struct rx_ppdu_end_common *rxd_ppdu_end_common = ath10k_htt_rx_desc_get_ppdu_end(hw, rxd);
/* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This /* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This
* means all prior MSDUs in a PPDU are reported to mac80211 without the * means all prior MSDUs in a PPDU are reported to mac80211 without the
* TSF. Is it worth holding frames until end of PPDU is known? * TSF. Is it worth holding frames until end of PPDU is known?
@ -1245,7 +1242,7 @@ static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
{ {
struct sk_buff *first; struct sk_buff *first;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_attention *rxd_attention; struct rx_attention *rxd_attention;
bool is_first_ppdu; bool is_first_ppdu;
bool is_last_ppdu; bool is_last_ppdu;
@ -1254,8 +1251,8 @@ static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
return; return;
first = skb_peek(amsdu); first = skb_peek(amsdu);
rxd = (void *)first->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)first->data - hw->rx_desc_ops->rx_desc_size);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
is_first_ppdu = !!(rxd_attention->flags & is_first_ppdu = !!(rxd_attention->flags &
__cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU)); __cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU));
@ -1399,7 +1396,7 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
{ {
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_end_common *rxd_msdu_end_common; struct rx_msdu_end_common *rxd_msdu_end_common;
size_t hdr_len; size_t hdr_len;
size_t crypto_len; size_t crypto_len;
@ -1409,8 +1406,8 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
int bytes_aligned = ar->hw_params.decap_align_bytes; int bytes_aligned = ar->hw_params.decap_align_bytes;
u8 *qos; u8 *qos;
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
is_first = !!(rxd_msdu_end_common->info0 & is_first = !!(rxd_msdu_end_common->info0 &
__cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU));
is_last = !!(rxd_msdu_end_common->info0 & is_last = !!(rxd_msdu_end_common->info0 &
@ -1431,7 +1428,7 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
* error packets. If limit exceeds, hw sends all remaining MSDUs as * error packets. If limit exceeds, hw sends all remaining MSDUs as
* a single last MSDU with this msdu limit error set. * a single last MSDU with this msdu limit error set.
*/ */
msdu_limit_err = ath10k_rx_desc_msdu_limit_error(hw, rxd); msdu_limit_err = ath10k_htt_rx_desc_msdu_limit_error(hw, rxd);
/* If MSDU limit error happens, then don't warn on, the partial raw MSDU /* If MSDU limit error happens, then don't warn on, the partial raw MSDU
* without first MSDU is expected in that case, and handled later here. * without first MSDU is expected in that case, and handled later here.
@ -1525,7 +1522,7 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
void *rxd; struct htt_rx_desc *rxd;
size_t hdr_len; size_t hdr_len;
u8 da[ETH_ALEN]; u8 da[ETH_ALEN];
u8 sa[ETH_ALEN]; u8 sa[ETH_ALEN];
@ -1544,9 +1541,9 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
*/ */
/* pull decapped header and copy SA & DA */ /* pull decapped header and copy SA & DA */
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd); l3_pad_bytes = ath10k_htt_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
skb_put(msdu, l3_pad_bytes); skb_put(msdu, l3_pad_bytes);
hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes); hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes);
@ -1583,7 +1580,7 @@ static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar,
{ {
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_end_common *rxd_msdu_end_common; struct rx_msdu_end_common *rxd_msdu_end_common;
u8 *rxd_rx_hdr_status; u8 *rxd_rx_hdr_status;
size_t hdr_len, crypto_len; size_t hdr_len, crypto_len;
@ -1591,9 +1588,9 @@ static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar,
bool is_first, is_last, is_amsdu; bool is_first, is_last, is_amsdu;
int bytes_aligned = ar->hw_params.decap_align_bytes; int bytes_aligned = ar->hw_params.decap_align_bytes;
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
rxd_rx_hdr_status = ath10k_rx_desc_get_rx_hdr_status(hw, rxd); rxd_rx_hdr_status = ath10k_htt_rx_desc_get_rx_hdr_status(hw, rxd);
hdr = (void *)rxd_rx_hdr_status; hdr = (void *)rxd_rx_hdr_status;
is_first = !!(rxd_msdu_end_common->info0 & is_first = !!(rxd_msdu_end_common->info0 &
@ -1632,7 +1629,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
u8 da[ETH_ALEN]; u8 da[ETH_ALEN];
u8 sa[ETH_ALEN]; u8 sa[ETH_ALEN];
int l3_pad_bytes; int l3_pad_bytes;
void *rxd; struct htt_rx_desc *rxd;
int bytes_aligned = ar->hw_params.decap_align_bytes; int bytes_aligned = ar->hw_params.decap_align_bytes;
/* Delivered decapped frame: /* Delivered decapped frame:
@ -1644,8 +1641,8 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
if (WARN_ON_ONCE(!rfc1042)) if (WARN_ON_ONCE(!rfc1042))
return; return;
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd); l3_pad_bytes = ath10k_htt_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
skb_put(msdu, l3_pad_bytes); skb_put(msdu, l3_pad_bytes);
skb_pull(msdu, l3_pad_bytes); skb_pull(msdu, l3_pad_bytes);
@ -1690,7 +1687,7 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
size_t hdr_len; size_t hdr_len;
int l3_pad_bytes; int l3_pad_bytes;
void *rxd; struct htt_rx_desc *rxd;
int bytes_aligned = ar->hw_params.decap_align_bytes; int bytes_aligned = ar->hw_params.decap_align_bytes;
/* Delivered decapped frame: /* Delivered decapped frame:
@ -1699,8 +1696,8 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
* [payload] * [payload]
*/ */
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd); l3_pad_bytes = ath10k_htt_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
skb_put(msdu, l3_pad_bytes); skb_put(msdu, l3_pad_bytes);
skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes); skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes);
@ -1726,7 +1723,7 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
bool is_decrypted) bool is_decrypted)
{ {
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_start_common *rxd_msdu_start_common; struct rx_msdu_start_common *rxd_msdu_start_common;
enum rx_msdu_decap_format decap; enum rx_msdu_decap_format decap;
@ -1741,8 +1738,8 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
* [rfc1042/llc] * [rfc1042/llc]
*/ */
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_start_common = ath10k_rx_desc_get_msdu_start(hw, rxd); rxd_msdu_start_common = ath10k_htt_rx_desc_get_msdu_start(hw, rxd);
decap = MS(__le32_to_cpu(rxd_msdu_start_common->info1), decap = MS(__le32_to_cpu(rxd_msdu_start_common->info1),
RX_MSDU_START_INFO1_DECAP_FORMAT); RX_MSDU_START_INFO1_DECAP_FORMAT);
@ -1767,7 +1764,7 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
static int ath10k_htt_rx_get_csum_state(struct ath10k_hw_params *hw, struct sk_buff *skb) static int ath10k_htt_rx_get_csum_state(struct ath10k_hw_params *hw, struct sk_buff *skb)
{ {
void *rxd; struct htt_rx_desc *rxd;
struct rx_attention *rxd_attention; struct rx_attention *rxd_attention;
struct rx_msdu_start_common *rxd_msdu_start_common; struct rx_msdu_start_common *rxd_msdu_start_common;
u32 flags, info; u32 flags, info;
@ -1775,9 +1772,9 @@ static int ath10k_htt_rx_get_csum_state(struct ath10k_hw_params *hw, struct sk_b
bool is_tcp, is_udp; bool is_tcp, is_udp;
bool ip_csum_ok, tcpudp_csum_ok; bool ip_csum_ok, tcpudp_csum_ok;
rxd = (void *)skb->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)skb->data - hw->rx_desc_ops->rx_desc_size);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
rxd_msdu_start_common = ath10k_rx_desc_get_msdu_start(hw, rxd); rxd_msdu_start_common = ath10k_htt_rx_desc_get_msdu_start(hw, rxd);
flags = __le32_to_cpu(rxd_attention->flags); flags = __le32_to_cpu(rxd_attention->flags);
info = __le32_to_cpu(rxd_msdu_start_common->info1); info = __le32_to_cpu(rxd_msdu_start_common->info1);
@ -1895,7 +1892,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
struct sk_buff *last; struct sk_buff *last;
struct sk_buff *msdu, *temp; struct sk_buff *msdu, *temp;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_attention *rxd_attention; struct rx_attention *rxd_attention;
struct rx_mpdu_start *rxd_mpdu_start; struct rx_mpdu_start *rxd_mpdu_start;
@ -1916,9 +1913,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
return; return;
first = skb_peek(amsdu); first = skb_peek(amsdu);
rxd = (void *)first->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)first->data - hw->rx_desc_ops->rx_desc_size);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
rxd_mpdu_start = ath10k_rx_desc_get_mpdu_start(hw, rxd); rxd_mpdu_start = ath10k_htt_rx_desc_get_mpdu_start(hw, rxd);
is_mgmt = !!(rxd_attention->flags & is_mgmt = !!(rxd_attention->flags &
__cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE)); __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE));
@ -1929,7 +1926,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
/* First MSDU's Rx descriptor in an A-MSDU contains full 802.11 /* First MSDU's Rx descriptor in an A-MSDU contains full 802.11
* decapped header. It'll be used for undecapping of each MSDU. * decapped header. It'll be used for undecapping of each MSDU.
*/ */
hdr = (void *)ath10k_rx_desc_get_rx_hdr_status(hw, rxd); hdr = (void *)ath10k_htt_rx_desc_get_rx_hdr_status(hw, rxd);
memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
if (rx_hdr) if (rx_hdr)
@ -1947,8 +1944,8 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
/* Some attention flags are valid only in the last MSDU. */ /* Some attention flags are valid only in the last MSDU. */
last = skb_peek_tail(amsdu); last = skb_peek_tail(amsdu);
rxd = (void *)last->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)last->data - hw->rx_desc_ops->rx_desc_size);
rxd_attention = ath10k_rx_desc_get_attention(hw, rxd); rxd_attention = ath10k_htt_rx_desc_get_attention(hw, rxd);
attention = __le32_to_cpu(rxd_attention->flags); attention = __le32_to_cpu(rxd_attention->flags);
has_fcs_err = !!(attention & RX_ATTENTION_FLAGS_FCS_ERR); has_fcs_err = !!(attention & RX_ATTENTION_FLAGS_FCS_ERR);
@ -2150,15 +2147,15 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar,
{ {
struct sk_buff *first; struct sk_buff *first;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_start_common *rxd_msdu_start_common; struct rx_msdu_start_common *rxd_msdu_start_common;
struct rx_frag_info_common *rxd_frag_info; struct rx_frag_info_common *rxd_frag_info;
enum rx_msdu_decap_format decap; enum rx_msdu_decap_format decap;
first = skb_peek(amsdu); first = skb_peek(amsdu);
rxd = (void *)first->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)first->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_start_common = ath10k_rx_desc_get_msdu_start(hw, rxd); rxd_msdu_start_common = ath10k_htt_rx_desc_get_msdu_start(hw, rxd);
rxd_frag_info = ath10k_rx_desc_get_frag_info(hw, rxd); rxd_frag_info = ath10k_htt_rx_desc_get_frag_info(hw, rxd);
decap = MS(__le32_to_cpu(rxd_msdu_start_common->info1), decap = MS(__le32_to_cpu(rxd_msdu_start_common->info1),
RX_MSDU_START_INFO1_DECAP_FORMAT); RX_MSDU_START_INFO1_DECAP_FORMAT);
@ -2184,7 +2181,7 @@ static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar,
struct sk_buff *first; struct sk_buff *first;
bool is_first, is_last; bool is_first, is_last;
struct ath10k_hw_params *hw = &ar->hw_params; struct ath10k_hw_params *hw = &ar->hw_params;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_end_common *rxd_msdu_end_common; struct rx_msdu_end_common *rxd_msdu_end_common;
struct rx_mpdu_start *rxd_mpdu_start; struct rx_mpdu_start *rxd_mpdu_start;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
@ -2194,10 +2191,10 @@ static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar,
first = skb_peek(amsdu); first = skb_peek(amsdu);
rxd = (void *)first->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)first->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
rxd_mpdu_start = ath10k_rx_desc_get_mpdu_start(hw, rxd); rxd_mpdu_start = ath10k_htt_rx_desc_get_mpdu_start(hw, rxd);
hdr = (void *)ath10k_rx_desc_get_rx_hdr_status(hw, rxd); hdr = (void *)ath10k_htt_rx_desc_get_rx_hdr_status(hw, rxd);
is_first = !!(rxd_msdu_end_common->info0 & is_first = !!(rxd_msdu_end_common->info0 &
__cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU));
@ -3109,7 +3106,7 @@ static int ath10k_htt_rx_extract_amsdu(struct ath10k_hw_params *hw,
struct sk_buff_head *amsdu) struct sk_buff_head *amsdu)
{ {
struct sk_buff *msdu; struct sk_buff *msdu;
void *rxd; struct htt_rx_desc *rxd;
struct rx_msdu_end_common *rxd_msdu_end_common; struct rx_msdu_end_common *rxd_msdu_end_common;
if (skb_queue_empty(list)) if (skb_queue_empty(list))
@ -3121,16 +3118,16 @@ static int ath10k_htt_rx_extract_amsdu(struct ath10k_hw_params *hw,
while ((msdu = __skb_dequeue(list))) { while ((msdu = __skb_dequeue(list))) {
__skb_queue_tail(amsdu, msdu); __skb_queue_tail(amsdu, msdu);
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
if (rxd_msdu_end_common->info0 & if (rxd_msdu_end_common->info0 &
__cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)) __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))
break; break;
} }
msdu = skb_peek_tail(amsdu); msdu = skb_peek_tail(amsdu);
rxd = (void *)msdu->data - hw->rx_desc_ops->rx_desc_size; rxd = ath10k_htt_rx_desc_from_raw_buffer(hw, (void *)msdu->data - hw->rx_desc_ops->rx_desc_size);
rxd_msdu_end_common = ath10k_rx_desc_get_msdu_end(hw, rxd); rxd_msdu_end_common = ath10k_htt_rx_desc_get_msdu_end(hw, rxd);
if (!(rxd_msdu_end_common->info0 & if (!(rxd_msdu_end_common->info0 &
__cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))) { __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))) {
skb_queue_splice_init(amsdu, list); skb_queue_splice_init(amsdu, list);

View File

@ -798,7 +798,7 @@ static void ath10k_htt_fill_rx_desc_offset_32(struct ath10k_hw_params *hw, void
struct htt_rx_ring_setup_ring32 *ring = struct htt_rx_ring_setup_ring32 *ring =
(struct htt_rx_ring_setup_ring32 *)rx_ring; (struct htt_rx_ring_setup_ring32 *)rx_ring;
ath10k_rx_desc_get_offsets(hw, &ring->offsets); ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
} }
static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw, void *rx_ring) static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw, void *rx_ring)
@ -806,7 +806,7 @@ static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw, void
struct htt_rx_ring_setup_ring64 *ring = struct htt_rx_ring_setup_ring64 *ring =
(struct htt_rx_ring_setup_ring64 *)rx_ring; (struct htt_rx_ring_setup_ring64 *)rx_ring;
ath10k_rx_desc_get_offsets(hw, &ring->offsets); ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
} }
static int ath10k_htt_send_rx_ring_cfg_32(struct ath10k_htt *htt) static int ath10k_htt_send_rx_ring_cfg_32(struct ath10k_htt *htt)

7
hw.h
View File

@ -510,6 +510,8 @@ struct ath10k_hw_clk_params {
u32 outdiv; u32 outdiv;
}; };
struct htt_rx_desc_ops;
struct ath10k_hw_params { struct ath10k_hw_params {
u32 id; u32 id;
u16 dev_id; u16 dev_id;
@ -630,7 +632,6 @@ struct ath10k_hw_params {
bool dynamic_sar_support; bool dynamic_sar_support;
}; };
struct htt_rx_desc_ops;
struct htt_resp; struct htt_resp;
struct htt_data_tx_completion_ext; struct htt_data_tx_completion_ext;
struct htt_rx_ring_rx_desc_offsets; struct htt_rx_ring_rx_desc_offsets;
@ -641,10 +642,6 @@ struct ath10k_hw_ops {
int (*enable_pll_clk)(struct ath10k *ar); int (*enable_pll_clk)(struct ath10k *ar);
int (*tx_data_rssi_pad_bytes)(struct htt_resp *htt); int (*tx_data_rssi_pad_bytes)(struct htt_resp *htt);
int (*is_rssi_enable)(struct htt_resp *resp); int (*is_rssi_enable)(struct htt_resp *resp);
/* Rx descriptor operations */
}; };
extern const struct ath10k_hw_ops qca988x_ops; extern const struct ath10k_hw_ops qca988x_ops;