2323#include <linux/sizes.h>
2424#include <linux/atomic.h>
2525#include <linux/skbuff.h>
26+ #include <linux/io.h>
2627#include <asm/barrier.h>
2728#include <asm/byteorder.h>
2829
3233#include "hinic_hw_wq.h"
3334#include "hinic_hw_qp_ctxt.h"
3435#include "hinic_hw_qp.h"
36+ #include "hinic_hw_io.h"
3537
3638#define SQ_DB_OFF SZ_2K
3739
5355 (((max_rqs) + (max_sqs)) * CTXT_RSVD + \
5456 (max_sqs + (q_id)) * Q_CTXT_SIZE)
5557
56- #define SIZE_16BYTES (size ) (ALIGN(size, 16) >> 4)
57- #define SIZE_8BYTES (size ) (ALIGN(size, 8) >> 3)
58+ #define SIZE_16BYTES (size ) (ALIGN(size, 16) >> 4)
59+ #define SIZE_8BYTES (size ) (ALIGN(size, 8) >> 3)
60+ #define SECT_SIZE_FROM_8BYTES (size ) ((size) << 3)
5861
62+ #define SQ_DB_PI_HI_SHIFT 8
63+ #define SQ_DB_PI_HI (prod_idx ) ((prod_idx) >> SQ_DB_PI_HI_SHIFT)
64+
65+ #define SQ_DB_PI_LOW_MASK 0xFF
66+ #define SQ_DB_PI_LOW (prod_idx ) ((prod_idx) & SQ_DB_PI_LOW_MASK)
67+
68+ #define SQ_DB_ADDR (sq , pi ) ((u64 *)((sq)->db_base) + SQ_DB_PI_LOW(pi))
69+
70+ #define SQ_MASKED_IDX (sq , idx ) ((idx) & (sq)->wq->mask)
5971#define RQ_MASKED_IDX (rq , idx ) ((idx) & (rq)->wq->mask)
6072
73+ #define TX_MAX_MSS_DEFAULT 0x3E00
74+
75+ enum sq_wqe_type {
76+ SQ_NORMAL_WQE = 0 ,
77+ };
78+
6179enum rq_completion_fmt {
6280 RQ_COMPLETE_SGE = 1
6381};
@@ -435,6 +453,19 @@ void hinic_clean_rq(struct hinic_rq *rq)
435453 free_rq_skb_arr (rq );
436454}
437455
456+ /**
457+ * hinic_get_sq_free_wqebbs - return number of free wqebbs for use
458+ * @sq: send queue
459+ *
460+ * Return number of free wqebbs
461+ **/
462+ int hinic_get_sq_free_wqebbs (struct hinic_sq * sq )
463+ {
464+ struct hinic_wq * wq = sq -> wq ;
465+
466+ return atomic_read (& wq -> delta ) - 1 ;
467+ }
468+
438469/**
439470 * hinic_get_rq_free_wqebbs - return number of free wqebbs for use
440471 * @rq: recv queue
@@ -448,6 +479,228 @@ int hinic_get_rq_free_wqebbs(struct hinic_rq *rq)
448479 return atomic_read (& wq -> delta ) - 1 ;
449480}
450481
482+ static void sq_prepare_ctrl (struct hinic_sq_ctrl * ctrl , u16 prod_idx ,
483+ int nr_descs )
484+ {
485+ u32 ctrl_size , task_size , bufdesc_size ;
486+
487+ ctrl_size = SIZE_8BYTES (sizeof (struct hinic_sq_ctrl ));
488+ task_size = SIZE_8BYTES (sizeof (struct hinic_sq_task ));
489+ bufdesc_size = nr_descs * sizeof (struct hinic_sq_bufdesc );
490+ bufdesc_size = SIZE_8BYTES (bufdesc_size );
491+
492+ ctrl -> ctrl_info = HINIC_SQ_CTRL_SET (bufdesc_size , BUFDESC_SECT_LEN ) |
493+ HINIC_SQ_CTRL_SET (task_size , TASKSECT_LEN ) |
494+ HINIC_SQ_CTRL_SET (SQ_NORMAL_WQE , DATA_FORMAT ) |
495+ HINIC_SQ_CTRL_SET (ctrl_size , LEN );
496+
497+ ctrl -> queue_info = HINIC_SQ_CTRL_SET (TX_MAX_MSS_DEFAULT ,
498+ QUEUE_INFO_MSS );
499+ }
500+
501+ static void sq_prepare_task (struct hinic_sq_task * task )
502+ {
503+ task -> pkt_info0 =
504+ HINIC_SQ_TASK_INFO0_SET (0 , L2HDR_LEN ) |
505+ HINIC_SQ_TASK_INFO0_SET (HINIC_L4_OFF_DISABLE , L4_OFFLOAD ) |
506+ HINIC_SQ_TASK_INFO0_SET (HINIC_OUTER_L3TYPE_UNKNOWN ,
507+ INNER_L3TYPE ) |
508+ HINIC_SQ_TASK_INFO0_SET (HINIC_VLAN_OFF_DISABLE ,
509+ VLAN_OFFLOAD ) |
510+ HINIC_SQ_TASK_INFO0_SET (HINIC_PKT_NOT_PARSED , PARSE_FLAG );
511+
512+ task -> pkt_info1 =
513+ HINIC_SQ_TASK_INFO1_SET (HINIC_MEDIA_UNKNOWN , MEDIA_TYPE ) |
514+ HINIC_SQ_TASK_INFO1_SET (0 , INNER_L4_LEN ) |
515+ HINIC_SQ_TASK_INFO1_SET (0 , INNER_L3_LEN );
516+
517+ task -> pkt_info2 =
518+ HINIC_SQ_TASK_INFO2_SET (0 , TUNNEL_L4_LEN ) |
519+ HINIC_SQ_TASK_INFO2_SET (0 , OUTER_L3_LEN ) |
520+ HINIC_SQ_TASK_INFO2_SET (HINIC_TUNNEL_L4TYPE_UNKNOWN ,
521+ TUNNEL_L4TYPE ) |
522+ HINIC_SQ_TASK_INFO2_SET (HINIC_OUTER_L3TYPE_UNKNOWN ,
523+ OUTER_L3TYPE );
524+
525+ task -> ufo_v6_identify = 0 ;
526+
527+ task -> pkt_info4 = HINIC_SQ_TASK_INFO4_SET (HINIC_L2TYPE_ETH , L2TYPE );
528+
529+ task -> zero_pad = 0 ;
530+ }
531+
532+ /**
533+ * hinic_sq_prepare_wqe - prepare wqe before insert to the queue
534+ * @sq: send queue
535+ * @prod_idx: pi value
536+ * @sq_wqe: wqe to prepare
537+ * @sges: sges for use by the wqe for send for buf addresses
538+ * @nr_sges: number of sges
539+ **/
540+ void hinic_sq_prepare_wqe (struct hinic_sq * sq , u16 prod_idx ,
541+ struct hinic_sq_wqe * sq_wqe , struct hinic_sge * sges ,
542+ int nr_sges )
543+ {
544+ int i ;
545+
546+ sq_prepare_ctrl (& sq_wqe -> ctrl , prod_idx , nr_sges );
547+
548+ sq_prepare_task (& sq_wqe -> task );
549+
550+ for (i = 0 ; i < nr_sges ; i ++ )
551+ sq_wqe -> buf_descs [i ].sge = sges [i ];
552+ }
553+
554+ /**
555+ * sq_prepare_db - prepare doorbell to write
556+ * @sq: send queue
557+ * @prod_idx: pi value for the doorbell
558+ * @cos: cos of the doorbell
559+ *
560+ * Return db value
561+ **/
562+ static u32 sq_prepare_db (struct hinic_sq * sq , u16 prod_idx , unsigned int cos )
563+ {
564+ struct hinic_qp * qp = container_of (sq , struct hinic_qp , sq );
565+ u8 hi_prod_idx = SQ_DB_PI_HI (SQ_MASKED_IDX (sq , prod_idx ));
566+
567+ /* Data should be written to HW in Big Endian Format */
568+ return cpu_to_be32 (HINIC_SQ_DB_INFO_SET (hi_prod_idx , PI_HI ) |
569+ HINIC_SQ_DB_INFO_SET (HINIC_DB_SQ_TYPE , TYPE ) |
570+ HINIC_SQ_DB_INFO_SET (HINIC_DATA_PATH , PATH ) |
571+ HINIC_SQ_DB_INFO_SET (cos , COS ) |
572+ HINIC_SQ_DB_INFO_SET (qp -> q_id , QID ));
573+ }
574+
575+ /**
576+ * hinic_sq_write_db- write doorbell
577+ * @sq: send queue
578+ * @prod_idx: pi value for the doorbell
579+ * @wqe_size: wqe size
580+ * @cos: cos of the wqe
581+ **/
582+ void hinic_sq_write_db (struct hinic_sq * sq , u16 prod_idx , unsigned int wqe_size ,
583+ unsigned int cos )
584+ {
585+ struct hinic_wq * wq = sq -> wq ;
586+
587+ /* increment prod_idx to the next */
588+ prod_idx += ALIGN (wqe_size , wq -> wqebb_size ) / wq -> wqebb_size ;
589+
590+ wmb (); /* Write all before the doorbell */
591+
592+ writel (sq_prepare_db (sq , prod_idx , cos ), SQ_DB_ADDR (sq , prod_idx ));
593+ }
594+
595+ /**
596+ * hinic_sq_get_wqe - get wqe ptr in the current pi and update the pi
597+ * @sq: sq to get wqe from
598+ * @wqe_size: wqe size
599+ * @prod_idx: returned pi
600+ *
601+ * Return wqe pointer
602+ **/
603+ struct hinic_sq_wqe * hinic_sq_get_wqe (struct hinic_sq * sq ,
604+ unsigned int wqe_size , u16 * prod_idx )
605+ {
606+ struct hinic_hw_wqe * hw_wqe = hinic_get_wqe (sq -> wq , wqe_size ,
607+ prod_idx );
608+
609+ if (IS_ERR (hw_wqe ))
610+ return NULL ;
611+
612+ return & hw_wqe -> sq_wqe ;
613+ }
614+
615+ /**
616+ * hinic_sq_write_wqe - write the wqe to the sq
617+ * @sq: send queue
618+ * @prod_idx: pi of the wqe
619+ * @sq_wqe: the wqe to write
620+ * @skb: skb to save
621+ * @wqe_size: the size of the wqe
622+ **/
623+ void hinic_sq_write_wqe (struct hinic_sq * sq , u16 prod_idx ,
624+ struct hinic_sq_wqe * sq_wqe ,
625+ struct sk_buff * skb , unsigned int wqe_size )
626+ {
627+ struct hinic_hw_wqe * hw_wqe = (struct hinic_hw_wqe * )sq_wqe ;
628+
629+ sq -> saved_skb [prod_idx ] = skb ;
630+
631+ /* The data in the HW should be in Big Endian Format */
632+ hinic_cpu_to_be32 (sq_wqe , wqe_size );
633+
634+ hinic_write_wqe (sq -> wq , hw_wqe , wqe_size );
635+ }
636+
637+ /**
638+ * hinic_sq_read_wqe - read wqe ptr in the current ci and update the ci
639+ * @sq: send queue
640+ * @skb: return skb that was saved
641+ * @wqe_size: the size of the wqe
642+ * @cons_idx: consumer index of the wqe
643+ *
644+ * Return wqe in ci position
645+ **/
646+ struct hinic_sq_wqe * hinic_sq_read_wqe (struct hinic_sq * sq ,
647+ struct sk_buff * * skb ,
648+ unsigned int * wqe_size , u16 * cons_idx )
649+ {
650+ struct hinic_hw_wqe * hw_wqe ;
651+ struct hinic_sq_wqe * sq_wqe ;
652+ struct hinic_sq_ctrl * ctrl ;
653+ unsigned int buf_sect_len ;
654+ u32 ctrl_info ;
655+
656+ /* read the ctrl section for getting wqe size */
657+ hw_wqe = hinic_read_wqe (sq -> wq , sizeof (* ctrl ), cons_idx );
658+ if (IS_ERR (hw_wqe ))
659+ return NULL ;
660+
661+ sq_wqe = & hw_wqe -> sq_wqe ;
662+ ctrl = & sq_wqe -> ctrl ;
663+ ctrl_info = be32_to_cpu (ctrl -> ctrl_info );
664+ buf_sect_len = HINIC_SQ_CTRL_GET (ctrl_info , BUFDESC_SECT_LEN );
665+
666+ * wqe_size = sizeof (* ctrl ) + sizeof (sq_wqe -> task );
667+ * wqe_size += SECT_SIZE_FROM_8BYTES (buf_sect_len );
668+
669+ * skb = sq -> saved_skb [* cons_idx ];
670+
671+ /* using the real wqe size to read wqe again */
672+ hw_wqe = hinic_read_wqe (sq -> wq , * wqe_size , cons_idx );
673+
674+ return & hw_wqe -> sq_wqe ;
675+ }
676+
677+ /**
678+ * hinic_sq_put_wqe - release the ci for new wqes
679+ * @sq: send queue
680+ * @wqe_size: the size of the wqe
681+ **/
682+ void hinic_sq_put_wqe (struct hinic_sq * sq , unsigned int wqe_size )
683+ {
684+ hinic_put_wqe (sq -> wq , wqe_size );
685+ }
686+
687+ /**
688+ * hinic_sq_get_sges - get sges from the wqe
689+ * @sq_wqe: wqe to get the sges from its buffer addresses
690+ * @sges: returned sges
691+ * @nr_sges: number sges to return
692+ **/
693+ void hinic_sq_get_sges (struct hinic_sq_wqe * sq_wqe , struct hinic_sge * sges ,
694+ int nr_sges )
695+ {
696+ int i ;
697+
698+ for (i = 0 ; i < nr_sges && i < HINIC_MAX_SQ_BUFDESCS ; i ++ ) {
699+ sges [i ] = sq_wqe -> buf_descs [i ].sge ;
700+ hinic_be32_to_cpu (& sges [i ], sizeof (sges [i ]));
701+ }
702+ }
703+
451704/**
452705 * hinic_rq_get_wqe - get wqe ptr in the current pi and update the pi
453706 * @rq: rq to get wqe from
0 commit comments