66#include "enic.h"
77#include "enic_wq.h"
88
9- static void cq_desc_dec (const struct cq_desc * desc_arg , u8 * type , u8 * color ,
10- u16 * q_number , u16 * completed_index )
9+ #define ENET_CQ_DESC_COMP_NDX_BITS 14
10+ #define ENET_CQ_DESC_COMP_NDX_MASK GENMASK(ENET_CQ_DESC_COMP_NDX_BITS - 1, 0)
11+
12+ static void enic_wq_cq_desc_dec (const struct cq_desc * desc_arg , bool ext_wq ,
13+ u8 * type , u8 * color , u16 * q_number ,
14+ u16 * completed_index )
1115{
1216 const struct cq_desc * desc = desc_arg ;
1317 const u8 type_color = desc -> type_color ;
@@ -25,48 +29,13 @@ static void cq_desc_dec(const struct cq_desc *desc_arg, u8 *type, u8 *color,
2529
2630 * type = type_color & CQ_DESC_TYPE_MASK ;
2731 * q_number = le16_to_cpu (desc -> q_number ) & CQ_DESC_Q_NUM_MASK ;
28- * completed_index = le16_to_cpu (desc -> completed_index ) &
29- CQ_DESC_COMP_NDX_MASK ;
30- }
31-
32- unsigned int vnic_cq_service (struct vnic_cq * cq , unsigned int work_to_do ,
33- int (* q_service )(struct vnic_dev * vdev ,
34- struct cq_desc * cq_desc , u8 type ,
35- u16 q_number , u16 completed_index ,
36- void * opaque ), void * opaque )
37- {
38- struct cq_desc * cq_desc ;
39- unsigned int work_done = 0 ;
40- u16 q_number , completed_index ;
41- u8 type , color ;
42-
43- cq_desc = (struct cq_desc * )((u8 * )cq -> ring .descs +
44- cq -> ring .desc_size * cq -> to_clean );
45- cq_desc_dec (cq_desc , & type , & color ,
46- & q_number , & completed_index );
47-
48- while (color != cq -> last_color ) {
49- if ((* q_service )(cq -> vdev , cq_desc , type , q_number ,
50- completed_index , opaque ))
51- break ;
52-
53- cq -> to_clean ++ ;
54- if (cq -> to_clean == cq -> ring .desc_count ) {
55- cq -> to_clean = 0 ;
56- cq -> last_color = cq -> last_color ? 0 : 1 ;
57- }
58-
59- cq_desc = (struct cq_desc * )((u8 * )cq -> ring .descs +
60- cq -> ring .desc_size * cq -> to_clean );
61- cq_desc_dec (cq_desc , & type , & color ,
62- & q_number , & completed_index );
6332
64- work_done ++ ;
65- if ( work_done >= work_to_do )
66- break ;
67- }
68-
69- return work_done ;
33+ if ( ext_wq )
34+ * completed_index = le16_to_cpu ( desc -> completed_index ) &
35+ ENET_CQ_DESC_COMP_NDX_MASK ;
36+ else
37+ * completed_index = le16_to_cpu ( desc -> completed_index ) &
38+ CQ_DESC_COMP_NDX_MASK ;
7039}
7140
7241void enic_free_wq_buf (struct vnic_wq * wq , struct vnic_wq_buf * buf )
@@ -94,15 +63,15 @@ static void enic_wq_free_buf(struct vnic_wq *wq, struct cq_desc *cq_desc,
9463 enic_free_wq_buf (wq , buf );
9564}
9665
97- int enic_wq_service (struct vnic_dev * vdev , struct cq_desc * cq_desc , u8 type ,
98- u16 q_number , u16 completed_index , void * opaque )
66+ static void enic_wq_service (struct vnic_dev * vdev , struct cq_desc * cq_desc ,
67+ u8 type , u16 q_number , u16 completed_index )
9968{
10069 struct enic * enic = vnic_dev_priv (vdev );
10170
10271 spin_lock (& enic -> wq [q_number ].lock );
10372
10473 vnic_wq_service (& enic -> wq [q_number ].vwq , cq_desc ,
105- completed_index , enic_wq_free_buf , opaque );
74+ completed_index , enic_wq_free_buf , NULL );
10675
10776 if (netif_tx_queue_stopped (netdev_get_tx_queue (enic -> netdev , q_number ))
10877 && vnic_wq_desc_avail (& enic -> wq [q_number ].vwq ) >=
@@ -112,7 +81,37 @@ int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
11281 }
11382
11483 spin_unlock (& enic -> wq [q_number ].lock );
115-
116- return 0 ;
11784}
11885
86+ unsigned int enic_wq_cq_service (struct enic * enic , unsigned int cq_index ,
87+ unsigned int work_to_do )
88+ {
89+ struct vnic_cq * cq = & enic -> cq [cq_index ];
90+ u16 q_number , completed_index ;
91+ unsigned int work_done = 0 ;
92+ struct cq_desc * cq_desc ;
93+ u8 type , color ;
94+ bool ext_wq ;
95+
96+ ext_wq = cq -> ring .size > ENIC_MAX_WQ_DESCS ;
97+
98+ cq_desc = (struct cq_desc * )vnic_cq_to_clean (cq );
99+ enic_wq_cq_desc_dec (cq_desc , ext_wq , & type , & color ,
100+ & q_number , & completed_index );
101+
102+ while (color != cq -> last_color ) {
103+ enic_wq_service (cq -> vdev , cq_desc , type , q_number ,
104+ completed_index );
105+
106+ vnic_cq_inc_to_clean (cq );
107+
108+ if (++ work_done >= work_to_do )
109+ break ;
110+
111+ cq_desc = (struct cq_desc * )vnic_cq_to_clean (cq );
112+ enic_wq_cq_desc_dec (cq_desc , ext_wq , & type , & color ,
113+ & q_number , & completed_index );
114+ }
115+
116+ return work_done ;
117+ }
0 commit comments