#ifndef _AQ_RING_H_
#define _AQ_RING_H_
#include <sys/counter.h>
#include "aq_hw.h"
#define REFILL_THRESHOLD 128
struct aq_rx_wb {
uint32_t rss_type:4;
uint32_t pkt_type:8;
uint32_t rdm_err:1;
uint32_t rsvd:6;
uint32_t rx_cntl:2;
uint32_t sph:1;
uint32_t hdr_len:10;
uint32_t rss_hash;
uint16_t dd:1;
uint16_t eop:1;
uint16_t rx_stat:4;
uint16_t rx_estat:6;
uint16_t rsc_cnt:4;
uint16_t pkt_len;
uint16_t next_desp;
uint16_t vlan;
} __packed;
struct aq_rx_desc {
union {
struct __packed {
uint64_t buf_addr;
uint64_t hdr_addr;
} read;
struct aq_rx_wb wb;
};
} __packed;
struct aq_tx_desc {
uint64_t buf_addr;
union {
struct {
uint32_t type:3;
uint32_t :1;
uint32_t len:16;
uint32_t dd:1;
uint32_t eop:1;
uint32_t cmd:8;
uint32_t :14;
uint32_t ct_idx:1;
uint32_t ct_en:1;
uint32_t pay_len:18;
} __packed;
uint64_t flags;
};
} __packed;
enum aq_tx_desc_type {
tx_desc_type_desc = 1,
tx_desc_type_ctx = 2,
};
enum aq_tx_desc_cmd {
tx_desc_cmd_vlan = 1,
tx_desc_cmd_fcs = 2,
tx_desc_cmd_ipv4 = 4,
tx_desc_cmd_l4cs = 8,
tx_desc_cmd_lso = 0x10,
tx_desc_cmd_wb = 0x20,
};
union aq_txc_desc {
struct __packed {
uint64_t flags1;
uint64_t flags2;
};
struct __packed {
uint64_t :40;
uint32_t tun_len:8;
uint32_t out_len:16;
uint32_t type:3;
uint32_t idx:1;
uint32_t vlan_tag:16;
uint32_t cmd:4;
uint32_t l2_len:7;
uint32_t l3_len:9;
uint32_t l4_len:8;
uint32_t mss_len:16;
};
} __packed;
struct aq_ring_stats {
counter_u64_t rx_pkts;
counter_u64_t rx_bytes;
counter_u64_t rx_err;
counter_u64_t irq;
counter_u64_t tx_pkts;
counter_u64_t tx_bytes;
};
struct aq_dev;
struct aq_ring {
struct aq_dev *dev;
int index;
struct if_irq irq;
int msix;
qidx_t rx_size;
int rx_buf_size;
void *rx_desc_area_ptr;
volatile struct aq_rx_desc *rx_descs;
uint64_t rx_descs_phys;
int tx_head, tx_tail;
qidx_t tx_size;
void *tx_desc_area_ptr;
volatile struct aq_tx_desc *tx_descs;
uint64_t tx_descs_phys;
struct aq_ring_stats stats;
};
int aq_ring_rx_init(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_tx_init(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_tx_start(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_tx_stop(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_rx_start(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_rx_stop(struct aq_hw *hw, struct aq_ring *ring);
int aq_ring_tx_tail_update(struct aq_hw *hw, struct aq_ring *ring, uint32_t tail);
extern struct if_txrx aq_txrx;
int aq_intr(void *arg);
#endif