@@ -897,6 +897,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
897
897
.get_strings = ibmveth_get_strings ,
898
898
.get_sset_count = ibmveth_get_sset_count ,
899
899
.get_ethtool_stats = ibmveth_get_ethtool_stats ,
900
+ .set_sg = ethtool_op_set_sg ,
900
901
};
901
902
902
903
static int ibmveth_ioctl (struct net_device * dev , struct ifreq * ifr , int cmd )
@@ -906,96 +907,158 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
906
907
907
908
#define page_offset (v ) ((unsigned long)(v) & ((1 << 12) - 1))
908
909
909
- static netdev_tx_t ibmveth_start_xmit (struct sk_buff * skb ,
910
- struct net_device * netdev )
910
+ static int ibmveth_send (struct ibmveth_adapter * adapter ,
911
+ union ibmveth_buf_desc * descs )
911
912
{
912
- struct ibmveth_adapter * adapter = netdev_priv (netdev );
913
- union ibmveth_buf_desc desc ;
914
- unsigned long lpar_rc ;
915
913
unsigned long correlator ;
916
914
unsigned int retry_count ;
917
- unsigned int tx_dropped = 0 ;
918
- unsigned int tx_bytes = 0 ;
919
- unsigned int tx_packets = 0 ;
920
- unsigned int tx_send_failed = 0 ;
921
- unsigned int tx_map_failed = 0 ;
922
- int used_bounce = 0 ;
923
- unsigned long data_dma_addr ;
915
+ unsigned long ret ;
916
+
917
+ /*
918
+ * The retry count sets a maximum for the number of broadcast and
919
+ * multicast destinations within the system.
920
+ */
921
+ retry_count = 1024 ;
922
+ correlator = 0 ;
923
+ do {
924
+ ret = h_send_logical_lan (adapter -> vdev -> unit_address ,
925
+ descs [0 ].desc , descs [1 ].desc ,
926
+ descs [2 ].desc , descs [3 ].desc ,
927
+ descs [4 ].desc , descs [5 ].desc ,
928
+ correlator , & correlator );
929
+ } while ((ret == H_BUSY ) && (retry_count -- ));
930
+
931
+ if (ret != H_SUCCESS && ret != H_DROPPED ) {
932
+ ibmveth_error_printk ("tx: h_send_logical_lan failed with "
933
+ "rc=%ld\n" , ret );
934
+ return 1 ;
935
+ }
936
+
937
+ return 0 ;
938
+ }
924
939
925
- desc .fields .flags_len = IBMVETH_BUF_VALID | skb -> len ;
940
+ static netdev_tx_t ibmveth_start_xmit (struct sk_buff * skb ,
941
+ struct net_device * netdev )
942
+ {
943
+ struct ibmveth_adapter * adapter = netdev_priv (netdev );
944
+ unsigned int desc_flags ;
945
+ union ibmveth_buf_desc descs [6 ];
946
+ int last , i ;
947
+ int force_bounce = 0 ;
948
+
949
+ /*
950
+ * veth handles a maximum of 6 segments including the header, so
951
+ * we have to linearize the skb if there are more than this.
952
+ */
953
+ if (skb_shinfo (skb )-> nr_frags > 5 && __skb_linearize (skb )) {
954
+ netdev -> stats .tx_dropped ++ ;
955
+ goto out ;
956
+ }
926
957
958
+ /* veth can't checksum offload UDP */
927
959
if (skb -> ip_summed == CHECKSUM_PARTIAL &&
928
960
ip_hdr (skb )-> protocol != IPPROTO_TCP && skb_checksum_help (skb )) {
929
961
ibmveth_error_printk ("tx: failed to checksum packet\n" );
930
- tx_dropped ++ ;
962
+ netdev -> stats . tx_dropped ++ ;
931
963
goto out ;
932
964
}
933
965
966
+ desc_flags = IBMVETH_BUF_VALID ;
967
+
934
968
if (skb -> ip_summed == CHECKSUM_PARTIAL ) {
935
- unsigned char * buf = skb_transport_header (skb ) + skb -> csum_offset ;
969
+ unsigned char * buf = skb_transport_header (skb ) +
970
+ skb -> csum_offset ;
936
971
937
- desc . fields . flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD );
972
+ desc_flags |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD );
938
973
939
974
/* Need to zero out the checksum */
940
975
buf [0 ] = 0 ;
941
976
buf [1 ] = 0 ;
942
977
}
943
978
944
- if (skb -> len < tx_copybreak ) {
945
- used_bounce = 1 ;
946
- } else {
947
- data_dma_addr = dma_map_single (& adapter -> vdev -> dev , skb -> data ,
948
- skb -> len , DMA_TO_DEVICE );
949
- if (dma_mapping_error (& adapter -> vdev -> dev , data_dma_addr )) {
950
- if (!firmware_has_feature (FW_FEATURE_CMO ))
951
- ibmveth_error_printk ("tx: unable to map "
952
- "xmit buffer\n" );
953
- tx_map_failed ++ ;
954
- used_bounce = 1 ;
955
- }
956
- }
979
+ retry_bounce :
980
+ memset (descs , 0 , sizeof (descs ));
957
981
958
- if (used_bounce ) {
982
+ /*
983
+ * If a linear packet is below the rx threshold then
984
+ * copy it into the static bounce buffer. This avoids the
985
+ * cost of a TCE insert and remove.
986
+ */
987
+ if (force_bounce || (!skb_is_nonlinear (skb ) &&
988
+ (skb -> len < tx_copybreak ))) {
959
989
skb_copy_from_linear_data (skb , adapter -> bounce_buffer ,
960
990
skb -> len );
961
- desc .fields .address = adapter -> bounce_buffer_dma ;
962
- } else
963
- desc .fields .address = data_dma_addr ;
964
991
965
- /* send the frame. Arbitrarily set retrycount to 1024 */
966
- correlator = 0 ;
967
- retry_count = 1024 ;
968
- do {
969
- lpar_rc = h_send_logical_lan (adapter -> vdev -> unit_address ,
970
- desc .desc , 0 , 0 , 0 , 0 , 0 ,
971
- correlator , & correlator );
972
- } while ((lpar_rc == H_BUSY ) && (retry_count -- ));
973
-
974
- if (lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED ) {
975
- ibmveth_error_printk ("tx: h_send_logical_lan failed with rc=%ld\n" , lpar_rc );
976
- ibmveth_error_printk ("tx: valid=%d, len=%d, address=0x%08x\n" ,
977
- (desc .fields .flags_len & IBMVETH_BUF_VALID ) ? 1 : 0 ,
978
- skb -> len , desc .fields .address );
979
- tx_send_failed ++ ;
980
- tx_dropped ++ ;
992
+ descs [0 ].fields .flags_len = desc_flags | skb -> len ;
993
+ descs [0 ].fields .address = adapter -> bounce_buffer_dma ;
994
+
995
+ if (ibmveth_send (adapter , descs )) {
996
+ adapter -> tx_send_failed ++ ;
997
+ netdev -> stats .tx_dropped ++ ;
998
+ } else {
999
+ netdev -> stats .tx_packets ++ ;
1000
+ netdev -> stats .tx_bytes += skb -> len ;
1001
+ }
1002
+
1003
+ goto out ;
1004
+ }
1005
+
1006
+ /* Map the header */
1007
+ descs [0 ].fields .address = dma_map_single (& adapter -> vdev -> dev , skb -> data ,
1008
+ skb_headlen (skb ),
1009
+ DMA_TO_DEVICE );
1010
+ if (dma_mapping_error (& adapter -> vdev -> dev , descs [0 ].fields .address ))
1011
+ goto map_failed ;
1012
+
1013
+ descs [0 ].fields .flags_len = desc_flags | skb_headlen (skb );
1014
+
1015
+ /* Map the frags */
1016
+ for (i = 0 ; i < skb_shinfo (skb )-> nr_frags ; i ++ ) {
1017
+ unsigned long dma_addr ;
1018
+ skb_frag_t * frag = & skb_shinfo (skb )-> frags [i ];
1019
+
1020
+ dma_addr = dma_map_page (& adapter -> vdev -> dev , frag -> page ,
1021
+ frag -> page_offset , frag -> size ,
1022
+ DMA_TO_DEVICE );
1023
+
1024
+ if (dma_mapping_error (& adapter -> vdev -> dev , dma_addr ))
1025
+ goto map_failed_frags ;
1026
+
1027
+ descs [i + 1 ].fields .flags_len = desc_flags | frag -> size ;
1028
+ descs [i + 1 ].fields .address = dma_addr ;
1029
+ }
1030
+
1031
+ if (ibmveth_send (adapter , descs )) {
1032
+ adapter -> tx_send_failed ++ ;
1033
+ netdev -> stats .tx_dropped ++ ;
981
1034
} else {
982
- tx_packets ++ ;
983
- tx_bytes += skb -> len ;
1035
+ netdev -> stats . tx_packets ++ ;
1036
+ netdev -> stats . tx_bytes += skb -> len ;
984
1037
}
985
1038
986
- if (!used_bounce )
987
- dma_unmap_single (& adapter -> vdev -> dev , data_dma_addr ,
988
- skb -> len , DMA_TO_DEVICE );
1039
+ for (i = 0 ; i < skb_shinfo (skb )-> nr_frags + 1 ; i ++ )
1040
+ dma_unmap_page (& adapter -> vdev -> dev , descs [i ].fields .address ,
1041
+ descs [i ].fields .flags_len & IBMVETH_BUF_LEN_MASK ,
1042
+ DMA_TO_DEVICE );
989
1043
990
1044
out :
991
- netdev -> stats .tx_dropped += tx_dropped ;
992
- netdev -> stats .tx_bytes += tx_bytes ;
993
- netdev -> stats .tx_packets += tx_packets ;
994
- adapter -> tx_send_failed += tx_send_failed ;
995
- adapter -> tx_map_failed += tx_map_failed ;
996
-
997
1045
dev_kfree_skb (skb );
998
1046
return NETDEV_TX_OK ;
1047
+
1048
+ map_failed_frags :
1049
+ last = i + 1 ;
1050
+ for (i = 0 ; i < last ; i ++ )
1051
+ dma_unmap_page (& adapter -> vdev -> dev , descs [i ].fields .address ,
1052
+ descs [i ].fields .flags_len & IBMVETH_BUF_LEN_MASK ,
1053
+ DMA_TO_DEVICE );
1054
+
1055
+ map_failed :
1056
+ if (!firmware_has_feature (FW_FEATURE_CMO ))
1057
+ ibmveth_error_printk ("tx: unable to map xmit buffer\n" );
1058
+ adapter -> tx_map_failed ++ ;
1059
+ skb_linearize (skb );
1060
+ force_bounce = 1 ;
1061
+ goto retry_bounce ;
999
1062
}
1000
1063
1001
1064
static int ibmveth_poll (struct napi_struct * napi , int budget )
@@ -1316,6 +1379,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
1316
1379
netdev -> netdev_ops = & ibmveth_netdev_ops ;
1317
1380
netdev -> ethtool_ops = & netdev_ethtool_ops ;
1318
1381
SET_NETDEV_DEV (netdev , & dev -> dev );
1382
+ netdev -> features |= NETIF_F_SG ;
1319
1383
1320
1384
memcpy (netdev -> dev_addr , & adapter -> mac_addr , netdev -> addr_len );
1321
1385
0 commit comments