@@ -2050,6 +2050,12 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
20502050 hdr -> hdr .l3 .vlan_id = skb_vlan_tag_get (skb );
20512051 }
20522052
2053+ if (!skb_is_gso (skb ) && skb -> ip_summed == CHECKSUM_PARTIAL ) {
2054+ qeth_tx_csum (skb , & hdr -> hdr .l3 .ext_flags , ipv );
2055+ if (card -> options .performance_stats )
2056+ card -> perf_stats .tx_csum ++ ;
2057+ }
2058+
20532059 /* OSA only: */
20542060 if (!ipv ) {
20552061 hdr -> hdr .l3 .flags = QETH_HDR_PASSTHRU ;
@@ -2164,8 +2170,8 @@ static int qeth_l3_xmit_offload(struct qeth_card *card, struct sk_buff *skb,
21642170 unsigned char eth_hdr [ETH_HLEN ];
21652171 unsigned int hdr_elements = 0 ;
21662172 struct qeth_hdr * hdr = NULL ;
2173+ int elements , push_len , rc ;
21672174 unsigned int hd_len = 0 ;
2168- int push_len , rc ;
21692175
21702176 /* compress skb to fit into one IO buffer: */
21712177 if (!qeth_get_elements_no (card , skb , 0 , 0 )) {
@@ -2199,17 +2205,26 @@ static int qeth_l3_xmit_offload(struct qeth_card *card, struct sk_buff *skb,
21992205 hdr_elements = 1 ;
22002206 }
22012207
2202- if (!qeth_get_elements_no (card , skb , hdr_elements , 0 )) {
2208+ elements = qeth_get_elements_no (card , skb , hdr_elements , 0 );
2209+ if (!elements ) {
22032210 rc = - E2BIG ;
22042211 goto out ;
22052212 }
2213+ elements += hdr_elements ;
22062214
22072215 if (skb -> protocol == htons (ETH_P_AF_IUCV ))
22082216 qeth_l3_fill_af_iucv_hdr (hdr , skb , frame_len );
22092217 else
22102218 qeth_l3_fill_header (card , hdr , skb , ipv , cast_type , frame_len );
22112219
2212- rc = qeth_do_send_packet_fast (queue , skb , hdr , 0 , hd_len );
2220+ if (IS_IQD (card )) {
2221+ rc = qeth_do_send_packet_fast (queue , skb , hdr , 0 , hd_len );
2222+ } else {
2223+ /* TODO: drop skb_orphan() once TX completion is fast enough */
2224+ skb_orphan (skb );
2225+ rc = qeth_do_send_packet (card , queue , skb , hdr , 0 , hd_len ,
2226+ elements );
2227+ }
22132228out :
22142229 if (!rc ) {
22152230 if (card -> options .performance_stats && nr_frags ) {
@@ -2295,12 +2310,6 @@ static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb,
22952310 hdr = skb_push (new_skb , sizeof (struct qeth_hdr ));
22962311 qeth_l3_fill_header (card , hdr , new_skb , ipv , cast_type ,
22972312 new_skb -> len - sizeof (struct qeth_hdr ));
2298-
2299- if (new_skb -> ip_summed == CHECKSUM_PARTIAL ) {
2300- qeth_tx_csum (new_skb , & hdr -> hdr .l3 .ext_flags , ipv );
2301- if (card -> options .performance_stats )
2302- card -> perf_stats .tx_csum ++ ;
2303- }
23042313 }
23052314
23062315 elements = use_tso ?
@@ -2384,7 +2393,7 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb,
23842393 }
23852394 netif_stop_queue (dev );
23862395
2387- if (IS_IQD (card ))
2396+ if (IS_IQD (card ) || (! skb_is_gso ( skb ) && ipv == 4 ) )
23882397 rc = qeth_l3_xmit_offload (card , skb , queue , ipv , cast_type );
23892398 else
23902399 rc = qeth_l3_xmit (card , skb , queue , ipv , cast_type );
@@ -2563,9 +2572,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
25632572 if (!card -> dev )
25642573 return - ENODEV ;
25652574 card -> dev -> flags |= IFF_NOARP ;
2566- card -> dev -> priv_flags &= ~IFF_TX_SKB_SHARING ;
25672575 card -> dev -> netdev_ops = & qeth_l3_netdev_ops ;
2568- card -> dev -> needed_headroom = sizeof (struct qeth_hdr ) - ETH_HLEN ;
25692576
25702577 rc = qeth_l3_iqd_read_initial_mac (card );
25712578 if (rc )
@@ -2582,6 +2589,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
25822589 card -> dev -> max_mtu = ETH_MAX_MTU ;
25832590 card -> dev -> dev_port = card -> info .portno ;
25842591 card -> dev -> ethtool_ops = & qeth_l3_ethtool_ops ;
2592+ card -> dev -> priv_flags &= ~IFF_TX_SKB_SHARING ;
2593+ card -> dev -> needed_headroom = sizeof (struct qeth_hdr ) - ETH_HLEN ;
25852594 card -> dev -> features |= NETIF_F_HW_VLAN_CTAG_TX |
25862595 NETIF_F_HW_VLAN_CTAG_RX |
25872596 NETIF_F_HW_VLAN_CTAG_FILTER ;
0 commit comments