1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Header file defining the HW IO elements 29 */ 30 31 #ifndef _OCE_IO_H_ 32 #define _OCE_IO_H_ 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 #include <sys/types.h> 39 #include <sys/dditypes.h> 40 #include <sys/mutex.h> 41 #include <sys/stream.h> 42 #include <sys/debug.h> 43 #include <sys/byteorder.h> 44 #include <oce_hw.h> 45 #include <oce_buf.h> 46 47 #define DEFAULT_MQ_MBOX_TIMEOUT (5 * 1000 * 1000) /* 5 sec (in usec) */ 48 #define MBX_TIMEOUT_SEC 5 49 #define STAT_TIMEOUT 2000000 /* update stats every 2 sec */ 50 51 struct oce_dev; 52 53 enum eq_len { 54 EQ_LEN_256 = 256, 55 EQ_LEN_512 = 512, 56 EQ_LEN_1024 = 1024, 57 EQ_LEN_2048 = 2048, 58 EQ_LEN_4096 = 4096 59 }; 60 61 enum eqe_size { 62 EQE_SIZE_4 = 4, 63 EQE_SIZE_16 = 16 64 }; 65 66 struct eq_config { 67 /* number of entries in the eq */ 68 enum eq_len q_len; 69 /* size of each entry */ 70 enum eqe_size item_size; 71 /* vector associated with this eq */ 72 uint32_t q_vector_num; 73 /* minimum possible eq delay i usec */ 74 uint8_t min_eqd; 75 /* max eq delay in usec */ 76 uint8_t max_eqd; 77 /* currently configured eq delay in usec */ 78 uint8_t cur_eqd; 79 /* pad */ 80 uint8_t pad; 81 }; 82 83 struct oce_eq { 84 /* configuration of this eq */ 85 struct eq_config eq_cfg; 86 /* id assigned by the hw to this eq */ 87 uint32_t eq_id; 88 /* handle to the creating parent dev */ 89 void *parent; 90 /* callback context */ 91 void *cb_context; 92 /* reference count of this structure */ 93 uint32_t ref_count; 94 /* ring buffer for this eq */ 95 oce_ring_buffer_t *ring; 96 /* Lock for this queue */ 97 kmutex_t lock; 98 }; 99 100 enum cq_len { 101 CQ_LEN_256 = 256, 102 CQ_LEN_512 = 512, 103 CQ_LEN_1024 = 1024 104 }; 105 106 struct cq_config { 107 /* length of queue */ 108 enum cq_len q_len; 109 /* size of each item */ 110 uint32_t item_size; 111 /* solicited eventable? */ 112 uint8_t sol_eventable; 113 /* no delay? */ 114 uint8_t nodelay; 115 /* dma coalescing */ 116 uint16_t dma_coalescing; 117 }; 118 119 typedef uint16_t (*cq_handler_t)(void *arg1); 120 121 struct oce_cq { 122 /* configuration of this cq */ 123 struct cq_config cq_cfg; 124 /* reference count of this structure */ 125 uint32_t ref_count; 126 /* id given by the hardware */ 127 uint32_t cq_id; 128 /* parent device to which this cq belongs */ 129 void *parent; 130 /* event queue associated with this cq */ 131 struct oce_eq *eq; 132 cq_handler_t cq_handler; 133 /* placeholder for callback context */ 134 void *cb_arg; 135 /* ring buffer for this cq */ 136 oce_ring_buffer_t *ring; 137 /* lock */ 138 kmutex_t lock; 139 }; 140 141 struct mq_config { 142 uint32_t eqd; 143 uint8_t q_len; 144 uint8_t pad[3]; 145 146 }; 147 148 struct oce_mq { 149 /* configuration of this mq */ 150 struct mq_config cfg; 151 /* handle to the parent device */ 152 void *parent; 153 /* send queue */ 154 oce_ring_buffer_t *ring; 155 /* idnetifier for the mq */ 156 uint32_t mq_id; 157 struct oce_cq *cq; 158 struct oce_cq *async_cq; 159 /* free entries in Queue */ 160 uint32_t mq_free; 161 }; 162 163 enum qtype { 164 QTYPE_EQ, 165 QTYPE_MQ, 166 QTYPE_WQ, 167 QTYPE_RQ, 168 QTYPE_CQ, 169 QTYPE_RSS 170 }; 171 172 /* 173 * utility structure that handles context of mbx 174 */ 175 struct oce_mbx_ctx { 176 /* pointer to mbx */ 177 struct oce_mbx *mbx; 178 /* call back functioin [optional] */ 179 void (*cb)(void *ctx); 180 /* call back context [optional] */ 181 void *cb_ctx; 182 }; 183 184 struct wq_config { 185 /* qtype */ 186 uint8_t wq_type; 187 uint8_t pad[3]; 188 uint32_t q_len; /* number of wqes */ 189 uint16_t pd_id; /* protection domain id */ 190 uint16_t pci_fn_num; /* pci function number */ 191 uint32_t eqd; /* interrupt delay */ 192 uint32_t nbufs; /* copy buffers */ 193 uint32_t nhdl; /* preallocated memory handles */ 194 }; 195 196 struct oce_wq { 197 struct wq_config cfg; /* q config */ 198 void *parent; /* parent of this wq */ 199 uint16_t wq_id; /* wq ID */ 200 oce_ring_buffer_t *ring; /* ring buffer managing the wqes */ 201 struct oce_cq *cq; /* cq associated with this wq */ 202 kmem_cache_t *wqed_cache; /* packet desc cache */ 203 OCE_LIST_T wqe_desc_list; /* packet descriptor list */ 204 oce_wq_bdesc_t *wq_bdesc_array; /* buffer desc array */ 205 OCE_LIST_T wq_buf_list; /* buffer list */ 206 OCE_LIST_T wq_mdesc_list; /* free list of memory handles */ 207 oce_wq_mdesc_t *wq_mdesc_array; /* preallocated memory handles */ 208 uint32_t wqm_used; /* memory handles uses */ 209 boolean_t resched; /* used for mac_tx_update */ 210 uint32_t wq_free; /* Wqe free */ 211 uint32_t tx_deferd; /* Wqe free */ 212 uint32_t pkt_drops; /* drops */ 213 kmutex_t lock; /* lock for the WQ */ 214 }; 215 216 struct rq_config { 217 uint32_t q_len; /* q length */ 218 uint32_t frag_size; /* fragment size. Send log2(size) in commmand */ 219 uint32_t mtu; /* max frame size for this RQ */ 220 uint32_t if_id; /* interface ID to associate this RQ with */ 221 uint32_t is_rss_queue; /* is this RQ an RSS queue? */ 222 uint32_t eqd; /* interrupt delay */ 223 uint32_t nbufs; /* Total data buffers */ 224 }; 225 226 struct rq_shadow_entry { 227 oce_rq_bdesc_t *rqbd; 228 }; 229 230 struct oce_rq { 231 /* RQ config */ 232 struct rq_config cfg; 233 /* RQ id */ 234 uint32_t rq_id; 235 /* parent of this rq */ 236 void *parent; 237 /* CPU ID assigend to this RQ if it is an RSS queue */ 238 uint32_t rss_cpuid; 239 /* ring buffer managing the RQEs */ 240 oce_ring_buffer_t *ring; 241 /* RQ Buffer cache */ 242 /* kmem_cache_t *rqb_cache; */ 243 /* shadow list of mblk for rq ring */ 244 struct rq_shadow_entry *shadow_ring; 245 /* cq associated with this queue */ 246 struct oce_cq *cq; 247 oce_rq_bdesc_t *rq_bdesc_array; 248 OCE_LIST_T rq_buf_list; /* Free list */ 249 uint32_t buf_avail; /* buffer avaialable with hw */ 250 uint32_t pending; /* Buffers sent up */ 251 /* rq lock */ 252 kmutex_t lock; 253 }; 254 255 struct link_status { 256 /* dw 0 */ 257 uint8_t physical_port; 258 uint8_t mac_duplex; 259 uint8_t mac_speed; 260 uint8_t mac_fault; 261 /* dw 1 */ 262 uint8_t mgmt_mac_duplex; 263 uint8_t mgmt_mac_speed; 264 uint16_t rsvd0; 265 }; 266 267 oce_dma_buf_t *oce_alloc_dma_buffer(struct oce_dev *dev, 268 uint32_t size, uint32_t flags); 269 void oce_free_dma_buffer(struct oce_dev *dev, oce_dma_buf_t *dbuf); 270 271 oce_ring_buffer_t *create_ring_buffer(struct oce_dev *dev, 272 uint32_t num_items, uint32_t item_size, 273 uint32_t flags); 274 void destroy_ring_buffer(struct oce_dev *dev, oce_ring_buffer_t *ring); 275 276 /* Queues */ 277 struct oce_eq *oce_eq_create(struct oce_dev *dev, uint32_t q_len, 278 uint32_t item_size, uint32_t eq_delay); 279 280 int oce_eq_del(struct oce_dev *dev, struct oce_eq *eq); 281 int oce_set_eq_delay(struct oce_dev *dev, uint32_t *eq_arr, 282 uint32_t eq_cnt, uint32_t eq_delay); 283 void oce_arm_eq(struct oce_dev *dev, int16_t qid, int npopped, 284 boolean_t rearm, boolean_t clearint); 285 void oce_arm_cq(struct oce_dev *dev, int16_t qid, int npopped, 286 boolean_t rearm); 287 void oce_drain_eq(struct oce_eq *eq); 288 289 290 /* Bootstrap */ 291 int oce_mbox_init(struct oce_dev *dev); 292 int oce_mbox_fini(struct oce_dev *dev); 293 int oce_mbox_dispatch(struct oce_dev *dev, uint32_t tmo_sec); 294 int oce_mbox_wait(struct oce_dev *dev, uint32_t tmo_sec); 295 int oce_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx, 296 struct oce_mbx_ctx *mbxctx); 297 298 /* Hardware */ 299 boolean_t oce_is_reset_pci(struct oce_dev *dev); 300 int oce_pci_soft_reset(struct oce_dev *dev); 301 int oce_POST(struct oce_dev *dev); 302 int oce_pci_init(struct oce_dev *dev); 303 void oce_pci_fini(struct oce_dev *dev); 304 305 /* Transmit */ 306 struct oce_wq *oce_wq_create(struct oce_dev *dev, struct oce_eq *eq, 307 uint32_t q_len, int wq_type); 308 309 int oce_wq_del(struct oce_dev *dev, struct oce_wq *wq); 310 struct oce_wq *oce_get_wq(struct oce_dev *dev, mblk_t *pkt); 311 uint16_t oce_drain_wq_cq(void *arg); 312 mblk_t *oce_send_packet(struct oce_wq *wq, mblk_t *mp); 313 int oce_start_wq(struct oce_wq *wq); 314 void oce_stop_wq(struct oce_wq *wq); 315 316 /* Recieve */ 317 uint16_t oce_drain_rq_cq(void *arg); 318 struct oce_rq *oce_rq_create(struct oce_dev *dev, struct oce_eq *eq, 319 uint32_t q_len, uint32_t frag_size, uint32_t mtu, 320 int16_t if_id, boolean_t rss); 321 int oce_rq_del(struct oce_dev *dev, struct oce_rq *rq); 322 int oce_start_rq(struct oce_rq *rq); 323 void oce_stop_rq(struct oce_rq *rq); 324 325 /* event handling */ 326 struct oce_mq *oce_mq_create(struct oce_dev *dev, 327 struct oce_eq *eq, uint32_t q_len); 328 int oce_mq_del(struct oce_dev *dev, struct oce_mq *mq); 329 uint16_t oce_drain_mq_cq(void *arg); 330 331 int oce_mq_mbox_post(struct oce_dev *dev, struct oce_mbx *mbx, 332 struct oce_mbx_ctx *mbxctx); 333 struct oce_mbx *oce_mq_get_mbx(struct oce_dev *dev); 334 void oce_stop_mq(struct oce_mq *mq); 335 void oce_rq_discharge(struct oce_rq *rq); 336 337 /* mbx functions */ 338 void mbx_common_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom, 339 uint8_t port, uint8_t subsys, uint8_t opcode, 340 uint32_t timeout, uint32_t pyld_len); 341 void mbx_nic_req_hdr_init(struct mbx_hdr *hdr, uint8_t dom, uint8_t port, 342 uint8_t opcode, uint32_t timeout, uint32_t pyld_len); 343 int oce_get_fw_version(struct oce_dev *dev); 344 int oce_read_mac_addr(struct oce_dev *dev, uint16_t if_id, uint8_t perm, 345 uint8_t type, struct mac_address_format *mac); 346 int oce_if_create(struct oce_dev *dev, uint32_t cap_flags, uint32_t en_flags, 347 uint16_t vlan_tag, uint8_t *mac_addr, uint32_t *if_id); 348 int oce_if_del(struct oce_dev *dev, uint32_t if_id); 349 int oce_num_intr_vectors_set(struct oce_dev *dev, uint32_t num_vectors); 350 351 int oce_get_link_status(struct oce_dev *dev, struct link_status *link); 352 int oce_set_rx_filter(struct oce_dev *dev, 353 struct mbx_set_common_ntwk_rx_filter *filter); 354 int oce_set_multicast_table(struct oce_dev *dev, struct ether_addr *mca_table, 355 uint8_t mca_cnt, boolean_t enable_promisc); 356 int oce_get_fw_config(struct oce_dev *dev); 357 int oce_get_hw_stats(struct oce_dev *dev); 358 int oce_set_flow_control(struct oce_dev *dev, uint32_t flow_control); 359 int oce_get_flow_control(struct oce_dev *dev, uint32_t *flow_control); 360 int oce_set_promiscuous(struct oce_dev *dev, boolean_t enable); 361 int oce_add_mac(struct oce_dev *dev, const uint8_t *mac, uint32_t *pmac_id); 362 int oce_del_mac(struct oce_dev *dev, uint32_t *pmac_id); 363 int oce_config_vlan(struct oce_dev *dev, uint8_t if_id, 364 struct normal_vlan *vtag_arr, 365 uint8_t vtag_cnt, boolean_t untagged, 366 boolean_t enable_promisc); 367 int oce_config_link(struct oce_dev *dev, boolean_t enable); 368 369 int oce_hw_init(struct oce_dev *dev); 370 void oce_hw_fini(struct oce_dev *dev); 371 int oce_chip_hw_init(struct oce_dev *dev); 372 void oce_chip_hw_fini(struct oce_dev *dev); 373 374 int oce_issue_mbox(struct oce_dev *dev, queue_t *wq, mblk_t *mp, 375 uint32_t *payload_length); 376 377 #ifdef __cplusplus 378 } 379 #endif 380 381 #endif /* _OCE_IO_H_ */ 382