#ifndef _OCE_IO_H_
#define _OCE_IO_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/dditypes.h>
#include <sys/mutex.h>
#include <sys/stream.h>
#include <sys/debug.h>
#include <sys/byteorder.h>
#include <oce_hw.h>
#include <oce_buf.h>
#define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000)
#define MBX_READY_TIMEOUT (1 * 1000 * 1000)
#define DEFAULT_DRAIN_TIME 200
#define MBX_TIMEOUT_SEC 5
#define STAT_TIMEOUT 2000000
struct oce_dev;
enum eq_len {
EQ_LEN_256 = 256,
EQ_LEN_512 = 512,
EQ_LEN_1024 = 1024,
EQ_LEN_2048 = 2048,
EQ_LEN_4096 = 4096
};
enum eqe_size {
EQE_SIZE_4 = 4,
EQE_SIZE_16 = 16
};
enum qtype {
QTYPE_EQ,
QTYPE_MQ,
QTYPE_WQ,
QTYPE_RQ,
QTYPE_CQ,
QTYPE_RSS
};
typedef enum qstate_e {
QDELETED = 0x0,
QCREATED = 0x1
}qstate_t;
struct eq_config {
enum eq_len q_len;
enum eqe_size item_size;
uint32_t q_vector_num;
uint8_t min_eqd;
uint8_t max_eqd;
uint8_t cur_eqd;
uint8_t pad;
};
struct oce_eq {
kmutex_t lock;
uint32_t eq_id;
void *parent;
void *cb_context;
oce_ring_buffer_t *ring;
uint32_t ref_count;
qstate_t qstate;
struct eq_config eq_cfg;
};
enum cq_len {
CQ_LEN_256 = 256,
CQ_LEN_512 = 512,
CQ_LEN_1024 = 1024
};
struct cq_config {
enum cq_len q_len;
uint32_t item_size;
boolean_t is_eventable;
boolean_t sol_eventable;
boolean_t nodelay;
uint16_t dma_coalescing;
};
typedef uint16_t (*cq_handler_t)(void *arg1);
struct oce_cq {
kmutex_t lock;
uint32_t cq_id;
void *parent;
struct oce_eq *eq;
cq_handler_t cq_handler;
void *cb_arg;
oce_ring_buffer_t *ring;
qstate_t qstate;
struct cq_config cq_cfg;
uint32_t ref_count;
};
struct mq_config {
uint32_t eqd;
uint8_t q_len;
uint8_t pad[3];
};
struct oce_mq {
kmutex_t lock;
void *parent;
oce_ring_buffer_t *ring;
uint32_t mq_id;
struct oce_cq *cq;
struct oce_cq *async_cq;
uint32_t mq_free;
qstate_t qstate;
struct mq_config cfg;
};
struct oce_mbx_ctx {
struct oce_mbx *mbx;
void (*cb)(void *ctx);
void *cb_ctx;
};
struct wq_config {
uint8_t wq_type;
uint16_t buf_size;
uint8_t pad[1];
uint32_t q_len;
uint16_t pd_id;
uint16_t pci_fn_num;
uint32_t eqd;
uint32_t nbufs;
uint32_t nhdl;
};
struct oce_wq {
kmutex_t tx_lock;
kmutex_t txc_lock;
void *parent;
oce_ring_buffer_t *ring;
struct oce_cq *cq;
kmem_cache_t *wqed_cache;
oce_wq_bdesc_t *wq_bdesc_array;
OCE_LIST_T wq_buf_list;
OCE_LIST_T wqe_desc_list;
OCE_LIST_T wq_mdesc_list;
oce_wq_mdesc_t *wq_mdesc_array;
uint32_t wqm_used;
boolean_t resched;
uint32_t wq_free;
uint32_t tx_deferd;
uint32_t pkt_drops;
qstate_t qstate;
uint16_t wq_id;
struct wq_config cfg;
};
struct rq_config {
uint32_t q_len;
uint32_t frag_size;
uint32_t mtu;
uint32_t if_id;
uint32_t is_rss_queue;
uint32_t eqd;
uint32_t nbufs;
};
struct rq_shadow_entry {
oce_rq_bdesc_t *rqbd;
};
struct oce_rq {
struct rq_config cfg;
uint32_t rq_id;
void *parent;
uint32_t rss_cpuid;
oce_ring_buffer_t *ring;
struct oce_cq *cq;
oce_rq_bdesc_t *rq_bdesc_array;
oce_rq_bdesc_t **shadow_ring;
oce_rq_bdesc_t **rqb_freelist;
uint32_t rqb_free;
uint32_t rqb_next_free;
uint32_t rqb_rc_head;
uint32_t buf_avail;
uint32_t pending;
qstate_t qstate;
kmutex_t rx_lock;
kmutex_t rc_lock;
};
struct link_status {
uint8_t physical_port;
uint8_t mac_duplex;
uint8_t mac_speed;
uint8_t mac_fault;
uint8_t mgmt_mac_duplex;
uint8_t mgmt_mac_speed;
uint16_t qos_link_speed;
uint32_t logical_link_status;
};
oce_dma_buf_t *oce_alloc_dma_buffer(struct oce_dev *dev,
uint32_t size, ddi_dma_attr_t *dma_attr, uint32_t flags);
void oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf);
oce_ring_buffer_t *create_ring_buffer(struct oce_dev *dev,
uint32_t num_items, uint32_t item_size,
uint32_t flags);
void destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring);
int oce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr,
uint32_t eq_cnt, uint32_t eq_delay);
void oce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped,
boolean_t rearm, boolean_t clearint);
void oce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped,
boolean_t rearm);
void oce_drain_eq(struct oce_eq *eq);
void oce_dev_rss_ready(struct oce_dev *dev);
int oce_mbox_init(struct oce_dev *dev);
int oce_mbox_fini(struct oce_dev *dev);
int oce_mbox_dispatch(struct oce_dev *dev, uint32_t tmo_sec);
int oce_mbox_wait(struct oce_dev *dev, uint32_t tmo_sec);
int oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
struct oce_mbx_ctx *mbxctx);
boolean_t oce_is_reset_pci(struct oce_dev *dev);
int oce_pci_soft_reset(struct oce_dev *dev);
int oce_POST(struct oce_dev *dev);
int oce_pci_init(struct oce_dev *dev);
void oce_pci_fini(struct oce_dev *dev);
int oce_init_txrx(struct oce_dev *dev);
void oce_fini_txrx(struct oce_dev *dev);
int oce_create_queues(struct oce_dev *dev);
void oce_delete_queues(struct oce_dev *dev);
void oce_delete_nw_interface(struct oce_dev *dev);
int oce_create_nw_interface(struct oce_dev *dev);
int oce_reset_fun(struct oce_dev *dev);
struct oce_wq *oce_get_wq(struct oce_dev *dev, mblk_t *pkt);
uint16_t oce_drain_wq_cq(void *arg);
mblk_t *oce_send_packet(struct oce_wq *wq, mblk_t *mp);
int oce_start_wq(struct oce_wq *wq);
void oce_clean_wq(struct oce_wq *wq);
uint16_t oce_drain_rq_cq(void *arg);
int oce_start_rq(struct oce_rq *rq);
void oce_clean_rq(struct oce_rq *rq);
void oce_rq_discharge(struct oce_rq *rq);
int oce_rx_pending(struct oce_dev *dev, struct oce_rq *rq, int32_t timeout);
uint16_t oce_drain_mq_cq(void *arg);
int oce_mq_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx,
struct oce_mbx_ctx *mbxctx);
struct oce_mbx *oce_mq_get_mbx(struct oce_dev *dev);
void oce_clean_mq(struct oce_mq *mq);
int oce_start_mq(struct oce_mq *mq);
void mbx_common_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom,
uint8_t port, uint8_t subsys, uint8_t opcode,
uint32_t timeout, uint32_t pyld_len);
void mbx_nic_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom, uint8_t port,
uint8_t opcode, uint32_t timeout, uint32_t pyld_len);
int oce_get_fw_version(struct oce_dev *dev);
int oce_read_mac_addr(struct oce_dev *dev, uint32_t if_id, uint8_t perm,
uint8_t type, struct mac_address_format *mac);
int oce_if_create(struct oce_dev *dev, uint32_t cap_flags, uint32_t en_flags,
uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id);
int oce_if_del(struct oce_dev *dev, uint32_t if_id);
int oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors);
int oce_get_link_status(struct oce_dev *dev, struct link_status *link);
int oce_set_rx_filter(struct oce_dev *dev,
struct mbx_set_common_ntwk_rx_filter *filter);
int oce_set_multicast_table(struct oce_dev *dev, uint32_t if_id,
struct ether_addr *mca_table, uint16_t mca_cnt, boolean_t promisc);
int oce_get_fw_config(struct oce_dev *dev);
int oce_get_hw_stats(struct oce_dev *dev);
int oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control);
int oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control);
int oce_set_promiscuous(struct oce_dev *dev, boolean_t enable);
int oce_add_mac(struct oce_dev *dev, uint32_t if_id,
const uint8_t *mac, uint32_t *pmac_id);
int oce_del_mac(struct oce_dev *dev, uint32_t if_id, uint32_t *pmac_id);
int oce_config_vlan(struct oce_dev *dev, uint32_t if_id,
struct normal_vlan *vtag_arr,
uint8_t vtag_cnt, boolean_t untagged,
boolean_t enable_promisc);
int oce_config_link(struct oce_dev *dev, boolean_t enable);
int oce_config_rss(struct oce_dev *dev, uint16_t if_id, char *hkey, char *itbl,
int tbl_sz, uint16_t rss_type, uint8_t flush);
int oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp,
uint32_t *payload_length);
#ifdef __cplusplus
}
#endif
#endif