@@ -5170,41 +5170,27 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
5170
5170
}
5171
5171
EXPORT_SYMBOL_GPL (qeth_core_hardsetup_card );
5172
5172
5173
- static int qeth_create_skb_frag (struct qeth_qdio_buffer * qethbuffer ,
5174
- struct qdio_buffer_element * element ,
5175
- struct sk_buff * * pskb , int offset , int data_len )
5173
+ static void qeth_create_skb_frag (struct qdio_buffer_element * element ,
5174
+ struct sk_buff * skb , int offset , int data_len )
5176
5175
{
5177
5176
struct page * page = virt_to_page (element -> addr );
5178
5177
unsigned int next_frag ;
5179
5178
5180
- if (* pskb == NULL ) {
5181
- if (qethbuffer -> rx_skb ) {
5182
- /* only if qeth_card.options.cq == QETH_CQ_ENABLED */
5183
- * pskb = qethbuffer -> rx_skb ;
5184
- qethbuffer -> rx_skb = NULL ;
5185
- } else {
5186
- * pskb = dev_alloc_skb (QETH_RX_PULL_LEN + ETH_HLEN );
5187
- if (!(* pskb ))
5188
- return - ENOMEM ;
5189
- }
5179
+ /* first fill the linear space */
5180
+ if (!skb -> len ) {
5181
+ unsigned int linear = min (data_len , skb_tailroom (skb ));
5190
5182
5191
- skb_reserve (* pskb , ETH_HLEN );
5192
- if (data_len <= QETH_RX_PULL_LEN ) {
5193
- skb_put_data (* pskb , element -> addr + offset , data_len );
5194
- return 0 ;
5195
- } else {
5196
- skb_put_data (* pskb , element -> addr + offset ,
5197
- QETH_RX_PULL_LEN );
5198
- data_len -= QETH_RX_PULL_LEN ;
5199
- offset += QETH_RX_PULL_LEN ;
5200
- /* fall through to add page frag for remaining data */
5201
- }
5183
+ skb_put_data (skb , element -> addr + offset , linear );
5184
+ data_len -= linear ;
5185
+ if (!data_len )
5186
+ return ;
5187
+ offset += linear ;
5188
+ /* fall through to add page frag for remaining data */
5202
5189
}
5203
5190
5204
- next_frag = skb_shinfo (* pskb )-> nr_frags ;
5191
+ next_frag = skb_shinfo (skb )-> nr_frags ;
5205
5192
get_page (page );
5206
- skb_add_rx_frag (* pskb , next_frag , page , offset , data_len , data_len );
5207
- return 0 ;
5193
+ skb_add_rx_frag (skb , next_frag , page , offset , data_len , data_len );
5208
5194
}
5209
5195
5210
5196
static inline int qeth_is_last_sbale (struct qdio_buffer_element * sbale )
@@ -5220,7 +5206,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
5220
5206
struct qdio_buffer_element * element = * __element ;
5221
5207
struct qdio_buffer * buffer = qethbuffer -> buffer ;
5222
5208
int offset = * __offset ;
5223
- struct sk_buff * skb = NULL ;
5209
+ struct sk_buff * skb ;
5224
5210
int skb_len = 0 ;
5225
5211
void * data_ptr ;
5226
5212
int data_len ;
@@ -5261,27 +5247,32 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
5261
5247
if (((skb_len >= card -> options .rx_sg_cb ) &&
5262
5248
(!(card -> info .type == QETH_CARD_TYPE_OSN )) &&
5263
5249
(!atomic_read (& card -> force_alloc_skb ))) ||
5264
- (card -> options .cq == QETH_CQ_ENABLED )) {
5250
+ (card -> options .cq == QETH_CQ_ENABLED ))
5265
5251
use_rx_sg = 1 ;
5252
+
5253
+ if (use_rx_sg && qethbuffer -> rx_skb ) {
5254
+ /* QETH_CQ_ENABLED only: */
5255
+ skb = qethbuffer -> rx_skb ;
5256
+ qethbuffer -> rx_skb = NULL ;
5266
5257
} else {
5267
- skb = dev_alloc_skb (skb_len + headroom );
5268
- if (!skb )
5269
- goto no_mem ;
5270
- if (headroom )
5271
- skb_reserve (skb , headroom );
5258
+ unsigned int linear = (use_rx_sg ) ? QETH_RX_PULL_LEN : skb_len ;
5259
+
5260
+ skb = dev_alloc_skb (linear + headroom );
5272
5261
}
5262
+ if (!skb )
5263
+ goto no_mem ;
5264
+ if (headroom )
5265
+ skb_reserve (skb , headroom );
5273
5266
5274
5267
data_ptr = element -> addr + offset ;
5275
5268
while (skb_len ) {
5276
5269
data_len = min (skb_len , (int )(element -> length - offset ));
5277
5270
if (data_len ) {
5278
- if (use_rx_sg ) {
5279
- if (qeth_create_skb_frag (qethbuffer , element ,
5280
- & skb , offset , data_len ))
5281
- goto no_mem ;
5282
- } else {
5271
+ if (use_rx_sg )
5272
+ qeth_create_skb_frag (element , skb , offset ,
5273
+ data_len );
5274
+ else
5283
5275
skb_put_data (skb , data_ptr , data_len );
5284
- }
5285
5276
}
5286
5277
skb_len -= data_len ;
5287
5278
if (skb_len ) {
0 commit comments