12
12
#include <linux/platform_device.h>
13
13
#include <linux/interrupt.h>
14
14
#include <linux/dma-mapping.h>
15
+ #include <linux/dim.h>
15
16
#include <linux/slab.h>
16
17
17
18
#include "dpio.h"
@@ -28,6 +29,14 @@ struct dpaa2_io {
28
29
spinlock_t lock_notifications ;
29
30
struct list_head notifications ;
30
31
struct device * dev ;
32
+
33
+ /* Net DIM */
34
+ struct dim rx_dim ;
35
+ /* protect against concurrent Net DIM updates */
36
+ spinlock_t dim_lock ;
37
+ u16 event_ctr ;
38
+ u64 bytes ;
39
+ u64 frames ;
31
40
};
32
41
33
42
struct dpaa2_io_store {
@@ -100,6 +109,17 @@ struct dpaa2_io *dpaa2_io_service_select(int cpu)
100
109
}
101
110
EXPORT_SYMBOL_GPL (dpaa2_io_service_select );
102
111
112
+ static void dpaa2_io_dim_work (struct work_struct * w )
113
+ {
114
+ struct dim * dim = container_of (w , struct dim , work );
115
+ struct dim_cq_moder moder =
116
+ net_dim_get_rx_moderation (dim -> mode , dim -> profile_ix );
117
+ struct dpaa2_io * d = container_of (dim , struct dpaa2_io , rx_dim );
118
+
119
+ dpaa2_io_set_irq_coalescing (d , moder .usec );
120
+ dim -> state = DIM_START_MEASURE ;
121
+ }
122
+
103
123
/**
104
124
* dpaa2_io_create() - create a dpaa2_io object.
105
125
* @desc: the dpaa2_io descriptor
@@ -147,6 +167,7 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
147
167
INIT_LIST_HEAD (& obj -> node );
148
168
spin_lock_init (& obj -> lock_mgmt_cmd );
149
169
spin_lock_init (& obj -> lock_notifications );
170
+ spin_lock_init (& obj -> dim_lock );
150
171
INIT_LIST_HEAD (& obj -> notifications );
151
172
152
173
/* For now only enable DQRR interrupts */
@@ -164,6 +185,12 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc,
164
185
165
186
obj -> dev = dev ;
166
187
188
+ memset (& obj -> rx_dim , 0 , sizeof (obj -> rx_dim ));
189
+ INIT_WORK (& obj -> rx_dim .work , dpaa2_io_dim_work );
190
+ obj -> event_ctr = 0 ;
191
+ obj -> bytes = 0 ;
192
+ obj -> frames = 0 ;
193
+
167
194
return obj ;
168
195
}
169
196
@@ -203,6 +230,8 @@ irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj)
203
230
struct qbman_swp * swp ;
204
231
u32 status ;
205
232
233
+ obj -> event_ctr ++ ;
234
+
206
235
swp = obj -> swp ;
207
236
status = qbman_swp_interrupt_read_status (swp );
208
237
if (!status )
@@ -817,3 +846,53 @@ void dpaa2_io_get_irq_coalescing(struct dpaa2_io *d, u32 *irq_holdoff)
817
846
qbman_swp_get_irq_coalescing (swp , NULL , irq_holdoff );
818
847
}
819
848
EXPORT_SYMBOL (dpaa2_io_get_irq_coalescing );
849
+
850
+ /**
851
+ * dpaa2_io_set_adaptive_coalescing() - Enable/disable adaptive coalescing
852
+ * @d: the given DPIO object
853
+ * @use_adaptive_rx_coalesce: adaptive coalescing state
854
+ */
855
+ void dpaa2_io_set_adaptive_coalescing (struct dpaa2_io * d ,
856
+ int use_adaptive_rx_coalesce )
857
+ {
858
+ d -> swp -> use_adaptive_rx_coalesce = use_adaptive_rx_coalesce ;
859
+ }
860
+ EXPORT_SYMBOL (dpaa2_io_set_adaptive_coalescing );
861
+
862
+ /**
863
+ * dpaa2_io_get_adaptive_coalescing() - Query adaptive coalescing state
864
+ * @d: the given DPIO object
865
+ *
866
+ * Return 1 when adaptive coalescing is enabled on the DPIO object and 0
867
+ * otherwise.
868
+ */
869
+ int dpaa2_io_get_adaptive_coalescing (struct dpaa2_io * d )
870
+ {
871
+ return d -> swp -> use_adaptive_rx_coalesce ;
872
+ }
873
+ EXPORT_SYMBOL (dpaa2_io_get_adaptive_coalescing );
874
+
875
+ /**
876
+ * dpaa2_io_update_net_dim() - Update Net DIM
877
+ * @d: the given DPIO object
878
+ * @frames: how many frames have been dequeued by the user since the last call
879
+ * @bytes: how many bytes have been dequeued by the user since the last call
880
+ */
881
+ void dpaa2_io_update_net_dim (struct dpaa2_io * d , __u64 frames , __u64 bytes )
882
+ {
883
+ struct dim_sample dim_sample = {};
884
+
885
+ if (!d -> swp -> use_adaptive_rx_coalesce )
886
+ return ;
887
+
888
+ spin_lock (& d -> dim_lock );
889
+
890
+ d -> bytes += bytes ;
891
+ d -> frames += frames ;
892
+
893
+ dim_update_sample (d -> event_ctr , d -> frames , d -> bytes , & dim_sample );
894
+ net_dim (& d -> rx_dim , dim_sample );
895
+
896
+ spin_unlock (& d -> dim_lock );
897
+ }
898
+ EXPORT_SYMBOL (dpaa2_io_update_net_dim );
0 commit comments