@@ -429,6 +429,95 @@ int t4vf_set_params(struct adapter *adapter, unsigned int nparams,
429429 return t4vf_wr_mbox (adapter , & cmd , sizeof (cmd ), NULL );
430430}
431431
432+ /**
433+ * t4_bar2_sge_qregs - return BAR2 SGE Queue register information
434+ * @adapter: the adapter
435+ * @qid: the Queue ID
436+ * @qtype: the Ingress or Egress type for @qid
437+ * @pbar2_qoffset: BAR2 Queue Offset
438+ * @pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues
439+ *
440+ * Returns the BAR2 SGE Queue Registers information associated with the
441+ * indicated Absolute Queue ID. These are passed back in return value
442+ * pointers. @qtype should be T4_BAR2_QTYPE_EGRESS for Egress Queue
443+ * and T4_BAR2_QTYPE_INGRESS for Ingress Queues.
444+ *
445+ * This may return an error which indicates that BAR2 SGE Queue
446+ * registers aren't available. If an error is not returned, then the
447+ * following values are returned:
448+ *
449+ * *@pbar2_qoffset: the BAR2 Offset of the @qid Registers
450+ * *@pbar2_qid: the BAR2 SGE Queue ID or 0 of @qid
451+ *
452+ * If the returned BAR2 Queue ID is 0, then BAR2 SGE registers which
453+ * require the "Inferred Queue ID" ability may be used. E.g. the
454+ * Write Combining Doorbell Buffer. If the BAR2 Queue ID is not 0,
455+ * then these "Inferred Queue ID" register may not be used.
456+ */
457+ int t4_bar2_sge_qregs (struct adapter * adapter ,
458+ unsigned int qid ,
459+ enum t4_bar2_qtype qtype ,
460+ u64 * pbar2_qoffset ,
461+ unsigned int * pbar2_qid )
462+ {
463+ unsigned int page_shift , page_size , qpp_shift , qpp_mask ;
464+ u64 bar2_page_offset , bar2_qoffset ;
465+ unsigned int bar2_qid , bar2_qid_offset , bar2_qinferred ;
466+
467+ /* T4 doesn't support BAR2 SGE Queue registers.
468+ */
469+ if (is_t4 (adapter -> params .chip ))
470+ return - EINVAL ;
471+
472+ /* Get our SGE Page Size parameters.
473+ */
474+ page_shift = adapter -> params .sge .sge_vf_hps + 10 ;
475+ page_size = 1 << page_shift ;
476+
477+ /* Get the right Queues per Page parameters for our Queue.
478+ */
479+ qpp_shift = (qtype == T4_BAR2_QTYPE_EGRESS
480+ ? adapter -> params .sge .sge_vf_eq_qpp
481+ : adapter -> params .sge .sge_vf_iq_qpp );
482+ qpp_mask = (1 << qpp_shift ) - 1 ;
483+
484+ /* Calculate the basics of the BAR2 SGE Queue register area:
485+ * o The BAR2 page the Queue registers will be in.
486+ * o The BAR2 Queue ID.
487+ * o The BAR2 Queue ID Offset into the BAR2 page.
488+ */
489+ bar2_page_offset = ((qid >> qpp_shift ) << page_shift );
490+ bar2_qid = qid & qpp_mask ;
491+ bar2_qid_offset = bar2_qid * SGE_UDB_SIZE ;
492+
493+ /* If the BAR2 Queue ID Offset is less than the Page Size, then the
494+ * hardware will infer the Absolute Queue ID simply from the writes to
495+ * the BAR2 Queue ID Offset within the BAR2 Page (and we need to use a
496+ * BAR2 Queue ID of 0 for those writes). Otherwise, we'll simply
497+ * write to the first BAR2 SGE Queue Area within the BAR2 Page with
498+ * the BAR2 Queue ID and the hardware will infer the Absolute Queue ID
499+ * from the BAR2 Page and BAR2 Queue ID.
500+ *
501+ * One important censequence of this is that some BAR2 SGE registers
502+ * have a "Queue ID" field and we can write the BAR2 SGE Queue ID
503+ * there. But other registers synthesize the SGE Queue ID purely
504+ * from the writes to the registers -- the Write Combined Doorbell
505+ * Buffer is a good example. These BAR2 SGE Registers are only
506+ * available for those BAR2 SGE Register areas where the SGE Absolute
507+ * Queue ID can be inferred from simple writes.
508+ */
509+ bar2_qoffset = bar2_page_offset ;
510+ bar2_qinferred = (bar2_qid_offset < page_size );
511+ if (bar2_qinferred ) {
512+ bar2_qoffset += bar2_qid_offset ;
513+ bar2_qid = 0 ;
514+ }
515+
516+ * pbar2_qoffset = bar2_qoffset ;
517+ * pbar2_qid = bar2_qid ;
518+ return 0 ;
519+ }
520+
432521/**
433522 * t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters
434523 * @adapter: the adapter
@@ -507,7 +596,7 @@ int t4vf_get_sge_params(struct adapter *adapter)
507596 */
508597 if (!is_t4 (adapter -> params .chip )) {
509598 u32 whoami ;
510- unsigned int pf , s_qpp ;
599+ unsigned int pf , s_hps , s_qpp ;
511600
512601 params [0 ] = (FW_PARAMS_MNEM_V (FW_PARAMS_MNEM_REG ) |
513602 FW_PARAMS_PARAM_XYZ_V (
@@ -533,6 +622,13 @@ int t4vf_get_sge_params(struct adapter *adapter)
533622 whoami = t4_read_reg (adapter ,
534623 T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI );
535624 pf = SOURCEPF_GET (whoami );
625+
626+ s_hps = (HOSTPAGESIZEPF0_S +
627+ (HOSTPAGESIZEPF1_S - HOSTPAGESIZEPF0_S ) * pf );
628+ sge_params -> sge_vf_hps =
629+ ((sge_params -> sge_host_page_size >> s_hps )
630+ & HOSTPAGESIZEPF0_M );
631+
536632 s_qpp = (QUEUESPERPAGEPF0_S +
537633 (QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S ) * pf );
538634 sge_params -> sge_vf_eq_qpp =
0 commit comments