2 * Copyright (C) 2005 - 2008 ServerEngines
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
10 * Contact Information:
11 * linux-drivers@serverengines.com
14 * 209 N. Fair Oaks Ave
17 #include <linux/if_ether.h>
22 *---------------------------------------------------------
23 * Function: be_eth_sq_create_ex
24 * Creates an ethernet send ring - extended version with
25 * additional parameters.
29 * type - The type of ring to create.
30 * ulp - The requested ULP number for the ring.
31 * This should be zero based, i.e. 0,1,2. This must
32 * be valid NIC ULP based on the firmware config.
33 * All doorbells for this ring must be sent to
34 * this ULP. The first network ring allocated for
35 * each ULP are higher performance than subsequent rings.
36 * cq_object - cq object for completions
37 * ex_parameters - Additional parameters (that may increase in
38 * future revisions). These parameters are only used
39 * for certain ring types -- see
40 * struct be_eth_sq_parameters for details.
42 * return status - BE_SUCCESS (0) on success. Negative error code on failure.
43 *---------------------------------------------------------
46 be_eth_sq_create_ex(struct be_function_object *pfob, struct ring_desc *rd,
47 u32 length, u32 type, u32 ulp, struct be_cq_object *cq_object,
48 struct be_eth_sq_parameters *ex_parameters,
49 struct be_ethsq_object *eth_sq)
51 struct FWCMD_COMMON_ETH_TX_CREATE *fwcmd = NULL;
52 struct MCC_WRB_AMAP *wrb = NULL;
59 ASSERT(ex_parameters);
61 spin_lock_irqsave(&pfob->post_lock, irql);
63 memset(eth_sq, 0, sizeof(*eth_sq));
65 eth_sq->parent_function = pfob;
66 eth_sq->bid = 0xFFFFFFFF;
67 eth_sq->cq_object = cq_object;
69 /* Translate hwlib interface to arm interface. */
71 case BE_ETH_TX_RING_TYPE_FORWARDING:
72 type = ETH_TX_RING_TYPE_FORWARDING;
74 case BE_ETH_TX_RING_TYPE_STANDARD:
75 type = ETH_TX_RING_TYPE_STANDARD;
77 case BE_ETH_TX_RING_TYPE_BOUND:
78 ASSERT(ex_parameters->port < 2);
79 type = ETH_TX_RING_TYPE_BOUND;
82 TRACE(DL_ERR, "Invalid eth tx ring type:%d", type);
87 wrb = be_function_peek_mcc_wrb(pfob);
90 TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
91 status = BE_STATUS_NO_MCC_WRB;
94 /* NIC must be supported by the current config. */
95 ASSERT(pfob->fw_config.nic_ulp_mask);
98 * The ulp parameter must select a valid NIC ULP
99 * for the current config.
101 ASSERT((1 << ulp) & pfob->fw_config.nic_ulp_mask);
103 /* Prepares an embedded fwcmd, including request/response sizes. */
104 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_TX_CREATE);
105 fwcmd->header.request.port_number = ex_parameters->port;
107 AMAP_SET_BITS_PTR(ETX_CONTEXT, pd_id,
108 &fwcmd->params.request.context, 0);
110 n = be_ring_length_to_encoding(length, sizeof(struct ETH_WRB_AMAP));
111 AMAP_SET_BITS_PTR(ETX_CONTEXT, tx_ring_size,
112 &fwcmd->params.request.context, n);
114 AMAP_SET_BITS_PTR(ETX_CONTEXT, cq_id_send,
115 &fwcmd->params.request.context, cq_object->cq_id);
117 n = pfob->pci_function_number;
118 AMAP_SET_BITS_PTR(ETX_CONTEXT, func, &fwcmd->params.request.context, n);
120 fwcmd->params.request.type = type;
121 fwcmd->params.request.ulp_num = (1 << ulp);
122 fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
123 ASSERT(PAGES_SPANNED(rd->va, rd->length) >=
124 fwcmd->params.request.num_pages);
126 /* Create a page list for the FWCMD. */
127 be_rd_to_pa_list(rd, fwcmd->params.request.pages,
128 ARRAY_SIZE(fwcmd->params.request.pages));
130 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
131 NULL, NULL, fwcmd, NULL);
132 if (status != BE_SUCCESS) {
133 TRACE(DL_ERR, "MCC to create etx queue failed.");
136 /* save the butler ID */
137 eth_sq->bid = fwcmd->params.response.cid;
139 /* add a reference to the corresponding CQ */
140 atomic_inc(&cq_object->ref_count);
143 spin_unlock_irqrestore(&pfob->post_lock, irql);
145 if (pfob->pend_queue_driving && pfob->mcc) {
146 pfob->pend_queue_driving = 0;
147 be_drive_mcc_wrb_queue(pfob->mcc);
154 This routine destroys an ethernet send queue
156 EthSq - EthSq Handle returned from EthSqCreate
158 This function always return BE_SUCCESS.
160 This function frees memory allocated by EthSqCreate for the EthSq Object.
163 int be_eth_sq_destroy(struct be_ethsq_object *eth_sq)
167 /* Send fwcmd to destroy the queue. */
168 status = be_function_ring_destroy(eth_sq->parent_function, eth_sq->bid,
169 FWCMD_RING_TYPE_ETH_TX, NULL, NULL, NULL, NULL);
172 /* Derefence any associated CQs. */
173 atomic_dec(ð_sq->cq_object->ref_count);
177 This routine attempts to set the transmit flow control parameters.
179 FunctionObject - Handle to a function object
181 txfc_enable - transmit flow control enable - true for
182 enable, false for disable
184 rxfc_enable - receive flow control enable - true for
185 enable, false for disable
187 Returns BE_SUCCESS if successfull, otherwise a useful int error
190 IRQL: < DISPATCH_LEVEL
192 This function always fails in non-privileged machine context.
195 be_eth_set_flow_control(struct be_function_object *pfob,
196 bool txfc_enable, bool rxfc_enable)
198 struct FWCMD_COMMON_SET_FLOW_CONTROL *fwcmd = NULL;
199 struct MCC_WRB_AMAP *wrb = NULL;
203 spin_lock_irqsave(&pfob->post_lock, irql);
205 wrb = be_function_peek_mcc_wrb(pfob);
207 TRACE(DL_ERR, "MCC wrb peek failed.");
208 status = BE_STATUS_NO_MCC_WRB;
211 /* Prepares an embedded fwcmd, including request/response sizes. */
212 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FLOW_CONTROL);
214 fwcmd->params.request.rx_flow_control = rxfc_enable;
215 fwcmd->params.request.tx_flow_control = txfc_enable;
217 /* Post the f/w command */
218 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
219 NULL, NULL, fwcmd, NULL);
222 TRACE(DL_ERR, "set flow control fwcmd failed.");
227 spin_unlock_irqrestore(&pfob->post_lock, irql);
229 if (pfob->pend_queue_driving && pfob->mcc) {
230 pfob->pend_queue_driving = 0;
231 be_drive_mcc_wrb_queue(pfob->mcc);
237 This routine attempts to get the transmit flow control parameters.
239 pfob - Handle to a function object
241 txfc_enable - transmit flow control enable - true for
242 enable, false for disable
244 rxfc_enable - receive flow control enable - true for enable,
247 Returns BE_SUCCESS if successfull, otherwise a useful int error code
250 IRQL: < DISPATCH_LEVEL
252 This function always fails in non-privileged machine context.
255 be_eth_get_flow_control(struct be_function_object *pfob,
256 bool *txfc_enable, bool *rxfc_enable)
258 struct FWCMD_COMMON_GET_FLOW_CONTROL *fwcmd = NULL;
259 struct MCC_WRB_AMAP *wrb = NULL;
263 spin_lock_irqsave(&pfob->post_lock, irql);
265 wrb = be_function_peek_mcc_wrb(pfob);
267 TRACE(DL_ERR, "MCC wrb peek failed.");
268 status = BE_STATUS_NO_MCC_WRB;
271 /* Prepares an embedded fwcmd, including request/response sizes. */
272 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FLOW_CONTROL);
274 /* Post the f/w command */
275 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
276 NULL, NULL, fwcmd, NULL);
279 TRACE(DL_ERR, "get flow control fwcmd failed.");
283 *txfc_enable = fwcmd->params.response.tx_flow_control;
284 *rxfc_enable = fwcmd->params.response.rx_flow_control;
287 spin_unlock_irqrestore(&pfob->post_lock, irql);
289 if (pfob->pend_queue_driving && pfob->mcc) {
290 pfob->pend_queue_driving = 0;
291 be_drive_mcc_wrb_queue(pfob->mcc);
297 *---------------------------------------------------------
298 * Function: be_eth_set_qos
299 * This function sets the ethernet transmit Quality of Service (QoS)
300 * characteristics of BladeEngine for the domain. All ethernet
301 * transmit rings of the domain will evenly share the bandwidth.
302 * The exeception to sharing is the host primary (super) ethernet
303 * transmit ring as well as the host ethernet forwarding ring
304 * for missed offload data.
306 * max_bps - the maximum bits per second in units of
307 * 10 Mbps (valid 0-100)
308 * max_pps - the maximum packets per second in units
309 * of 1 Kpps (0 indicates no limit)
310 * return status - BE_SUCCESS (0) on success. Negative error code on failure.
311 *---------------------------------------------------------
314 be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps)
316 struct FWCMD_COMMON_SET_QOS *fwcmd = NULL;
317 struct MCC_WRB_AMAP *wrb = NULL;
321 spin_lock_irqsave(&pfob->post_lock, irql);
323 wrb = be_function_peek_mcc_wrb(pfob);
325 TRACE(DL_ERR, "MCC wrb peek failed.");
326 status = BE_STATUS_NO_MCC_WRB;
329 /* Prepares an embedded fwcmd, including request/response sizes. */
330 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_QOS);
332 /* Set fields in fwcmd */
333 fwcmd->params.request.max_bits_per_second_NIC = max_bps;
334 fwcmd->params.request.max_packets_per_second_NIC = max_pps;
335 fwcmd->params.request.valid_flags = QOS_BITS_NIC | QOS_PKTS_NIC;
337 /* Post the f/w command */
338 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
339 NULL, NULL, fwcmd, NULL);
342 TRACE(DL_ERR, "network set qos fwcmd failed.");
345 spin_unlock_irqrestore(&pfob->post_lock, irql);
346 if (pfob->pend_queue_driving && pfob->mcc) {
347 pfob->pend_queue_driving = 0;
348 be_drive_mcc_wrb_queue(pfob->mcc);
354 *---------------------------------------------------------
355 * Function: be_eth_get_qos
356 * This function retrieves the ethernet transmit Quality of Service (QoS)
357 * characteristics for the domain.
358 * max_bps - the maximum bits per second in units of
359 * 10 Mbps (valid 0-100)
360 * max_pps - the maximum packets per second in units of
361 * 1 Kpps (0 indicates no limit)
362 * return status - BE_SUCCESS (0) on success. Negative error code on failure.
363 *---------------------------------------------------------
366 be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps)
368 struct FWCMD_COMMON_GET_QOS *fwcmd = NULL;
369 struct MCC_WRB_AMAP *wrb = NULL;
373 spin_lock_irqsave(&pfob->post_lock, irql);
375 wrb = be_function_peek_mcc_wrb(pfob);
377 TRACE(DL_ERR, "MCC wrb peek failed.");
378 status = BE_STATUS_NO_MCC_WRB;
381 /* Prepares an embedded fwcmd, including request/response sizes. */
382 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_QOS);
384 /* Post the f/w command */
385 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
386 NULL, NULL, fwcmd, NULL);
389 TRACE(DL_ERR, "network get qos fwcmd failed.");
393 *max_bps = fwcmd->params.response.max_bits_per_second_NIC;
394 *max_pps = fwcmd->params.response.max_packets_per_second_NIC;
397 spin_unlock_irqrestore(&pfob->post_lock, irql);
398 if (pfob->pend_queue_driving && pfob->mcc) {
399 pfob->pend_queue_driving = 0;
400 be_drive_mcc_wrb_queue(pfob->mcc);
406 *---------------------------------------------------------
407 * Function: be_eth_set_frame_size
408 * This function sets the ethernet maximum frame size. The previous
409 * values are returned.
411 * tx_frame_size - maximum transmit frame size in bytes
412 * rx_frame_size - maximum receive frame size in bytes
413 * return status - BE_SUCCESS (0) on success. Negative error code on failure.
414 *---------------------------------------------------------
417 be_eth_set_frame_size(struct be_function_object *pfob,
418 u32 *tx_frame_size, u32 *rx_frame_size)
420 struct FWCMD_COMMON_SET_FRAME_SIZE *fwcmd = NULL;
421 struct MCC_WRB_AMAP *wrb = NULL;
425 spin_lock_irqsave(&pfob->post_lock, irql);
427 wrb = be_function_peek_mcc_wrb(pfob);
429 TRACE(DL_ERR, "MCC wrb peek failed.");
430 status = BE_STATUS_NO_MCC_WRB;
433 /* Prepares an embedded fwcmd, including request/response sizes. */
434 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FRAME_SIZE);
435 fwcmd->params.request.max_tx_frame_size = *tx_frame_size;
436 fwcmd->params.request.max_rx_frame_size = *rx_frame_size;
438 /* Post the f/w command */
439 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
440 NULL, NULL, fwcmd, NULL);
443 TRACE(DL_ERR, "network set frame size fwcmd failed.");
447 *tx_frame_size = fwcmd->params.response.chip_max_tx_frame_size;
448 *rx_frame_size = fwcmd->params.response.chip_max_rx_frame_size;
451 spin_unlock_irqrestore(&pfob->post_lock, irql);
452 if (pfob->pend_queue_driving && pfob->mcc) {
453 pfob->pend_queue_driving = 0;
454 be_drive_mcc_wrb_queue(pfob->mcc);
461 This routine creates a Ethernet receive ring.
463 pfob - handle to a function object
464 rq_base_va - base VA for the default receive ring. this must be
465 exactly 8K in length and continguous physical memory.
466 cq_object - handle to a previously created CQ to be associated
468 pp_eth_rq - pointer to an opqaue handle where an eth
469 receive object is returned.
470 Returns BE_SUCCESS if successfull, , otherwise a useful
471 int error code is returned.
473 IRQL: < DISPATCH_LEVEL
474 this function allocates a struct be_ethrq_object *object.
475 there must be no more than 1 of these per function object, unless the
476 function object supports RSS (is networking and on the host).
477 the rq_base_va must point to a buffer of exactly 8K.
478 the erx::host_cqid (or host_stor_cqid) register and erx::ring_page registers
479 will be updated as appropriate on return
482 be_eth_rq_create(struct be_function_object *pfob,
483 struct ring_desc *rd, struct be_cq_object *cq_object,
484 struct be_cq_object *bcmc_cq_object,
485 struct be_ethrq_object *eth_rq)
488 struct MCC_WRB_AMAP *wrb = NULL;
489 struct FWCMD_COMMON_ETH_RX_CREATE *fwcmd = NULL;
492 /* MPU will set the */
496 spin_lock_irqsave(&pfob->post_lock, irql);
498 eth_rq->parent_function = pfob;
499 eth_rq->cq_object = cq_object;
501 wrb = be_function_peek_mcc_wrb(pfob);
503 TRACE(DL_ERR, "MCC wrb peek failed.");
504 status = BE_STATUS_NO_MCC_WRB;
507 /* Prepares an embedded fwcmd, including request/response sizes. */
508 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_RX_CREATE);
510 fwcmd->params.request.num_pages = 2; /* required length */
511 fwcmd->params.request.cq_id = cq_object->cq_id;
514 fwcmd->params.request.bcmc_cq_id = bcmc_cq_object->cq_id;
516 fwcmd->params.request.bcmc_cq_id = 0xFFFF;
518 /* Create a page list for the FWCMD. */
519 be_rd_to_pa_list(rd, fwcmd->params.request.pages,
520 ARRAY_SIZE(fwcmd->params.request.pages));
522 /* Post the f/w command */
523 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
524 NULL, NULL, fwcmd, NULL);
525 if (status != BE_SUCCESS) {
526 TRACE(DL_ERR, "fwcmd to map eth rxq frags failed.");
529 /* Save the ring ID for cleanup. */
530 eth_rq->rid = fwcmd->params.response.id;
532 atomic_inc(&cq_object->ref_count);
535 spin_unlock_irqrestore(&pfob->post_lock, irql);
537 if (pfob->pend_queue_driving && pfob->mcc) {
538 pfob->pend_queue_driving = 0;
539 be_drive_mcc_wrb_queue(pfob->mcc);
545 This routine destroys an Ethernet receive queue
547 eth_rq - ethernet receive queue handle returned from eth_rq_create
549 Returns BE_SUCCESS on success and an appropriate int on failure.
551 This function frees resourcs allocated by EthRqCreate.
552 The erx::host_cqid (or host_stor_cqid) register and erx::ring_page
553 registers will be updated as appropriate on return
554 IRQL: < DISPATCH_LEVEL
557 static void be_eth_rq_destroy_internal_cb(void *context, int status,
558 struct MCC_WRB_AMAP *wrb)
560 struct be_ethrq_object *eth_rq = (struct be_ethrq_object *) context;
562 if (status != BE_SUCCESS) {
563 TRACE(DL_ERR, "Destroy eth rq failed in internal callback.\n");
565 /* Dereference any CQs associated with this queue. */
566 atomic_dec(ð_rq->cq_object->ref_count);
572 int be_eth_rq_destroy(struct be_ethrq_object *eth_rq)
574 int status = BE_SUCCESS;
576 /* Send fwcmd to destroy the RQ. */
577 status = be_function_ring_destroy(eth_rq->parent_function,
578 eth_rq->rid, FWCMD_RING_TYPE_ETH_RX, NULL, NULL,
579 be_eth_rq_destroy_internal_cb, eth_rq);
585 *---------------------------------------------------------------------------
586 * Function: be_eth_rq_destroy_options
587 * Destroys an ethernet receive ring with finer granularity options
588 * than the standard be_eth_rq_destroy() API function.
590 * flush - Set to 1 to flush the ring, set to 0 to bypass the flush
591 * cb - Callback function on completion
592 * cb_context - Callback context
593 * return status - BE_SUCCESS (0) on success. Negative error code on failure.
594 *----------------------------------------------------------------------------
597 be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush,
598 mcc_wrb_cqe_callback cb, void *cb_context)
600 struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL;
601 struct MCC_WRB_AMAP *wrb = NULL;
602 int status = BE_SUCCESS;
603 struct be_function_object *pfob = NULL;
606 pfob = eth_rq->parent_function;
608 spin_lock_irqsave(&pfob->post_lock, irql);
610 TRACE(DL_INFO, "Destroy eth_rq ring id:%d, flush:%d", eth_rq->rid,
613 wrb = be_function_peek_mcc_wrb(pfob);
616 TRACE(DL_ERR, "No free MCC WRBs in destroy eth_rq ring.");
617 status = BE_STATUS_NO_MCC_WRB;
620 /* Prepares an embedded fwcmd, including request/response sizes. */
621 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY);
623 fwcmd->params.request.id = eth_rq->rid;
624 fwcmd->params.request.ring_type = FWCMD_RING_TYPE_ETH_RX;
625 fwcmd->params.request.bypass_flush = ((0 == flush) ? 1 : 0);
627 /* Post the f/w command */
628 status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context,
629 be_eth_rq_destroy_internal_cb, eth_rq, fwcmd, NULL);
631 if (status != BE_SUCCESS && status != BE_PENDING) {
632 TRACE(DL_ERR, "eth_rq ring destroy failed. id:%d, flush:%d",
638 spin_unlock_irqrestore(&pfob->post_lock, irql);
640 if (pfob->pend_queue_driving && pfob->mcc) {
641 pfob->pend_queue_driving = 0;
642 be_drive_mcc_wrb_queue(pfob->mcc);
648 This routine queries the frag size for erx.
650 pfob - handle to a function object
652 frag_size_bytes - erx frag size in bytes that is/was set.
654 Returns BE_SUCCESS if successfull, otherwise a useful int error
657 IRQL: < DISPATCH_LEVEL
661 be_eth_rq_get_frag_size(struct be_function_object *pfob, u32 *frag_size_bytes)
663 struct FWCMD_ETH_GET_RX_FRAG_SIZE *fwcmd = NULL;
664 struct MCC_WRB_AMAP *wrb = NULL;
668 ASSERT(frag_size_bytes);
670 spin_lock_irqsave(&pfob->post_lock, irql);
672 wrb = be_function_peek_mcc_wrb(pfob);
674 TRACE(DL_ERR, "MCC wrb peek failed.");
675 return BE_STATUS_NO_MCC_WRB;
677 /* Prepares an embedded fwcmd, including request/response sizes. */
678 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_GET_RX_FRAG_SIZE);
680 /* Post the f/w command */
681 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
682 NULL, NULL, fwcmd, NULL);
685 TRACE(DL_ERR, "get frag size fwcmd failed.");
689 *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
692 spin_unlock_irqrestore(&pfob->post_lock, irql);
694 if (pfob->pend_queue_driving && pfob->mcc) {
695 pfob->pend_queue_driving = 0;
696 be_drive_mcc_wrb_queue(pfob->mcc);
702 This routine attempts to set the frag size for erx. If the frag size is
703 already set, the attempt fails and the current frag size is returned.
705 pfob - Handle to a function object
707 frag_size - Erx frag size in bytes that is/was set.
709 current_frag_size_bytes - Pointer to location where currrent frag
712 Returns BE_SUCCESS if successfull, otherwise a useful int error
715 IRQL: < DISPATCH_LEVEL
717 This function always fails in non-privileged machine context.
720 be_eth_rq_set_frag_size(struct be_function_object *pfob,
721 u32 frag_size, u32 *frag_size_bytes)
723 struct FWCMD_ETH_SET_RX_FRAG_SIZE *fwcmd = NULL;
724 struct MCC_WRB_AMAP *wrb = NULL;
728 ASSERT(frag_size_bytes);
730 spin_lock_irqsave(&pfob->post_lock, irql);
732 wrb = be_function_peek_mcc_wrb(pfob);
734 TRACE(DL_ERR, "MCC wrb peek failed.");
735 status = BE_STATUS_NO_MCC_WRB;
738 /* Prepares an embedded fwcmd, including request/response sizes. */
739 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_SET_RX_FRAG_SIZE);
741 ASSERT(frag_size >= 128 && frag_size <= 16 * 1024);
743 /* This is the log2 of the fragsize. This is not the exact
745 fwcmd->params.request.new_fragsize_log2 = __ilog2_u32(frag_size);
747 /* Post the f/w command */
748 status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
749 NULL, NULL, fwcmd, NULL);
752 TRACE(DL_ERR, "set frag size fwcmd failed.");
756 *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
758 spin_unlock_irqrestore(&pfob->post_lock, irql);
760 if (pfob->pend_queue_driving && pfob->mcc) {
761 pfob->pend_queue_driving = 0;
762 be_drive_mcc_wrb_queue(pfob->mcc);
769 This routine gets or sets a mac address for a domain
770 given the port and mac.
772 FunctionObject - Function object handle.
773 port1 - Set to TRUE if this function will set/get the Port 1
774 address. Only the host may set this to TRUE.
775 mac1 - Set to TRUE if this function will set/get the
776 MAC 1 address. Only the host may set this to TRUE.
777 write - Set to TRUE if this function should write the mac address.
778 mac_address - Buffer of the mac address to read or write.
780 Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
782 IRQL: < DISPATCH_LEVEL
784 int be_rxf_mac_address_read_write(struct be_function_object *pfob,
785 bool port1, /* VM must always set to false */
786 bool mac1, /* VM must always set to false */
787 bool mgmt, bool write,
788 bool permanent, u8 *mac_address,
789 mcc_wrb_cqe_callback cb, /* optional */
790 void *cb_context) /* optional */
792 int status = BE_SUCCESS;
794 struct FWCMD_COMMON_NTWK_MAC_QUERY *query;
795 struct FWCMD_COMMON_NTWK_MAC_SET *set;
797 struct MCC_WRB_AMAP *wrb = NULL;
800 struct be_mcc_wrb_response_copy rc;
802 spin_lock_irqsave(&pfob->post_lock, irql);
806 ASSERT(port1 == false);
807 ASSERT(mac1 == false);
809 wrb = be_function_peek_mcc_wrb(pfob);
811 TRACE(DL_ERR, "MCC wrb peek failed.");
812 status = BE_STATUS_NO_MCC_WRB;
817 type = MAC_ADDRESS_TYPE_MANAGEMENT;
819 if (pfob->type == BE_FUNCTION_TYPE_NETWORK)
820 type = MAC_ADDRESS_TYPE_NETWORK;
822 type = MAC_ADDRESS_TYPE_STORAGE;
826 /* Prepares an embedded fwcmd, including
827 * request/response sizes.
829 fwcmd.set = BE_PREPARE_EMBEDDED_FWCMD(pfob,
830 wrb, COMMON_NTWK_MAC_SET);
832 fwcmd.set->params.request.invalidate = 0;
833 fwcmd.set->params.request.mac1 = (mac1 ? 1 : 0);
834 fwcmd.set->params.request.port = (port1 ? 1 : 0);
835 fwcmd.set->params.request.type = type;
837 /* Copy the mac address to set. */
838 fwcmd.set->params.request.mac.SizeOfStructure =
839 sizeof(fwcmd.set->params.request.mac);
840 memcpy(fwcmd.set->params.request.mac.MACAddress,
841 mac_address, ETH_ALEN);
843 /* Post the f/w command */
844 status = be_function_post_mcc_wrb(pfob, wrb, NULL,
845 cb, cb_context, NULL, NULL, fwcmd.set, NULL);
850 * Prepares an embedded fwcmd, including
851 * request/response sizes.
853 fwcmd.query = BE_PREPARE_EMBEDDED_FWCMD(pfob,
854 wrb, COMMON_NTWK_MAC_QUERY);
856 fwcmd.query->params.request.mac1 = (mac1 ? 1 : 0);
857 fwcmd.query->params.request.port = (port1 ? 1 : 0);
858 fwcmd.query->params.request.type = type;
859 fwcmd.query->params.request.permanent = permanent;
861 rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_MAC_QUERY,
862 params.response.mac.MACAddress);
863 rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_MAC_QUERY,
864 params.response.mac.MACAddress);
866 /* Post the f/w command (with a copy for the response) */
867 status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb,
868 cb_context, NULL, NULL, fwcmd.query, &rc);
872 TRACE(DL_ERR, "mac set/query failed.");
877 spin_unlock_irqrestore(&pfob->post_lock, irql);
878 if (pfob->pend_queue_driving && pfob->mcc) {
879 pfob->pend_queue_driving = 0;
880 be_drive_mcc_wrb_queue(pfob->mcc);
886 This routine writes data to context memory.
888 pfob - Function object handle.
889 mac_table - Set to the 128-bit multicast address hash table.
891 Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
893 IRQL: < DISPATCH_LEVEL
896 int be_rxf_multicast_config(struct be_function_object *pfob,
897 bool promiscuous, u32 num, u8 *mac_table,
898 mcc_wrb_cqe_callback cb, /* optional */
900 struct be_multicast_q_ctxt *q_ctxt)
902 int status = BE_SUCCESS;
903 struct FWCMD_COMMON_NTWK_MULTICAST_SET *fwcmd = NULL;
904 struct MCC_WRB_AMAP *wrb = NULL;
905 struct be_generic_q_ctxt *generic_ctxt = NULL;
908 ASSERT(num <= ARRAY_SIZE(fwcmd->params.request.mac));
910 if (num > ARRAY_SIZE(fwcmd->params.request.mac)) {
911 TRACE(DL_ERR, "Too many multicast addresses. BE supports %d.",
912 (int) ARRAY_SIZE(fwcmd->params.request.mac));
916 spin_lock_irqsave(&pfob->post_lock, irql);
918 wrb = be_function_peek_mcc_wrb(pfob);
921 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
922 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
923 generic_ctxt->context.bytes = sizeof(*q_ctxt);
925 status = BE_STATUS_NO_MCC_WRB;
929 /* Prepares an embedded fwcmd, including request/response sizes. */
930 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_MULTICAST_SET);
932 fwcmd->params.request.promiscuous = promiscuous;
934 fwcmd->params.request.num_mac = num;
937 memcpy(fwcmd->params.request.mac,
938 mac_table, ETH_ALEN * num);
942 /* Post the f/w command */
943 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
944 cb, cb_context, NULL, NULL, fwcmd, NULL);
946 TRACE(DL_ERR, "multicast fwcmd failed.");
951 spin_unlock_irqrestore(&pfob->post_lock, irql);
952 if (pfob->pend_queue_driving && pfob->mcc) {
953 pfob->pend_queue_driving = 0;
954 be_drive_mcc_wrb_queue(pfob->mcc);
960 This routine adds or removes a vlan tag from the rxf table.
962 FunctionObject - Function object handle.
963 VLanTag - VLan tag to add or remove.
964 Add - Set to TRUE if this will add a vlan tag
966 Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
968 IRQL: < DISPATCH_LEVEL
970 int be_rxf_vlan_config(struct be_function_object *pfob,
971 bool promiscuous, u32 num, u16 *vlan_tag_array,
972 mcc_wrb_cqe_callback cb, /* optional */
974 struct be_vlan_q_ctxt *q_ctxt) /* optional */
976 int status = BE_SUCCESS;
977 struct FWCMD_COMMON_NTWK_VLAN_CONFIG *fwcmd = NULL;
978 struct MCC_WRB_AMAP *wrb = NULL;
979 struct be_generic_q_ctxt *generic_ctxt = NULL;
982 if (num > ARRAY_SIZE(fwcmd->params.request.vlan_tag)) {
983 TRACE(DL_ERR, "Too many VLAN tags.");
987 spin_lock_irqsave(&pfob->post_lock, irql);
989 wrb = be_function_peek_mcc_wrb(pfob);
992 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
993 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
994 generic_ctxt->context.bytes = sizeof(*q_ctxt);
996 status = BE_STATUS_NO_MCC_WRB;
1000 /* Prepares an embedded fwcmd, including request/response sizes. */
1001 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_VLAN_CONFIG);
1003 fwcmd->params.request.promiscuous = promiscuous;
1005 fwcmd->params.request.num_vlan = num;
1008 ASSERT(vlan_tag_array);
1009 memcpy(fwcmd->params.request.vlan_tag, vlan_tag_array,
1010 num * sizeof(vlan_tag_array[0]));
1014 /* Post the commadn */
1015 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
1016 cb, cb_context, NULL, NULL, fwcmd, NULL);
1018 TRACE(DL_ERR, "vlan fwcmd failed.");
1023 spin_unlock_irqrestore(&pfob->post_lock, irql);
1024 if (pfob->pend_queue_driving && pfob->mcc) {
1025 pfob->pend_queue_driving = 0;
1026 be_drive_mcc_wrb_queue(pfob->mcc);
1032 int be_rxf_link_status(struct be_function_object *pfob,
1033 struct BE_LINK_STATUS *link_status,
1034 mcc_wrb_cqe_callback cb,
1036 struct be_link_status_q_ctxt *q_ctxt)
1038 struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY *fwcmd = NULL;
1039 struct MCC_WRB_AMAP *wrb = NULL;
1041 struct be_generic_q_ctxt *generic_ctxt = NULL;
1043 struct be_mcc_wrb_response_copy rc;
1045 ASSERT(link_status);
1047 spin_lock_irqsave(&pfob->post_lock, irql);
1049 wrb = be_function_peek_mcc_wrb(pfob);
1053 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
1054 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
1055 generic_ctxt->context.bytes = sizeof(*q_ctxt);
1057 status = BE_STATUS_NO_MCC_WRB;
1061 /* Prepares an embedded fwcmd, including request/response sizes. */
1062 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb,
1063 COMMON_NTWK_LINK_STATUS_QUERY);
1065 rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
1067 rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
1069 rc.va = link_status;
1070 /* Post or queue the f/w command */
1071 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
1072 cb, cb_context, NULL, NULL, fwcmd, &rc);
1075 TRACE(DL_ERR, "link status fwcmd failed.");
1080 spin_unlock_irqrestore(&pfob->post_lock, irql);
1081 if (pfob->pend_queue_driving && pfob->mcc) {
1082 pfob->pend_queue_driving = 0;
1083 be_drive_mcc_wrb_queue(pfob->mcc);
1089 be_rxf_query_eth_statistics(struct be_function_object *pfob,
1090 struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd,
1091 u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb,
1093 struct be_nonembedded_q_ctxt *q_ctxt)
1095 struct MCC_WRB_AMAP *wrb = NULL;
1097 struct be_generic_q_ctxt *generic_ctxt = NULL;
1100 ASSERT(va_for_fwcmd);
1101 ASSERT(pa_for_fwcmd);
1103 spin_lock_irqsave(&pfob->post_lock, irql);
1105 wrb = be_function_peek_mcc_wrb(pfob);
1109 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
1110 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
1111 generic_ctxt->context.bytes = sizeof(*q_ctxt);
1113 status = BE_STATUS_NO_MCC_WRB;
1118 TRACE(DL_INFO, "Query eth stats. fwcmd va:%p pa:0x%08x_%08x",
1119 va_for_fwcmd, upper_32_bits(pa_for_fwcmd), (u32)pa_for_fwcmd);
1121 /* Prepares an embedded fwcmd, including request/response sizes. */
1122 va_for_fwcmd = BE_PREPARE_NONEMBEDDED_FWCMD(pfob, wrb,
1123 va_for_fwcmd, pa_for_fwcmd, ETH_GET_STATISTICS);
1125 /* Post the f/w command */
1126 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
1127 cb, cb_context, NULL, NULL, va_for_fwcmd, NULL);
1129 TRACE(DL_ERR, "eth stats fwcmd failed.");
1134 spin_unlock_irqrestore(&pfob->post_lock, irql);
1135 if (pfob->pend_queue_driving && pfob->mcc) {
1136 pfob->pend_queue_driving = 0;
1137 be_drive_mcc_wrb_queue(pfob->mcc);
1143 be_rxf_promiscuous(struct be_function_object *pfob,
1144 bool enable_port0, bool enable_port1,
1145 mcc_wrb_cqe_callback cb, void *cb_context,
1146 struct be_promiscuous_q_ctxt *q_ctxt)
1148 struct FWCMD_ETH_PROMISCUOUS *fwcmd = NULL;
1149 struct MCC_WRB_AMAP *wrb = NULL;
1151 struct be_generic_q_ctxt *generic_ctxt = NULL;
1155 spin_lock_irqsave(&pfob->post_lock, irql);
1157 wrb = be_function_peek_mcc_wrb(pfob);
1161 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
1162 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
1163 generic_ctxt->context.bytes = sizeof(*q_ctxt);
1165 status = BE_STATUS_NO_MCC_WRB;
1169 /* Prepares an embedded fwcmd, including request/response sizes. */
1170 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_PROMISCUOUS);
1172 fwcmd->params.request.port0_promiscuous = enable_port0;
1173 fwcmd->params.request.port1_promiscuous = enable_port1;
1175 /* Post the f/w command */
1176 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
1177 cb, cb_context, NULL, NULL, fwcmd, NULL);
1180 TRACE(DL_ERR, "promiscuous fwcmd failed.");
1185 spin_unlock_irqrestore(&pfob->post_lock, irql);
1186 if (pfob->pend_queue_driving && pfob->mcc) {
1187 pfob->pend_queue_driving = 0;
1188 be_drive_mcc_wrb_queue(pfob->mcc);
1195 *-------------------------------------------------------------------------
1196 * Function: be_rxf_filter_config
1197 * Configures BladeEngine ethernet receive filter settings.
1199 * settings - Pointer to the requested filter settings.
1200 * The response from BladeEngine will be placed back
1201 * in this structure.
1203 * cb_context - optional
1204 * q_ctxt - Optional. Pointer to a previously allocated struct.
1205 * If the MCC WRB ring is full, this structure is
1206 * used to queue the operation. It will be posted
1207 * to the MCC ring when space becomes available. All
1208 * queued commands will be posted to the ring in
1209 * the order they are received. It is always valid
1210 * to pass a pointer to a generic
1211 * be_generic_q_ctxt. However, the specific
1212 * context structs are generally smaller than
1213 * the generic struct.
1214 * return pend_status - BE_SUCCESS (0) on success.
1215 * BE_PENDING (postive value) if the FWCMD
1216 * completion is pending. Negative error code on failure.
1217 *---------------------------------------------------------------------------
1220 be_rxf_filter_config(struct be_function_object *pfob,
1221 struct NTWK_RX_FILTER_SETTINGS *settings,
1222 mcc_wrb_cqe_callback cb, void *cb_context,
1223 struct be_rxf_filter_q_ctxt *q_ctxt)
1225 struct FWCMD_COMMON_NTWK_RX_FILTER *fwcmd = NULL;
1226 struct MCC_WRB_AMAP *wrb = NULL;
1228 struct be_generic_q_ctxt *generic_ctxt = NULL;
1230 struct be_mcc_wrb_response_copy rc;
1234 spin_lock_irqsave(&pfob->post_lock, irql);
1236 wrb = be_function_peek_mcc_wrb(pfob);
1240 wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
1241 generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
1242 generic_ctxt->context.bytes = sizeof(*q_ctxt);
1244 status = BE_STATUS_NO_MCC_WRB;
1248 /* Prepares an embedded fwcmd, including request/response sizes. */
1249 fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_RX_FILTER);
1250 memcpy(&fwcmd->params.request, settings, sizeof(*settings));
1252 rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_RX_FILTER,
1254 rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_RX_FILTER,
1257 /* Post or queue the f/w command */
1258 status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
1259 cb, cb_context, NULL, NULL, fwcmd, &rc);
1262 TRACE(DL_ERR, "RXF/ERX filter config fwcmd failed.");
1267 spin_unlock_irqrestore(&pfob->post_lock, irql);
1268 if (pfob->pend_queue_driving && pfob->mcc) {
1269 pfob->pend_queue_driving = 0;
1270 be_drive_mcc_wrb_queue(pfob->mcc);