@@ -1266,6 +1266,187 @@ static void raw_packet_qp_copy_info(struct mlx5_ib_qp *qp,
12661266 rq -> doorbell = & qp -> db ;
12671267}
12681268
1269+ static void destroy_rss_raw_qp_tir (struct mlx5_ib_dev * dev , struct mlx5_ib_qp * qp )
1270+ {
1271+ mlx5_core_destroy_tir (dev -> mdev , qp -> rss_qp .tirn );
1272+ }
1273+
1274+ static int create_rss_raw_qp_tir (struct mlx5_ib_dev * dev , struct mlx5_ib_qp * qp ,
1275+ struct ib_pd * pd ,
1276+ struct ib_qp_init_attr * init_attr ,
1277+ struct ib_udata * udata )
1278+ {
1279+ struct ib_uobject * uobj = pd -> uobject ;
1280+ struct ib_ucontext * ucontext = uobj -> context ;
1281+ struct mlx5_ib_ucontext * mucontext = to_mucontext (ucontext );
1282+ struct mlx5_ib_create_qp_resp resp = {};
1283+ int inlen ;
1284+ int err ;
1285+ u32 * in ;
1286+ void * tirc ;
1287+ void * hfso ;
1288+ u32 selected_fields = 0 ;
1289+ size_t min_resp_len ;
1290+ u32 tdn = mucontext -> tdn ;
1291+ struct mlx5_ib_create_qp_rss ucmd = {};
1292+ size_t required_cmd_sz ;
1293+
1294+ if (init_attr -> qp_type != IB_QPT_RAW_PACKET )
1295+ return - EOPNOTSUPP ;
1296+
1297+ if (init_attr -> create_flags || init_attr -> send_cq )
1298+ return - EINVAL ;
1299+
1300+ min_resp_len = offsetof(typeof (resp ), uuar_index ) + sizeof (resp .uuar_index );
1301+ if (udata -> outlen < min_resp_len )
1302+ return - EINVAL ;
1303+
1304+ required_cmd_sz = offsetof(typeof (ucmd ), reserved1 ) + sizeof (ucmd .reserved1 );
1305+ if (udata -> inlen < required_cmd_sz ) {
1306+ mlx5_ib_dbg (dev , "invalid inlen\n" );
1307+ return - EINVAL ;
1308+ }
1309+
1310+ if (udata -> inlen > sizeof (ucmd ) &&
1311+ !ib_is_udata_cleared (udata , sizeof (ucmd ),
1312+ udata -> inlen - sizeof (ucmd ))) {
1313+ mlx5_ib_dbg (dev , "inlen is not supported\n" );
1314+ return - EOPNOTSUPP ;
1315+ }
1316+
1317+ if (ib_copy_from_udata (& ucmd , udata , min (sizeof (ucmd ), udata -> inlen ))) {
1318+ mlx5_ib_dbg (dev , "copy failed\n" );
1319+ return - EFAULT ;
1320+ }
1321+
1322+ if (ucmd .comp_mask ) {
1323+ mlx5_ib_dbg (dev , "invalid comp mask\n" );
1324+ return - EOPNOTSUPP ;
1325+ }
1326+
1327+ if (memchr_inv (ucmd .reserved , 0 , sizeof (ucmd .reserved )) || ucmd .reserved1 ) {
1328+ mlx5_ib_dbg (dev , "invalid reserved\n" );
1329+ return - EOPNOTSUPP ;
1330+ }
1331+
1332+ err = ib_copy_to_udata (udata , & resp , min_resp_len );
1333+ if (err ) {
1334+ mlx5_ib_dbg (dev , "copy failed\n" );
1335+ return - EINVAL ;
1336+ }
1337+
1338+ inlen = MLX5_ST_SZ_BYTES (create_tir_in );
1339+ in = mlx5_vzalloc (inlen );
1340+ if (!in )
1341+ return - ENOMEM ;
1342+
1343+ tirc = MLX5_ADDR_OF (create_tir_in , in , ctx );
1344+ MLX5_SET (tirc , tirc , disp_type ,
1345+ MLX5_TIRC_DISP_TYPE_INDIRECT );
1346+ MLX5_SET (tirc , tirc , indirect_table ,
1347+ init_attr -> rwq_ind_tbl -> ind_tbl_num );
1348+ MLX5_SET (tirc , tirc , transport_domain , tdn );
1349+
1350+ hfso = MLX5_ADDR_OF (tirc , tirc , rx_hash_field_selector_outer );
1351+ switch (ucmd .rx_hash_function ) {
1352+ case MLX5_RX_HASH_FUNC_TOEPLITZ :
1353+ {
1354+ void * rss_key = MLX5_ADDR_OF (tirc , tirc , rx_hash_toeplitz_key );
1355+ size_t len = MLX5_FLD_SZ_BYTES (tirc , rx_hash_toeplitz_key );
1356+
1357+ if (len != ucmd .rx_key_len ) {
1358+ err = - EINVAL ;
1359+ goto err ;
1360+ }
1361+
1362+ MLX5_SET (tirc , tirc , rx_hash_fn , MLX5_RX_HASH_FN_TOEPLITZ );
1363+ MLX5_SET (tirc , tirc , rx_hash_symmetric , 1 );
1364+ memcpy (rss_key , ucmd .rx_hash_key , len );
1365+ break ;
1366+ }
1367+ default :
1368+ err = - EOPNOTSUPP ;
1369+ goto err ;
1370+ }
1371+
1372+ if (!ucmd .rx_hash_fields_mask ) {
1373+ /* special case when this TIR serves as steering entry without hashing */
1374+ if (!init_attr -> rwq_ind_tbl -> log_ind_tbl_size )
1375+ goto create_tir ;
1376+ err = - EINVAL ;
1377+ goto err ;
1378+ }
1379+
1380+ if (((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4 ) ||
1381+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4 )) &&
1382+ ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6 ) ||
1383+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6 ))) {
1384+ err = - EINVAL ;
1385+ goto err ;
1386+ }
1387+
1388+ /* If none of IPV4 & IPV6 SRC/DST was set - this bit field is ignored */
1389+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4 ) ||
1390+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4 ))
1391+ MLX5_SET (rx_hash_field_select , hfso , l3_prot_type ,
1392+ MLX5_L3_PROT_TYPE_IPV4 );
1393+ else if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6 ) ||
1394+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6 ))
1395+ MLX5_SET (rx_hash_field_select , hfso , l3_prot_type ,
1396+ MLX5_L3_PROT_TYPE_IPV6 );
1397+
1398+ if (((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP ) ||
1399+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP )) &&
1400+ ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP ) ||
1401+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP ))) {
1402+ err = - EINVAL ;
1403+ goto err ;
1404+ }
1405+
1406+ /* If none of TCP & UDP SRC/DST was set - this bit field is ignored */
1407+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP ) ||
1408+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP ))
1409+ MLX5_SET (rx_hash_field_select , hfso , l4_prot_type ,
1410+ MLX5_L4_PROT_TYPE_TCP );
1411+ else if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP ) ||
1412+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP ))
1413+ MLX5_SET (rx_hash_field_select , hfso , l4_prot_type ,
1414+ MLX5_L4_PROT_TYPE_UDP );
1415+
1416+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4 ) ||
1417+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6 ))
1418+ selected_fields |= MLX5_HASH_FIELD_SEL_SRC_IP ;
1419+
1420+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4 ) ||
1421+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6 ))
1422+ selected_fields |= MLX5_HASH_FIELD_SEL_DST_IP ;
1423+
1424+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP ) ||
1425+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP ))
1426+ selected_fields |= MLX5_HASH_FIELD_SEL_L4_SPORT ;
1427+
1428+ if ((ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP ) ||
1429+ (ucmd .rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP ))
1430+ selected_fields |= MLX5_HASH_FIELD_SEL_L4_DPORT ;
1431+
1432+ MLX5_SET (rx_hash_field_select , hfso , selected_fields , selected_fields );
1433+
1434+ create_tir :
1435+ err = mlx5_core_create_tir (dev -> mdev , in , inlen , & qp -> rss_qp .tirn );
1436+
1437+ if (err )
1438+ goto err ;
1439+
1440+ kvfree (in );
1441+ /* qpn is reserved for that QP */
1442+ qp -> trans_qp .base .mqp .qpn = 0 ;
1443+ return 0 ;
1444+
1445+ err :
1446+ kvfree (in );
1447+ return err ;
1448+ }
1449+
12691450static int create_qp_common (struct mlx5_ib_dev * dev , struct ib_pd * pd ,
12701451 struct ib_qp_init_attr * init_attr ,
12711452 struct ib_udata * udata , struct mlx5_ib_qp * qp )
@@ -1292,6 +1473,14 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
12921473 spin_lock_init (& qp -> sq .lock );
12931474 spin_lock_init (& qp -> rq .lock );
12941475
1476+ if (init_attr -> rwq_ind_tbl ) {
1477+ if (!udata )
1478+ return - ENOSYS ;
1479+
1480+ err = create_rss_raw_qp_tir (dev , qp , pd , init_attr , udata );
1481+ return err ;
1482+ }
1483+
12951484 if (init_attr -> create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK ) {
12961485 if (!MLX5_CAP_GEN (mdev , block_lb_mc )) {
12971486 mlx5_ib_dbg (dev , "block multicast loopback isn't supported\n" );
@@ -1644,6 +1833,11 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
16441833 struct mlx5_modify_qp_mbox_in * in ;
16451834 int err ;
16461835
1836+ if (qp -> ibqp .rwq_ind_tbl ) {
1837+ destroy_rss_raw_qp_tir (dev , qp );
1838+ return ;
1839+ }
1840+
16471841 base = qp -> ibqp .qp_type == IB_QPT_RAW_PACKET ?
16481842 & qp -> raw_packet_qp .rq .base :
16491843 & qp -> trans_qp .base ;
@@ -2504,6 +2698,9 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
25042698 int port ;
25052699 enum rdma_link_layer ll = IB_LINK_LAYER_UNSPECIFIED ;
25062700
2701+ if (ibqp -> rwq_ind_tbl )
2702+ return - ENOSYS ;
2703+
25072704 if (unlikely (ibqp -> qp_type == IB_QPT_GSI ))
25082705 return mlx5_ib_gsi_modify_qp (ibqp , attr , attr_mask );
25092706
@@ -4119,6 +4316,9 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
41194316 int err = 0 ;
41204317 u8 raw_packet_qp_state ;
41214318
4319+ if (ibqp -> rwq_ind_tbl )
4320+ return - ENOSYS ;
4321+
41224322 if (unlikely (ibqp -> qp_type == IB_QPT_GSI ))
41234323 return mlx5_ib_gsi_query_qp (ibqp , qp_attr , qp_attr_mask ,
41244324 qp_init_attr );
0 commit comments