Print this page
NEX-1890 update oce from source provided by Emulex

*** 17,28 **** * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* Copyright © 2003-2011 Emulex. All rights reserved. */ /* * Header file defining the HW IO elements */ #ifndef _OCE_IO_H_ --- 17,33 ---- * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ ! /* ! * Copyright (c) 2009-2012 Emulex. All rights reserved. ! * Use is subject to license terms. ! */ + + /* * Header file defining the HW IO elements */ #ifndef _OCE_IO_H_
*** 44,53 **** --- 49,59 ---- #define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000) /* 5 sec (in usec) */ #define MBX_READY_TIMEOUT (1 * 1000 * 1000) /* 1 sec (in usec) */ #define DEFAULT_DRAIN_TIME 200 /* Default Drain Time */ #define MBX_TIMEOUT_SEC 5 #define STAT_TIMEOUT 2000000 /* update stats every 2 sec */ + #define OCE_HDR_LEN 64 struct oce_dev; enum eq_len { EQ_LEN_256 = 256,
*** 71,145 **** QTYPE_RSS }; typedef enum qstate_e { QDELETED = 0x0, ! QCREATED = 0x1 }qstate_t; ! struct eq_config { ! /* number of entries in the eq */ ! enum eq_len q_len; ! /* size of each entry */ ! enum eqe_size item_size; ! /* vector associated with this eq */ ! uint32_t q_vector_num; ! /* minimum possible eq delay i usec */ ! uint8_t min_eqd; ! /* max eq delay in usec */ ! uint8_t max_eqd; ! /* currently configured eq delay in usec */ ! uint8_t cur_eqd; ! /* pad */ ! uint8_t pad; }; struct oce_eq { - /* Lock for this queue */ - kmutex_t lock; /* id assigned by the hw to this eq */ uint32_t eq_id; /* handle to the creating parent dev */ void *parent; - /* callback context */ - void *cb_context; /* ring buffer for this eq */ oce_ring_buffer_t *ring; /* reference count of this structure */ uint32_t ref_count; ! /* Queue state */ ! qstate_t qstate; ! /* configuration of this eq */ ! struct eq_config eq_cfg; }; enum cq_len { CQ_LEN_256 = 256, CQ_LEN_512 = 512, ! CQ_LEN_1024 = 1024 }; struct cq_config { /* length of queue */ enum cq_len q_len; - /* size of each item */ - uint32_t item_size; - /* is eventable */ - boolean_t is_eventable; - /* solicited eventable? */ - boolean_t sol_eventable; - /* no delay? */ - boolean_t nodelay; - /* dma coalescing */ - uint16_t dma_coalescing; }; ! typedef uint16_t (*cq_handler_t)(void *arg1); struct oce_cq { - /* lock */ - kmutex_t lock; /* id given by the hardware */ uint32_t cq_id; /* parent device to which this cq belongs */ void *parent; /* event queue associated with this cq */ --- 77,137 ---- QTYPE_RSS }; typedef enum qstate_e { QDELETED = 0x0, ! QCREATED, ! QSTARTED, ! QSTOPPED, ! QFINI, ! QFINI_PENDING }qstate_t; ! enum mb_mode_e { ! MBX_BOOTSTRAP = 0x00, /* issue a command on the bootstrap mbox */ ! MBX_ASYNC_MQ = 0x01 /* issue command thru MCC */ }; + /* Driver special codes */ + + #define MBX_SUCCESS 0x00 + #define MBX_FAILURE 0x01 + #define MBX_COMPLETED 0x02 + #define MBX_QUEUE_FULL 0xF8 + #define MBX_BUSY 0xFD + #define MBX_TIMEOUT 0xFE + struct oce_eq { /* id assigned by the hw to this eq */ uint32_t eq_id; /* handle to the creating parent dev */ void *parent; /* ring buffer for this eq */ oce_ring_buffer_t *ring; /* reference count of this structure */ uint32_t ref_count; ! /* vector index */ ! uint32_t idx; ! uint32_t qstate; ! kmutex_t lock; }; enum cq_len { CQ_LEN_256 = 256, CQ_LEN_512 = 512, ! CQ_LEN_1024 = 1024, ! CQ_LEN_2048 = 2048 }; struct cq_config { /* length of queue */ enum cq_len q_len; }; ! typedef void * (*cq_handler_t)(void *arg1, int arg2, int arg3); struct oce_cq { /* id given by the hardware */ uint32_t cq_id; /* parent device to which this cq belongs */ void *parent; /* event queue associated with this cq */
*** 189,204 **** --- 181,204 ---- * utility structure that handles context of mbx */ struct oce_mbx_ctx { /* pointer to mbx */ struct oce_mbx *mbx; + kmutex_t cv_lock; + kcondvar_t cond_var; /* call back functioin [optional] */ void (*cb)(void *ctx); /* call back context [optional] */ void *cb_ctx; + uint32_t mbx_status; + struct oce_mbx *mqe; /* pointer to mq entry */ + uint32_t compl_status; /* mgmt status | addl status */ }; + #define OCE_MODE_POLL B_FALSE + #define OCE_MODE_INTR B_TRUE + struct wq_config { /* qtype */ uint8_t wq_type; uint16_t buf_size; uint8_t pad[1];
*** 212,236 **** struct oce_wq { kmutex_t tx_lock; /* lock for the WQ */ kmutex_t txc_lock; /* tx compl lock */ void *parent; /* parent of this wq */ oce_ring_buffer_t *ring; /* ring buffer managing the wqes */ struct oce_cq *cq; /* cq associated with this wq */ kmem_cache_t *wqed_cache; /* packet desc cache */ oce_wq_bdesc_t *wq_bdesc_array; /* buffer desc array */ ! OCE_LIST_T wq_buf_list; /* buffer list */ ! OCE_LIST_T wqe_desc_list; /* packet descriptor list */ ! OCE_LIST_T wq_mdesc_list; /* free list of memory handles */ oce_wq_mdesc_t *wq_mdesc_array; /* preallocated memory handles */ uint32_t wqm_used; /* memory handles uses */ boolean_t resched; /* used for mac_tx_update */ uint32_t wq_free; /* Wqe free */ uint32_t tx_deferd; /* Wqe free */ uint32_t pkt_drops; /* drops */ /* Queue state */ qstate_t qstate; uint16_t wq_id; /* wq ID */ struct wq_config cfg; /* q config */ }; struct rq_config { --- 212,262 ---- struct oce_wq { kmutex_t tx_lock; /* lock for the WQ */ kmutex_t txc_lock; /* tx compl lock */ void *parent; /* parent of this wq */ + mac_ring_handle_t handle; /* ring handle used by crossbow framework */ + oce_ring_buffer_t *ring; /* ring buffer managing the wqes */ struct oce_cq *cq; /* cq associated with this wq */ kmem_cache_t *wqed_cache; /* packet desc cache */ oce_wq_bdesc_t *wq_bdesc_array; /* buffer desc array */ ! uint32_t wqb_free; /* Wqb free */ ! uint32_t wqbd_next_free; /* Next availble wqbd index */ ! uint32_t wqbd_rc_head; /* wqbd recycle head */ ! kmutex_t wqb_alloc_lock; /* wqbd lock in allocation path */ ! kmutex_t wqb_free_lock; /* wqbd lock in recycle path */ ! oce_wq_bdesc_t **wqb_freelist; /* Free wqbds */ ! list_t wqe_desc_list; /* packet descriptor list */ ! kmutex_t wqed_list_lock; /* wqed list lock */ ! uint32_t wqe_pending; /* Wqe pending */ oce_wq_mdesc_t *wq_mdesc_array; /* preallocated memory handles */ + uint32_t wqm_free; /* Wqm free */ + uint32_t wqmd_next_free; /* Next free wqmd slot */ + uint32_t wqmd_rc_head; /* wqmd recycle head */ + kmutex_t wqm_alloc_lock; /* Lock for wqm alloc path */ + kmutex_t wqm_free_lock; /* Lock for wqm free path */ + oce_wq_mdesc_t **wqm_freelist; /* Free wqmds */ uint32_t wqm_used; /* memory handles uses */ + oce_dma_buf_t wqb; /* Tx Copy buffer dma memory */ boolean_t resched; /* used for mac_tx_update */ uint32_t wq_free; /* Wqe free */ + uint32_t tx_deferd; /* Wqe free */ uint32_t pkt_drops; /* drops */ + + int64_t last_compl; + int64_t last_armed; + int64_t last_intr; + int64_t last_defered; + + uint64_t stat_bytes; + uint64_t stat_pkts; + /* Queue state */ qstate_t qstate; + uint_t qmode; /* poll or interrupt mode */ uint16_t wq_id; /* wq ID */ struct wq_config cfg; /* q config */ }; struct rq_config {
*** 246,281 **** struct rq_shadow_entry { oce_rq_bdesc_t *rqbd; }; struct oce_rq { /* RQ config */ struct rq_config cfg; ! /* RQ id */ ! uint32_t rq_id; ! /* parent of this rq */ ! void *parent; ! /* CPU ID assigend to this RQ if it is an RSS queue */ ! uint32_t rss_cpuid; /* ring buffer managing the RQEs */ oce_ring_buffer_t *ring; /* cq associated with this queue */ struct oce_cq *cq; oce_rq_bdesc_t *rq_bdesc_array; /* shadow list of mblk for rq ring */ oce_rq_bdesc_t **shadow_ring; oce_rq_bdesc_t **rqb_freelist; uint32_t rqb_free; uint32_t rqb_next_free; /* next free slot */ uint32_t rqb_rc_head; /* recycling head */ uint32_t buf_avail; /* buffer avaialable with hw */ uint32_t pending; /* Buffers sent up */ - /* Queue state */ - qstate_t qstate; /* rq lock */ - kmutex_t rx_lock; kmutex_t rc_lock; }; struct link_status { /* dw 0 */ uint8_t physical_port; --- 272,319 ---- struct rq_shadow_entry { oce_rq_bdesc_t *rqbd; }; struct oce_rq { + + kmutex_t rx_lock; + kmutex_t rq_fini_lock; + mac_ring_handle_t handle; /* ring handle used by framework */ + uint64_t gen_number; /* used by framework */ + boolean_t qmode; + uint64_t stat_bytes; + uint64_t stat_pkts; + /* RQ config */ struct rq_config cfg; ! /* ring buffer managing the RQEs */ oce_ring_buffer_t *ring; /* cq associated with this queue */ struct oce_cq *cq; oce_rq_bdesc_t *rq_bdesc_array; /* shadow list of mblk for rq ring */ oce_rq_bdesc_t **shadow_ring; oce_rq_bdesc_t **rqb_freelist; + oce_dma_buf_t rqb; /* data buffer for the rq's */ uint32_t rqb_free; uint32_t rqb_next_free; /* next free slot */ uint32_t rqb_rc_head; /* recycling head */ uint32_t buf_avail; /* buffer avaialable with hw */ uint32_t pending; /* Buffers sent up */ /* rq lock */ kmutex_t rc_lock; + + /* parent of this rq */ + void *parent; + /* RQ id */ + uint32_t rq_id; + /* CPU ID assigend to this RQ if it is an RSS queue */ + uint32_t rss_cpuid; + /* Queue state */ + uint32_t qstate; + void *grp; /* group it belongs to */ }; struct link_status { /* dw 0 */ uint8_t physical_port;
*** 288,396 **** uint16_t qos_link_speed; /* dw2 */ 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); /* Queues */ 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); /* Bootstrap */ 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); /* Hardware */ 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); /* Transmit */ ! 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); - /* Recieve */ ! 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); ! /* event handling */ ! 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); ! ! /* mbx functions */ 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 --- 326,438 ---- uint16_t qos_link_speed; /* dw2 */ uint32_t logical_link_status; }; ! int oce_alloc_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf, 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 *oce_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); /* Queues */ int oce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr, ! uint32_t eq_cnt, uint32_t eq_delay, uint32_t mode); 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); + /* Bootstrap */ 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_issue_mbox_passthru(struct oce_dev *dev, queue_t *wq, mblk_t *mp, ! uint32_t *rsp_len); ! int oce_issue_mbox_cmd(struct oce_dev *dev, struct oce_mbx *mbx, ! uint32_t tmo_sec, uint32_t flag); /* Hardware */ 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_tx(struct oce_dev *dev); ! void oce_fini_tx(struct oce_dev *dev); int oce_create_queues(struct oce_dev *dev); + int oce_create_mcc_queue(struct oce_dev *dev); void oce_delete_queues(struct oce_dev *dev); ! void oce_delete_mcc_queue(struct oce_dev *dev); int oce_reset_fun(struct oce_dev *dev); /* Transmit */ ! void *oce_drain_wq_cq(void *arg, int arg2, int arg3); 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); /* Recieve */ ! void * oce_drain_rq_cq(void *arg, int arg2, int arg3); 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); + void oce_rq_fini(struct oce_dev *dev, struct oce_rq *rq); ! /* Mailbox */ ! void * oce_drain_mq_cq(void *arg, int arg2, int arg3); ! int oce_issue_mq_mbox(struct oce_dev *dev, struct oce_mbx *mbx); 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); ! /* mbx helper functions */ 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, uint8_t version); 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, uint32_t mode); int oce_read_mac_addr(struct oce_dev *dev, uint32_t if_id, uint8_t perm, ! uint8_t type, struct mac_address_format *mac, uint32_t mode); 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, uint32_t mode); ! int oce_if_del(struct oce_dev *dev, uint32_t if_id, uint32_t mode); ! int oce_get_link_status(struct oce_dev *dev, link_state_t *link_status, ! int32_t *link_speed, uint8_t *link_duplex, uint8_t cmd_ver, uint32_t mode); int oce_set_rx_filter(struct oce_dev *dev, ! struct mbx_set_common_ntwk_rx_filter *filter, uint32_t mode); 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, ! uint32_t mode); ! int oce_get_fw_config(struct oce_dev *dev, uint32_t mode); ! int oce_get_hw_stats(struct oce_dev *dev, uint32_t mode); ! int oce_get_pport_stats(struct oce_dev *dev, uint32_t mode); ! int oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control, ! uint32_t mode); ! int oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control, ! uint32_t mode); ! int oce_set_promiscuous(struct oce_dev *dev, boolean_t enable, uint32_t mode); int oce_add_mac(struct oce_dev *dev, uint32_t if_id, ! const uint8_t *mac, uint32_t *pmac_id, uint32_t mode); ! int oce_del_mac(struct oce_dev *dev, uint32_t if_id, uint32_t *pmac_id, ! uint32_t mode); 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, uint32_t mode); ! int oce_config_link(struct oce_dev *dev, boolean_t enable, uint32_t mode); 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, uint32_t mode); int oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp, uint32_t *payload_length); #ifdef __cplusplus } #endif