@@ -227,6 +227,7 @@ struct virtnet_info {
227227
228228 /* Host supports rss and/or hash report */
229229 bool has_rss ;
230+ bool has_rss_hash_report ;
230231 u8 rss_key_size ;
231232 u16 rss_indir_table_size ;
232233 u32 rss_hash_types_supported ;
@@ -1148,6 +1149,35 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
11481149 return NULL ;
11491150}
11501151
1152+ static void virtio_skb_set_hash (const struct virtio_net_hdr_v1_hash * hdr_hash ,
1153+ struct sk_buff * skb )
1154+ {
1155+ enum pkt_hash_types rss_hash_type ;
1156+
1157+ if (!hdr_hash || !skb )
1158+ return ;
1159+
1160+ switch ((int )hdr_hash -> hash_report ) {
1161+ case VIRTIO_NET_HASH_REPORT_TCPv4 :
1162+ case VIRTIO_NET_HASH_REPORT_UDPv4 :
1163+ case VIRTIO_NET_HASH_REPORT_TCPv6 :
1164+ case VIRTIO_NET_HASH_REPORT_UDPv6 :
1165+ case VIRTIO_NET_HASH_REPORT_TCPv6_EX :
1166+ case VIRTIO_NET_HASH_REPORT_UDPv6_EX :
1167+ rss_hash_type = PKT_HASH_TYPE_L4 ;
1168+ break ;
1169+ case VIRTIO_NET_HASH_REPORT_IPv4 :
1170+ case VIRTIO_NET_HASH_REPORT_IPv6 :
1171+ case VIRTIO_NET_HASH_REPORT_IPv6_EX :
1172+ rss_hash_type = PKT_HASH_TYPE_L3 ;
1173+ break ;
1174+ case VIRTIO_NET_HASH_REPORT_NONE :
1175+ default :
1176+ rss_hash_type = PKT_HASH_TYPE_NONE ;
1177+ }
1178+ skb_set_hash (skb , (unsigned int )hdr_hash -> hash_value , rss_hash_type );
1179+ }
1180+
11511181static void receive_buf (struct virtnet_info * vi , struct receive_queue * rq ,
11521182 void * buf , unsigned int len , void * * ctx ,
11531183 unsigned int * xdp_xmit ,
@@ -1182,6 +1212,8 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
11821212 return ;
11831213
11841214 hdr = skb_vnet_hdr (skb );
1215+ if (dev -> features & NETIF_F_RXHASH && vi -> has_rss_hash_report )
1216+ virtio_skb_set_hash ((const struct virtio_net_hdr_v1_hash * )hdr , skb );
11851217
11861218 if (hdr -> hdr .flags & VIRTIO_NET_HDR_F_DATA_VALID )
11871219 skb -> ip_summed = CHECKSUM_UNNECESSARY ;
@@ -2232,7 +2264,8 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi)
22322264 sg_set_buf (& sgs [3 ], vi -> ctrl -> rss .key , sg_buf_size );
22332265
22342266 if (!virtnet_send_command (vi , VIRTIO_NET_CTRL_MQ ,
2235- VIRTIO_NET_CTRL_MQ_RSS_CONFIG , sgs )) {
2267+ vi -> has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG
2268+ : VIRTIO_NET_CTRL_MQ_HASH_CONFIG , sgs )) {
22362269 dev_warn (& dev -> dev , "VIRTIONET issue with committing RSS sgs\n" );
22372270 return false;
22382271 }
@@ -3231,6 +3264,8 @@ static bool virtnet_validate_features(struct virtio_device *vdev)
32313264 VIRTNET_FAIL_ON (vdev , VIRTIO_NET_F_CTRL_MAC_ADDR ,
32323265 "VIRTIO_NET_F_CTRL_VQ" ) ||
32333266 VIRTNET_FAIL_ON (vdev , VIRTIO_NET_F_RSS ,
3267+ "VIRTIO_NET_F_CTRL_VQ" ) ||
3268+ VIRTNET_FAIL_ON (vdev , VIRTIO_NET_F_HASH_REPORT ,
32343269 "VIRTIO_NET_F_CTRL_VQ" ))) {
32353270 return false;
32363271 }
@@ -3366,8 +3401,13 @@ static int virtnet_probe(struct virtio_device *vdev)
33663401 if (virtio_has_feature (vdev , VIRTIO_NET_F_MRG_RXBUF ))
33673402 vi -> mergeable_rx_bufs = true;
33683403
3369- if (virtio_has_feature (vdev , VIRTIO_NET_F_RSS )) {
3404+ if (virtio_has_feature (vdev , VIRTIO_NET_F_HASH_REPORT ))
3405+ vi -> has_rss_hash_report = true;
3406+
3407+ if (virtio_has_feature (vdev , VIRTIO_NET_F_RSS ))
33703408 vi -> has_rss = true;
3409+
3410+ if (vi -> has_rss || vi -> has_rss_hash_report ) {
33713411 vi -> rss_indir_table_size =
33723412 virtio_cread16 (vdev , offsetof(struct virtio_net_config ,
33733413 rss_max_indirection_table_length ));
@@ -3383,8 +3423,11 @@ static int virtnet_probe(struct virtio_device *vdev)
33833423
33843424 dev -> hw_features |= NETIF_F_RXHASH ;
33853425 }
3386- if (virtio_has_feature (vdev , VIRTIO_NET_F_MRG_RXBUF ) ||
3387- virtio_has_feature (vdev , VIRTIO_F_VERSION_1 ))
3426+
3427+ if (vi -> has_rss_hash_report )
3428+ vi -> hdr_len = sizeof (struct virtio_net_hdr_v1_hash );
3429+ else if (virtio_has_feature (vdev , VIRTIO_NET_F_MRG_RXBUF ) ||
3430+ virtio_has_feature (vdev , VIRTIO_F_VERSION_1 ))
33883431 vi -> hdr_len = sizeof (struct virtio_net_hdr_mrg_rxbuf );
33893432 else
33903433 vi -> hdr_len = sizeof (struct virtio_net_hdr );
@@ -3451,7 +3494,7 @@ static int virtnet_probe(struct virtio_device *vdev)
34513494 }
34523495 }
34533496
3454- if (vi -> has_rss )
3497+ if (vi -> has_rss || vi -> has_rss_hash_report )
34553498 virtnet_init_default_rss (vi );
34563499
34573500 err = register_netdev (dev );
@@ -3586,7 +3629,7 @@ static struct virtio_device_id id_table[] = {
35863629 VIRTIO_NET_F_CTRL_MAC_ADDR, \
35873630 VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
35883631 VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \
3589- VIRTIO_NET_F_RSS
3632+ VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT
35903633
35913634static unsigned int features [] = {
35923635 VIRTNET_FEATURES ,
0 commit comments