@@ -98,6 +98,7 @@ _qed_eth_queue_to_cid(struct qed_hwfn *p_hwfn,
9898 p_cid -> cid = cid ;
9999 p_cid -> vf_qid = vf_qid ;
100100 p_cid -> rel = * p_params ;
101+ p_cid -> p_owner = p_hwfn ;
101102
102103 /* Don't try calculating the absolute indices for VFs */
103104 if (IS_VF (p_hwfn -> cdev )) {
@@ -272,76 +273,103 @@ static int qed_sp_vport_start(struct qed_hwfn *p_hwfn,
272273static int
273274qed_sp_vport_update_rss (struct qed_hwfn * p_hwfn ,
274275 struct vport_update_ramrod_data * p_ramrod ,
275- struct qed_rss_params * p_params )
276+ struct qed_rss_params * p_rss )
276277{
277- struct eth_vport_rss_config * rss = & p_ramrod -> rss_config ;
278- u16 abs_l2_queue = 0 , capabilities = 0 ;
279- int rc = 0 , i ;
278+ struct eth_vport_rss_config * p_config ;
279+ u16 capabilities = 0 ;
280+ int i , table_size ;
281+ int rc = 0 ;
280282
281- if (!p_params ) {
283+ if (!p_rss ) {
282284 p_ramrod -> common .update_rss_flg = 0 ;
283285 return rc ;
284286 }
287+ p_config = & p_ramrod -> rss_config ;
285288
286- BUILD_BUG_ON (QED_RSS_IND_TABLE_SIZE !=
287- ETH_RSS_IND_TABLE_ENTRIES_NUM );
289+ BUILD_BUG_ON (QED_RSS_IND_TABLE_SIZE != ETH_RSS_IND_TABLE_ENTRIES_NUM );
288290
289- rc = qed_fw_rss_eng (p_hwfn , p_params -> rss_eng_id , & rss -> rss_id );
291+ rc = qed_fw_rss_eng (p_hwfn , p_rss -> rss_eng_id , & p_config -> rss_id );
290292 if (rc )
291293 return rc ;
292294
293- p_ramrod -> common .update_rss_flg = p_params -> update_rss_config ;
294- rss -> update_rss_capabilities = p_params -> update_rss_capabilities ;
295- rss -> update_rss_ind_table = p_params -> update_rss_ind_table ;
296- rss -> update_rss_key = p_params -> update_rss_key ;
295+ p_ramrod -> common .update_rss_flg = p_rss -> update_rss_config ;
296+ p_config -> update_rss_capabilities = p_rss -> update_rss_capabilities ;
297+ p_config -> update_rss_ind_table = p_rss -> update_rss_ind_table ;
298+ p_config -> update_rss_key = p_rss -> update_rss_key ;
297299
298- rss -> rss_mode = p_params -> rss_enable ?
299- ETH_VPORT_RSS_MODE_REGULAR :
300- ETH_VPORT_RSS_MODE_DISABLED ;
300+ p_config -> rss_mode = p_rss -> rss_enable ?
301+ ETH_VPORT_RSS_MODE_REGULAR :
302+ ETH_VPORT_RSS_MODE_DISABLED ;
301303
302304 SET_FIELD (capabilities ,
303305 ETH_VPORT_RSS_CONFIG_IPV4_CAPABILITY ,
304- !!(p_params -> rss_caps & QED_RSS_IPV4 ));
306+ !!(p_rss -> rss_caps & QED_RSS_IPV4 ));
305307 SET_FIELD (capabilities ,
306308 ETH_VPORT_RSS_CONFIG_IPV6_CAPABILITY ,
307- !!(p_params -> rss_caps & QED_RSS_IPV6 ));
309+ !!(p_rss -> rss_caps & QED_RSS_IPV6 ));
308310 SET_FIELD (capabilities ,
309311 ETH_VPORT_RSS_CONFIG_IPV4_TCP_CAPABILITY ,
310- !!(p_params -> rss_caps & QED_RSS_IPV4_TCP ));
312+ !!(p_rss -> rss_caps & QED_RSS_IPV4_TCP ));
311313 SET_FIELD (capabilities ,
312314 ETH_VPORT_RSS_CONFIG_IPV6_TCP_CAPABILITY ,
313- !!(p_params -> rss_caps & QED_RSS_IPV6_TCP ));
315+ !!(p_rss -> rss_caps & QED_RSS_IPV6_TCP ));
314316 SET_FIELD (capabilities ,
315317 ETH_VPORT_RSS_CONFIG_IPV4_UDP_CAPABILITY ,
316- !!(p_params -> rss_caps & QED_RSS_IPV4_UDP ));
318+ !!(p_rss -> rss_caps & QED_RSS_IPV4_UDP ));
317319 SET_FIELD (capabilities ,
318320 ETH_VPORT_RSS_CONFIG_IPV6_UDP_CAPABILITY ,
319- !!(p_params -> rss_caps & QED_RSS_IPV6_UDP ));
320- rss -> tbl_size = p_params -> rss_table_size_log ;
321+ !!(p_rss -> rss_caps & QED_RSS_IPV6_UDP ));
322+ p_config -> tbl_size = p_rss -> rss_table_size_log ;
321323
322- rss -> capabilities = cpu_to_le16 (capabilities );
324+ p_config -> capabilities = cpu_to_le16 (capabilities );
323325
324326 DP_VERBOSE (p_hwfn , NETIF_MSG_IFUP ,
325327 "update rss flag %d, rss_mode = %d, update_caps = %d, capabilities = %d, update_ind = %d, update_rss_key = %d\n" ,
326328 p_ramrod -> common .update_rss_flg ,
327- rss -> rss_mode , rss -> update_rss_capabilities ,
328- capabilities , rss -> update_rss_ind_table ,
329- rss -> update_rss_key );
329+ p_config -> rss_mode ,
330+ p_config -> update_rss_capabilities ,
331+ p_config -> capabilities ,
332+ p_config -> update_rss_ind_table , p_config -> update_rss_key );
330333
331- for (i = 0 ; i < QED_RSS_IND_TABLE_SIZE ; i ++ ) {
332- rc = qed_fw_l2_queue (p_hwfn ,
333- (u8 )p_params -> rss_ind_table [i ],
334- & abs_l2_queue );
335- if (rc )
336- return rc ;
334+ table_size = min_t (int , QED_RSS_IND_TABLE_SIZE ,
335+ 1 << p_config -> tbl_size );
336+ for (i = 0 ; i < table_size ; i ++ ) {
337+ struct qed_queue_cid * p_queue = p_rss -> rss_ind_table [i ];
337338
338- rss -> indirection_table [i ] = cpu_to_le16 (abs_l2_queue );
339- DP_VERBOSE (p_hwfn , NETIF_MSG_IFUP , "i= %d, queue = %d\n" ,
340- i , rss -> indirection_table [i ]);
339+ if (!p_queue )
340+ return - EINVAL ;
341+
342+ p_config -> indirection_table [i ] =
343+ cpu_to_le16 (p_queue -> abs .queue_id );
344+ }
345+
346+ DP_VERBOSE (p_hwfn , NETIF_MSG_IFUP ,
347+ "Configured RSS indirection table [%d entries]:\n" ,
348+ table_size );
349+ for (i = 0 ; i < QED_RSS_IND_TABLE_SIZE ; i += 0x10 ) {
350+ DP_VERBOSE (p_hwfn ,
351+ NETIF_MSG_IFUP ,
352+ "%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n" ,
353+ le16_to_cpu (p_config -> indirection_table [i ]),
354+ le16_to_cpu (p_config -> indirection_table [i + 1 ]),
355+ le16_to_cpu (p_config -> indirection_table [i + 2 ]),
356+ le16_to_cpu (p_config -> indirection_table [i + 3 ]),
357+ le16_to_cpu (p_config -> indirection_table [i + 4 ]),
358+ le16_to_cpu (p_config -> indirection_table [i + 5 ]),
359+ le16_to_cpu (p_config -> indirection_table [i + 6 ]),
360+ le16_to_cpu (p_config -> indirection_table [i + 7 ]),
361+ le16_to_cpu (p_config -> indirection_table [i + 8 ]),
362+ le16_to_cpu (p_config -> indirection_table [i + 9 ]),
363+ le16_to_cpu (p_config -> indirection_table [i + 10 ]),
364+ le16_to_cpu (p_config -> indirection_table [i + 11 ]),
365+ le16_to_cpu (p_config -> indirection_table [i + 12 ]),
366+ le16_to_cpu (p_config -> indirection_table [i + 13 ]),
367+ le16_to_cpu (p_config -> indirection_table [i + 14 ]),
368+ le16_to_cpu (p_config -> indirection_table [i + 15 ]));
341369 }
342370
343371 for (i = 0 ; i < 10 ; i ++ )
344- rss -> rss_key [i ] = cpu_to_le32 (p_params -> rss_key [i ]);
372+ p_config -> rss_key [i ] = cpu_to_le32 (p_rss -> rss_key [i ]);
345373
346374 return rc ;
347375}
@@ -1899,18 +1927,84 @@ static int qed_stop_vport(struct qed_dev *cdev, u8 vport_id)
18991927 return 0 ;
19001928}
19011929
1930+ static int qed_update_vport_rss (struct qed_dev * cdev ,
1931+ struct qed_update_vport_rss_params * input ,
1932+ struct qed_rss_params * rss )
1933+ {
1934+ int i , fn ;
1935+
1936+ /* Update configuration with what's correct regardless of CMT */
1937+ rss -> update_rss_config = 1 ;
1938+ rss -> rss_enable = 1 ;
1939+ rss -> update_rss_capabilities = 1 ;
1940+ rss -> update_rss_ind_table = 1 ;
1941+ rss -> update_rss_key = 1 ;
1942+ rss -> rss_caps = input -> rss_caps ;
1943+ memcpy (rss -> rss_key , input -> rss_key , QED_RSS_KEY_SIZE * sizeof (u32 ));
1944+
1945+ /* In regular scenario, we'd simply need to take input handlers.
1946+ * But in CMT, we'd have to split the handlers according to the
1947+ * engine they were configured on. We'd then have to understand
1948+ * whether RSS is really required, since 2-queues on CMT doesn't
1949+ * require RSS.
1950+ */
1951+ if (cdev -> num_hwfns == 1 ) {
1952+ memcpy (rss -> rss_ind_table ,
1953+ input -> rss_ind_table ,
1954+ QED_RSS_IND_TABLE_SIZE * sizeof (void * ));
1955+ rss -> rss_table_size_log = 7 ;
1956+ return 0 ;
1957+ }
1958+
1959+ /* Start by copying the non-spcific information to the 2nd copy */
1960+ memcpy (& rss [1 ], & rss [0 ], sizeof (struct qed_rss_params ));
1961+
1962+ /* CMT should be round-robin */
1963+ for (i = 0 ; i < QED_RSS_IND_TABLE_SIZE ; i ++ ) {
1964+ struct qed_queue_cid * cid = input -> rss_ind_table [i ];
1965+ struct qed_rss_params * t_rss ;
1966+
1967+ if (cid -> p_owner == QED_LEADING_HWFN (cdev ))
1968+ t_rss = & rss [0 ];
1969+ else
1970+ t_rss = & rss [1 ];
1971+
1972+ t_rss -> rss_ind_table [i / cdev -> num_hwfns ] = cid ;
1973+ }
1974+
1975+ /* Make sure RSS is actually required */
1976+ for_each_hwfn (cdev , fn ) {
1977+ for (i = 1 ; i < QED_RSS_IND_TABLE_SIZE / cdev -> num_hwfns ; i ++ ) {
1978+ if (rss [fn ].rss_ind_table [i ] !=
1979+ rss [fn ].rss_ind_table [0 ])
1980+ break ;
1981+ }
1982+ if (i == QED_RSS_IND_TABLE_SIZE / cdev -> num_hwfns ) {
1983+ DP_VERBOSE (cdev , NETIF_MSG_IFUP ,
1984+ "CMT - 1 queue per-hwfn; Disabling RSS\n" );
1985+ return - EINVAL ;
1986+ }
1987+ rss [fn ].rss_table_size_log = 6 ;
1988+ }
1989+
1990+ return 0 ;
1991+ }
1992+
19021993static int qed_update_vport (struct qed_dev * cdev ,
19031994 struct qed_update_vport_params * params )
19041995{
19051996 struct qed_sp_vport_update_params sp_params ;
1906- struct qed_rss_params sp_rss_params ;
1907- int rc , i ;
1997+ struct qed_rss_params * rss ;
1998+ int rc = 0 , i ;
19081999
19092000 if (!cdev )
19102001 return - ENODEV ;
19112002
2003+ rss = vzalloc (sizeof (* rss ) * cdev -> num_hwfns );
2004+ if (!rss )
2005+ return - ENOMEM ;
2006+
19122007 memset (& sp_params , 0 , sizeof (sp_params ));
1913- memset (& sp_rss_params , 0 , sizeof (sp_rss_params ));
19142008
19152009 /* Translate protocol params into sp params */
19162010 sp_params .vport_id = params -> vport_id ;
@@ -1924,66 +2018,24 @@ static int qed_update_vport(struct qed_dev *cdev,
19242018 sp_params .update_accept_any_vlan_flg =
19252019 params -> update_accept_any_vlan_flg ;
19262020
1927- /* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns.
1928- * We need to re-fix the rss values per engine for CMT.
1929- */
1930- if (cdev -> num_hwfns > 1 && params -> update_rss_flg ) {
1931- struct qed_update_vport_rss_params * rss = & params -> rss_params ;
1932- int k , max = 0 ;
1933-
1934- /* Find largest entry, since it's possible RSS needs to
1935- * be disabled [in case only 1 queue per-hwfn]
1936- */
1937- for (k = 0 ; k < QED_RSS_IND_TABLE_SIZE ; k ++ )
1938- max = (max > rss -> rss_ind_table [k ]) ?
1939- max : rss -> rss_ind_table [k ];
1940-
1941- /* Either fix RSS values or disable RSS */
1942- if (cdev -> num_hwfns < max + 1 ) {
1943- int divisor = (max + cdev -> num_hwfns - 1 ) /
1944- cdev -> num_hwfns ;
1945-
1946- DP_VERBOSE (cdev , (QED_MSG_SPQ | NETIF_MSG_IFUP ),
1947- "CMT - fixing RSS values (modulo %02x)\n" ,
1948- divisor );
1949-
1950- for (k = 0 ; k < QED_RSS_IND_TABLE_SIZE ; k ++ )
1951- rss -> rss_ind_table [k ] =
1952- rss -> rss_ind_table [k ] % divisor ;
1953- } else {
1954- DP_VERBOSE (cdev , (QED_MSG_SPQ | NETIF_MSG_IFUP ),
1955- "CMT - 1 queue per-hwfn; Disabling RSS\n" );
2021+ /* Prepare the RSS configuration */
2022+ if (params -> update_rss_flg )
2023+ if (qed_update_vport_rss (cdev , & params -> rss_params , rss ))
19562024 params -> update_rss_flg = 0 ;
1957- }
1958- }
1959-
1960- /* Now, update the RSS configuration for actual configuration */
1961- if (params -> update_rss_flg ) {
1962- sp_rss_params .update_rss_config = 1 ;
1963- sp_rss_params .rss_enable = 1 ;
1964- sp_rss_params .update_rss_capabilities = 1 ;
1965- sp_rss_params .update_rss_ind_table = 1 ;
1966- sp_rss_params .update_rss_key = 1 ;
1967- sp_rss_params .rss_caps = params -> rss_params .rss_caps ;
1968- sp_rss_params .rss_table_size_log = 7 ; /* 2^7 = 128 */
1969- memcpy (sp_rss_params .rss_ind_table ,
1970- params -> rss_params .rss_ind_table ,
1971- QED_RSS_IND_TABLE_SIZE * sizeof (u16 ));
1972- memcpy (sp_rss_params .rss_key , params -> rss_params .rss_key ,
1973- QED_RSS_KEY_SIZE * sizeof (u32 ));
1974- sp_params .rss_params = & sp_rss_params ;
1975- }
19762025
19772026 for_each_hwfn (cdev , i ) {
19782027 struct qed_hwfn * p_hwfn = & cdev -> hwfns [i ];
19792028
2029+ if (params -> update_rss_flg )
2030+ sp_params .rss_params = & rss [i ];
2031+
19802032 sp_params .opaque_fid = p_hwfn -> hw_info .opaque_fid ;
19812033 rc = qed_sp_vport_update (p_hwfn , & sp_params ,
19822034 QED_SPQ_MODE_EBLOCK ,
19832035 NULL );
19842036 if (rc ) {
19852037 DP_ERR (cdev , "Failed to update VPORT\n" );
1986- return rc ;
2038+ goto out ;
19872039 }
19882040
19892041 DP_VERBOSE (cdev , (QED_MSG_SPQ | NETIF_MSG_IFUP ),
@@ -1992,7 +2044,9 @@ static int qed_update_vport(struct qed_dev *cdev,
19922044 params -> update_vport_active_flg );
19932045 }
19942046
1995- return 0 ;
2047+ out :
2048+ vfree (rss );
2049+ return rc ;
19962050}
19972051
19982052static int qed_start_rxq (struct qed_dev * cdev ,
0 commit comments