@@ -137,13 +137,15 @@ static irqreturn_t xgene_enet_rx_irq(const int irq, void *data)
137
137
static int xgene_enet_tx_completion (struct xgene_enet_desc_ring * cp_ring ,
138
138
struct xgene_enet_raw_desc * raw_desc )
139
139
{
140
+ struct xgene_enet_pdata * pdata = netdev_priv (cp_ring -> ndev );
140
141
struct sk_buff * skb ;
141
142
struct device * dev ;
142
143
skb_frag_t * frag ;
143
144
dma_addr_t * frag_dma_addr ;
144
145
u16 skb_index ;
145
146
u8 status ;
146
147
int i , ret = 0 ;
148
+ u8 mss_index ;
147
149
148
150
skb_index = GET_VAL (USERINFO , le64_to_cpu (raw_desc -> m0 ));
149
151
skb = cp_ring -> cp_skb [skb_index ];
@@ -160,6 +162,13 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
160
162
DMA_TO_DEVICE );
161
163
}
162
164
165
+ if (GET_BIT (ET , le64_to_cpu (raw_desc -> m3 ))) {
166
+ mss_index = GET_VAL (MSS , le64_to_cpu (raw_desc -> m3 ));
167
+ spin_lock (& pdata -> mss_lock );
168
+ pdata -> mss_refcnt [mss_index ]-- ;
169
+ spin_unlock (& pdata -> mss_lock );
170
+ }
171
+
163
172
/* Checking for error */
164
173
status = GET_VAL (LERR , le64_to_cpu (raw_desc -> m0 ));
165
174
if (unlikely (status > 2 )) {
@@ -178,15 +187,53 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
178
187
return ret ;
179
188
}
180
189
181
- static u64 xgene_enet_work_msg (struct sk_buff * skb )
190
+ static int xgene_enet_setup_mss (struct net_device * ndev , u32 mss )
191
+ {
192
+ struct xgene_enet_pdata * pdata = netdev_priv (ndev );
193
+ bool mss_index_found = false;
194
+ int mss_index ;
195
+ int i ;
196
+
197
+ spin_lock (& pdata -> mss_lock );
198
+
199
+ /* Reuse the slot if MSS matches */
200
+ for (i = 0 ; !mss_index_found && i < NUM_MSS_REG ; i ++ ) {
201
+ if (pdata -> mss [i ] == mss ) {
202
+ pdata -> mss_refcnt [i ]++ ;
203
+ mss_index = i ;
204
+ mss_index_found = true;
205
+ }
206
+ }
207
+
208
+ /* Overwrite the slot with ref_count = 0 */
209
+ for (i = 0 ; !mss_index_found && i < NUM_MSS_REG ; i ++ ) {
210
+ if (!pdata -> mss_refcnt [i ]) {
211
+ pdata -> mss_refcnt [i ]++ ;
212
+ pdata -> mac_ops -> set_mss (pdata , mss , i );
213
+ pdata -> mss [i ] = mss ;
214
+ mss_index = i ;
215
+ mss_index_found = true;
216
+ }
217
+ }
218
+
219
+ spin_unlock (& pdata -> mss_lock );
220
+
221
+ /* No slots with ref_count = 0 available, return busy */
222
+ if (!mss_index_found )
223
+ return - EBUSY ;
224
+
225
+ return mss_index ;
226
+ }
227
+
228
+ static int xgene_enet_work_msg (struct sk_buff * skb , u64 * hopinfo )
182
229
{
183
230
struct net_device * ndev = skb -> dev ;
184
231
struct iphdr * iph ;
185
232
u8 l3hlen = 0 , l4hlen = 0 ;
186
233
u8 ethhdr , proto = 0 , csum_enable = 0 ;
187
- u64 hopinfo = 0 ;
188
234
u32 hdr_len , mss = 0 ;
189
235
u32 i , len , nr_frags ;
236
+ int mss_index ;
190
237
191
238
ethhdr = xgene_enet_hdr_len (skb -> data );
192
239
@@ -226,23 +273,27 @@ static u64 xgene_enet_work_msg(struct sk_buff *skb)
226
273
if (!mss || ((skb -> len - hdr_len ) <= mss ))
227
274
goto out ;
228
275
229
- hopinfo |= SET_BIT (ET );
276
+ mss_index = xgene_enet_setup_mss (ndev , mss );
277
+ if (unlikely (mss_index < 0 ))
278
+ return - EBUSY ;
279
+
280
+ * hopinfo |= SET_BIT (ET ) | SET_VAL (MSS , mss_index );
230
281
}
231
282
} else if (iph -> protocol == IPPROTO_UDP ) {
232
283
l4hlen = UDP_HDR_SIZE ;
233
284
csum_enable = 1 ;
234
285
}
235
286
out :
236
287
l3hlen = ip_hdrlen (skb ) >> 2 ;
237
- hopinfo |= SET_VAL (TCPHDR , l4hlen ) |
238
- SET_VAL (IPHDR , l3hlen ) |
239
- SET_VAL (ETHHDR , ethhdr ) |
240
- SET_VAL (EC , csum_enable ) |
241
- SET_VAL (IS , proto ) |
242
- SET_BIT (IC ) |
243
- SET_BIT (TYPE_ETH_WORK_MESSAGE );
244
-
245
- return hopinfo ;
288
+ * hopinfo |= SET_VAL (TCPHDR , l4hlen ) |
289
+ SET_VAL (IPHDR , l3hlen ) |
290
+ SET_VAL (ETHHDR , ethhdr ) |
291
+ SET_VAL (EC , csum_enable ) |
292
+ SET_VAL (IS , proto ) |
293
+ SET_BIT (IC ) |
294
+ SET_BIT (TYPE_ETH_WORK_MESSAGE );
295
+
296
+ return 0 ;
246
297
}
247
298
248
299
static u16 xgene_enet_encode_len (u16 len )
@@ -282,20 +333,22 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
282
333
dma_addr_t dma_addr , pbuf_addr , * frag_dma_addr ;
283
334
skb_frag_t * frag ;
284
335
u16 tail = tx_ring -> tail ;
285
- u64 hopinfo ;
336
+ u64 hopinfo = 0 ;
286
337
u32 len , hw_len ;
287
338
u8 ll = 0 , nv = 0 , idx = 0 ;
288
339
bool split = false;
289
340
u32 size , offset , ell_bytes = 0 ;
290
341
u32 i , fidx , nr_frags , count = 1 ;
342
+ int ret ;
291
343
292
344
raw_desc = & tx_ring -> raw_desc [tail ];
293
345
tail = (tail + 1 ) & (tx_ring -> slots - 1 );
294
346
memset (raw_desc , 0 , sizeof (struct xgene_enet_raw_desc ));
295
347
296
- hopinfo = xgene_enet_work_msg (skb );
297
- if (!hopinfo )
298
- return - EINVAL ;
348
+ ret = xgene_enet_work_msg (skb , & hopinfo );
349
+ if (ret )
350
+ return ret ;
351
+
299
352
raw_desc -> m3 = cpu_to_le64 (SET_VAL (HENQNUM , tx_ring -> dst_ring_num ) |
300
353
hopinfo );
301
354
@@ -435,6 +488,9 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
435
488
return NETDEV_TX_OK ;
436
489
437
490
count = xgene_enet_setup_tx_desc (tx_ring , skb );
491
+ if (count == - EBUSY )
492
+ return NETDEV_TX_BUSY ;
493
+
438
494
if (count <= 0 ) {
439
495
dev_kfree_skb_any (skb );
440
496
return NETDEV_TX_OK ;
@@ -1669,7 +1725,7 @@ static int xgene_enet_probe(struct platform_device *pdev)
1669
1725
1670
1726
if (pdata -> phy_mode == PHY_INTERFACE_MODE_XGMII ) {
1671
1727
ndev -> features |= NETIF_F_TSO ;
1672
- pdata -> mss = XGENE_ENET_MSS ;
1728
+ spin_lock_init ( & pdata -> mss_lock ) ;
1673
1729
}
1674
1730
ndev -> hw_features = ndev -> features ;
1675
1731
0 commit comments