@@ -52,7 +52,6 @@ EXPORT_SYMBOL_GPL(qeth_core_header_cache);
52
52
static struct kmem_cache * qeth_qdio_outbuf_cache ;
53
53
54
54
static struct device * qeth_core_root_dev ;
55
- static unsigned int known_devices [][6 ] = QETH_MODELLIST_ARRAY ;
56
55
static struct lock_class_key qdio_out_skb_queue_key ;
57
56
static struct mutex qeth_mod_mutex ;
58
57
@@ -1386,6 +1385,7 @@ static void qeth_init_qdio_info(struct qeth_card *card)
1386
1385
QETH_DBF_TEXT (SETUP , 4 , "intqdinf" );
1387
1386
atomic_set (& card -> qdio .state , QETH_QDIO_UNINITIALIZED );
1388
1387
/* inbound */
1388
+ card -> qdio .no_in_queues = 1 ;
1389
1389
card -> qdio .in_buf_size = QETH_IN_BUF_SIZE_DEFAULT ;
1390
1390
if (card -> info .type == QETH_CARD_TYPE_IQD )
1391
1391
card -> qdio .init_pool .buf_count = QETH_IN_BUF_COUNT_HSDEFAULT ;
@@ -1519,34 +1519,17 @@ static struct qeth_card *qeth_alloc_card(void)
1519
1519
return NULL ;
1520
1520
}
1521
1521
1522
- static int qeth_determine_card_type (struct qeth_card * card )
1522
+ static void qeth_determine_card_type (struct qeth_card * card )
1523
1523
{
1524
- int i = 0 ;
1525
-
1526
1524
QETH_DBF_TEXT (SETUP , 2 , "detcdtyp" );
1527
1525
1528
1526
card -> qdio .do_prio_queueing = QETH_PRIOQ_DEFAULT ;
1529
1527
card -> qdio .default_out_queue = QETH_DEFAULT_QUEUE ;
1530
- while (known_devices [i ][QETH_DEV_MODEL_IND ]) {
1531
- if ((CARD_RDEV (card )-> id .dev_type ==
1532
- known_devices [i ][QETH_DEV_TYPE_IND ]) &&
1533
- (CARD_RDEV (card )-> id .dev_model ==
1534
- known_devices [i ][QETH_DEV_MODEL_IND ])) {
1535
- card -> info .type = known_devices [i ][QETH_DEV_MODEL_IND ];
1536
- card -> qdio .no_out_queues =
1537
- known_devices [i ][QETH_QUEUE_NO_IND ];
1538
- card -> qdio .no_in_queues = 1 ;
1539
- card -> info .is_multicast_different =
1540
- known_devices [i ][QETH_MULTICAST_IND ];
1541
- qeth_update_from_chp_desc (card );
1542
- return 0 ;
1543
- }
1544
- i ++ ;
1545
- }
1546
- card -> info .type = QETH_CARD_TYPE_UNKNOWN ;
1547
- dev_err (& card -> gdev -> dev , "The adapter hardware is of an "
1548
- "unknown type\n" );
1549
- return - ENOENT ;
1528
+ card -> info .type = CARD_RDEV (card )-> id .driver_info ;
1529
+ card -> qdio .no_out_queues = QETH_MAX_QUEUES ;
1530
+ if (card -> info .type == QETH_CARD_TYPE_IQD )
1531
+ card -> info .is_multicast_different = 0x0103 ;
1532
+ qeth_update_from_chp_desc (card );
1550
1533
}
1551
1534
1552
1535
static int qeth_clear_channel (struct qeth_channel * channel )
@@ -2090,7 +2073,6 @@ int qeth_send_control_data(struct qeth_card *card, int len,
2090
2073
spin_lock_irqsave (& card -> lock , flags );
2091
2074
list_add_tail (& reply -> list , & card -> cmd_waiter_list );
2092
2075
spin_unlock_irqrestore (& card -> lock , flags );
2093
- QETH_DBF_HEX (CTRL , 2 , iob -> data , QETH_DBF_CTRL_LEN );
2094
2076
2095
2077
while (atomic_cmpxchg (& card -> write .irq_pending , 0 , 1 )) ;
2096
2078
qeth_prepare_control_data (card , len , iob );
@@ -2233,23 +2215,15 @@ static int qeth_cm_setup(struct qeth_card *card)
2233
2215
static int qeth_get_initial_mtu_for_card (struct qeth_card * card )
2234
2216
{
2235
2217
switch (card -> info .type ) {
2236
- case QETH_CARD_TYPE_UNKNOWN :
2237
- return 1500 ;
2238
2218
case QETH_CARD_TYPE_IQD :
2239
2219
return card -> info .max_mtu ;
2240
2220
case QETH_CARD_TYPE_OSD :
2241
- switch (card -> info .link_type ) {
2242
- case QETH_LINK_TYPE_HSTR :
2243
- case QETH_LINK_TYPE_LANE_TR :
2244
- return 2000 ;
2245
- default :
2246
- return card -> options .layer2 ? 1500 : 1492 ;
2247
- }
2248
- case QETH_CARD_TYPE_OSM :
2249
2221
case QETH_CARD_TYPE_OSX :
2250
- return card -> options .layer2 ? 1500 : 1492 ;
2222
+ if (!card -> options .layer2 )
2223
+ return ETH_DATA_LEN - 8 ; /* L3: allow for LLC + SNAP */
2224
+ /* fall through */
2251
2225
default :
2252
- return 1500 ;
2226
+ return ETH_DATA_LEN ;
2253
2227
}
2254
2228
}
2255
2229
@@ -2279,7 +2253,6 @@ static int qeth_mtu_is_valid(struct qeth_card *card, int mtu)
2279
2253
return ((mtu >= 576 ) &&
2280
2254
(mtu <= card -> info .max_mtu ));
2281
2255
case QETH_CARD_TYPE_OSN :
2282
- case QETH_CARD_TYPE_UNKNOWN :
2283
2256
default :
2284
2257
return 1 ;
2285
2258
}
@@ -5196,49 +5169,27 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
5196
5169
}
5197
5170
EXPORT_SYMBOL_GPL (qeth_core_hardsetup_card );
5198
5171
5199
- static int qeth_create_skb_frag (struct qeth_qdio_buffer * qethbuffer ,
5200
- struct qdio_buffer_element * element ,
5201
- struct sk_buff * * pskb , int offset , int * pfrag ,
5202
- int data_len )
5172
+ static void qeth_create_skb_frag (struct qdio_buffer_element * element ,
5173
+ struct sk_buff * skb , int offset , int data_len )
5203
5174
{
5204
5175
struct page * page = virt_to_page (element -> addr );
5205
- if (* pskb == NULL ) {
5206
- if (qethbuffer -> rx_skb ) {
5207
- /* only if qeth_card.options.cq == QETH_CQ_ENABLED */
5208
- * pskb = qethbuffer -> rx_skb ;
5209
- qethbuffer -> rx_skb = NULL ;
5210
- } else {
5211
- * pskb = dev_alloc_skb (QETH_RX_PULL_LEN + ETH_HLEN );
5212
- if (!(* pskb ))
5213
- return - ENOMEM ;
5214
- }
5176
+ unsigned int next_frag ;
5215
5177
5216
- skb_reserve (* pskb , ETH_HLEN );
5217
- if (data_len <= QETH_RX_PULL_LEN ) {
5218
- skb_put_data (* pskb , element -> addr + offset , data_len );
5219
- } else {
5220
- get_page (page );
5221
- skb_put_data (* pskb , element -> addr + offset ,
5222
- QETH_RX_PULL_LEN );
5223
- skb_fill_page_desc (* pskb , * pfrag , page ,
5224
- offset + QETH_RX_PULL_LEN ,
5225
- data_len - QETH_RX_PULL_LEN );
5226
- (* pskb )-> data_len += data_len - QETH_RX_PULL_LEN ;
5227
- (* pskb )-> len += data_len - QETH_RX_PULL_LEN ;
5228
- (* pskb )-> truesize += data_len - QETH_RX_PULL_LEN ;
5229
- (* pfrag )++ ;
5230
- }
5231
- } else {
5232
- get_page (page );
5233
- skb_fill_page_desc (* pskb , * pfrag , page , offset , data_len );
5234
- (* pskb )-> data_len += data_len ;
5235
- (* pskb )-> len += data_len ;
5236
- (* pskb )-> truesize += data_len ;
5237
- (* pfrag )++ ;
5238
- }
5178
+ /* first fill the linear space */
5179
+ if (!skb -> len ) {
5180
+ unsigned int linear = min (data_len , skb_tailroom (skb ));
5239
5181
5182
+ skb_put_data (skb , element -> addr + offset , linear );
5183
+ data_len -= linear ;
5184
+ if (!data_len )
5185
+ return ;
5186
+ offset += linear ;
5187
+ /* fall through to add page frag for remaining data */
5188
+ }
5240
5189
5241
- return 0 ;
5190
+ next_frag = skb_shinfo (skb )-> nr_frags ;
5191
+ get_page (page );
5192
+ skb_add_rx_frag (skb , next_frag , page , offset , data_len , data_len );
5242
5193
}
5243
5194
5244
5195
static inline int qeth_is_last_sbale (struct qdio_buffer_element * sbale )
@@ -5254,22 +5205,19 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
5254
5205
struct qdio_buffer_element * element = * __element ;
5255
5206
struct qdio_buffer * buffer = qethbuffer -> buffer ;
5256
5207
int offset = * __offset ;
5257
- struct sk_buff * skb = NULL ;
5208
+ struct sk_buff * skb ;
5258
5209
int skb_len = 0 ;
5259
5210
void * data_ptr ;
5260
5211
int data_len ;
5261
5212
int headroom = 0 ;
5262
5213
int use_rx_sg = 0 ;
5263
- int frag = 0 ;
5264
5214
5265
5215
/* qeth_hdr must not cross element boundaries */
5266
- if (element -> length < offset + sizeof (struct qeth_hdr )) {
5216
+ while (element -> length < offset + sizeof (struct qeth_hdr )) {
5267
5217
if (qeth_is_last_sbale (element ))
5268
5218
return NULL ;
5269
5219
element ++ ;
5270
5220
offset = 0 ;
5271
- if (element -> length < sizeof (struct qeth_hdr ))
5272
- return NULL ;
5273
5221
}
5274
5222
* hdr = element -> addr + offset ;
5275
5223
@@ -5296,27 +5244,32 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
5296
5244
if (((skb_len >= card -> options .rx_sg_cb ) &&
5297
5245
(!(card -> info .type == QETH_CARD_TYPE_OSN )) &&
5298
5246
(!atomic_read (& card -> force_alloc_skb ))) ||
5299
- (card -> options .cq == QETH_CQ_ENABLED )) {
5247
+ (card -> options .cq == QETH_CQ_ENABLED ))
5300
5248
use_rx_sg = 1 ;
5249
+
5250
+ if (use_rx_sg && qethbuffer -> rx_skb ) {
5251
+ /* QETH_CQ_ENABLED only: */
5252
+ skb = qethbuffer -> rx_skb ;
5253
+ qethbuffer -> rx_skb = NULL ;
5301
5254
} else {
5302
- skb = dev_alloc_skb (skb_len + headroom );
5303
- if (!skb )
5304
- goto no_mem ;
5305
- if (headroom )
5306
- skb_reserve (skb , headroom );
5255
+ unsigned int linear = (use_rx_sg ) ? QETH_RX_PULL_LEN : skb_len ;
5256
+
5257
+ skb = dev_alloc_skb (linear + headroom );
5307
5258
}
5259
+ if (!skb )
5260
+ goto no_mem ;
5261
+ if (headroom )
5262
+ skb_reserve (skb , headroom );
5308
5263
5309
5264
data_ptr = element -> addr + offset ;
5310
5265
while (skb_len ) {
5311
5266
data_len = min (skb_len , (int )(element -> length - offset ));
5312
5267
if (data_len ) {
5313
- if (use_rx_sg ) {
5314
- if (qeth_create_skb_frag (qethbuffer , element ,
5315
- & skb , offset , & frag , data_len ))
5316
- goto no_mem ;
5317
- } else {
5268
+ if (use_rx_sg )
5269
+ qeth_create_skb_frag (element , skb , offset ,
5270
+ data_len );
5271
+ else
5318
5272
skb_put_data (skb , data_ptr , data_len );
5319
- }
5320
5273
}
5321
5274
skb_len -= data_len ;
5322
5275
if (skb_len ) {
@@ -5416,7 +5369,7 @@ int qeth_poll(struct napi_struct *napi, int budget)
5416
5369
}
5417
5370
}
5418
5371
5419
- napi_complete (napi );
5372
+ napi_complete_done (napi , work_done );
5420
5373
if (qdio_start_irq (card -> data .ccwdev , 0 ))
5421
5374
napi_schedule (& card -> napi );
5422
5375
out :
@@ -5724,11 +5677,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
5724
5677
gdev -> cdev [1 ]-> handler = qeth_irq ;
5725
5678
gdev -> cdev [2 ]-> handler = qeth_irq ;
5726
5679
5727
- rc = qeth_determine_card_type (card );
5728
- if (rc ) {
5729
- QETH_DBF_TEXT_ (SETUP , 2 , "3err%d" , rc );
5730
- goto err_card ;
5731
- }
5680
+ qeth_determine_card_type (card );
5732
5681
rc = qeth_setup_card (card );
5733
5682
if (rc ) {
5734
5683
QETH_DBF_TEXT_ (SETUP , 2 , "2err%d" , rc );
@@ -6403,32 +6352,29 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
6403
6352
return rc ;
6404
6353
}
6405
6354
6406
- /* try to restore device features on a device after recovery */
6407
- int qeth_recover_features (struct net_device * dev )
6355
+ #define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO)
6356
+
6357
+ /**
6358
+ * qeth_recover_features() - Restore device features after recovery
6359
+ * @dev: the recovering net_device
6360
+ *
6361
+ * Caller must hold rtnl lock.
6362
+ */
6363
+ void qeth_recover_features (struct net_device * dev )
6408
6364
{
6365
+ netdev_features_t features = dev -> features ;
6409
6366
struct qeth_card * card = dev -> ml_priv ;
6410
- netdev_features_t recover = dev -> features ;
6411
6367
6412
- if (recover & NETIF_F_IP_CSUM ) {
6413
- if (qeth_set_ipa_csum (card , 1 , IPA_OUTBOUND_CHECKSUM ))
6414
- recover ^= NETIF_F_IP_CSUM ;
6415
- }
6416
- if (recover & NETIF_F_RXCSUM ) {
6417
- if (qeth_set_ipa_csum (card , 1 , IPA_INBOUND_CHECKSUM ))
6418
- recover ^= NETIF_F_RXCSUM ;
6419
- }
6420
- if (recover & NETIF_F_TSO ) {
6421
- if (qeth_set_ipa_tso (card , 1 ))
6422
- recover ^= NETIF_F_TSO ;
6423
- }
6424
-
6425
- if (recover == dev -> features )
6426
- return 0 ;
6368
+ /* force-off any feature that needs an IPA sequence.
6369
+ * netdev_update_features() will restart them.
6370
+ */
6371
+ dev -> features &= ~QETH_HW_FEATURES ;
6372
+ netdev_update_features (dev );
6427
6373
6374
+ if (features == dev -> features )
6375
+ return ;
6428
6376
dev_warn (& card -> gdev -> dev ,
6429
6377
"Device recovery failed to restore all offload features\n" );
6430
- dev -> features = recover ;
6431
- return - EIO ;
6432
6378
}
6433
6379
EXPORT_SYMBOL_GPL (qeth_recover_features );
6434
6380
@@ -6485,8 +6431,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
6485
6431
/* if the card isn't up, remove features that require hw changes */
6486
6432
if (card -> state == CARD_STATE_DOWN ||
6487
6433
card -> state == CARD_STATE_RECOVER )
6488
- features = features & ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
6489
- NETIF_F_TSO );
6434
+ features &= ~QETH_HW_FEATURES ;
6490
6435
QETH_DBF_HEX (SETUP , 2 , & features , sizeof (features ));
6491
6436
return features ;
6492
6437
}
0 commit comments