29
29
#include "qed_hw.h"
30
30
#include "qed_init_ops.h"
31
31
#include "qed_int.h"
32
+ #include "qed_ll2.h"
32
33
#include "qed_mcp.h"
33
34
#include "qed_reg_addr.h"
34
35
#include "qed_sp.h"
@@ -147,6 +148,9 @@ void qed_resc_free(struct qed_dev *cdev)
147
148
qed_eq_free (p_hwfn , p_hwfn -> p_eq );
148
149
qed_consq_free (p_hwfn , p_hwfn -> p_consq );
149
150
qed_int_free (p_hwfn );
151
+ #ifdef CONFIG_QED_LL2
152
+ qed_ll2_free (p_hwfn , p_hwfn -> p_ll2_info );
153
+ #endif
150
154
qed_iov_free (p_hwfn );
151
155
qed_dmae_info_free (p_hwfn );
152
156
qed_dcbx_info_free (p_hwfn , p_hwfn -> p_dcbx_info );
@@ -403,6 +407,9 @@ int qed_qm_reconf(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
403
407
404
408
int qed_resc_alloc (struct qed_dev * cdev )
405
409
{
410
+ #ifdef CONFIG_QED_LL2
411
+ struct qed_ll2_info * p_ll2_info ;
412
+ #endif
406
413
struct qed_consq * p_consq ;
407
414
struct qed_eq * p_eq ;
408
415
int i , rc = 0 ;
@@ -513,6 +520,15 @@ int qed_resc_alloc(struct qed_dev *cdev)
513
520
goto alloc_no_mem ;
514
521
p_hwfn -> p_consq = p_consq ;
515
522
523
+ #ifdef CONFIG_QED_LL2
524
+ if (p_hwfn -> using_ll2 ) {
525
+ p_ll2_info = qed_ll2_alloc (p_hwfn );
526
+ if (!p_ll2_info )
527
+ goto alloc_no_mem ;
528
+ p_hwfn -> p_ll2_info = p_ll2_info ;
529
+ }
530
+ #endif
531
+
516
532
/* DMA info initialization */
517
533
rc = qed_dmae_info_alloc (p_hwfn );
518
534
if (rc )
@@ -561,6 +577,10 @@ void qed_resc_setup(struct qed_dev *cdev)
561
577
qed_int_setup (p_hwfn , p_hwfn -> p_main_ptt );
562
578
563
579
qed_iov_setup (p_hwfn , p_hwfn -> p_main_ptt );
580
+ #ifdef CONFIG_QED_LL2
581
+ if (p_hwfn -> using_ll2 )
582
+ qed_ll2_setup (p_hwfn , p_hwfn -> p_ll2_info );
583
+ #endif
564
584
}
565
585
}
566
586
@@ -1304,6 +1324,7 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
1304
1324
resc_num [QED_VLAN ] = (ETH_NUM_VLAN_FILTERS - 1 /*For vlan0*/ ) /
1305
1325
num_funcs ;
1306
1326
resc_num [QED_ILT ] = PXP_NUM_ILT_RECORDS_BB / num_funcs ;
1327
+ resc_num [QED_LL2_QUEUE ] = MAX_NUM_LL2_RX_QUEUES / num_funcs ;
1307
1328
1308
1329
for (i = 0 ; i < QED_MAX_RESC ; i ++ )
1309
1330
resc_start [i ] = resc_num [i ] * enabled_func_idx ;
@@ -1327,7 +1348,8 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
1327
1348
"RL = %d start = %d\n"
1328
1349
"MAC = %d start = %d\n"
1329
1350
"VLAN = %d start = %d\n"
1330
- "ILT = %d start = %d\n" ,
1351
+ "ILT = %d start = %d\n"
1352
+ "LL2_QUEUE = %d start = %d\n" ,
1331
1353
p_hwfn -> hw_info .resc_num [QED_SB ],
1332
1354
p_hwfn -> hw_info .resc_start [QED_SB ],
1333
1355
p_hwfn -> hw_info .resc_num [QED_L2_QUEUE ],
@@ -1343,7 +1365,9 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn)
1343
1365
p_hwfn -> hw_info .resc_num [QED_VLAN ],
1344
1366
p_hwfn -> hw_info .resc_start [QED_VLAN ],
1345
1367
p_hwfn -> hw_info .resc_num [QED_ILT ],
1346
- p_hwfn -> hw_info .resc_start [QED_ILT ]);
1368
+ p_hwfn -> hw_info .resc_start [QED_ILT ],
1369
+ RESC_NUM (p_hwfn , QED_LL2_QUEUE ),
1370
+ RESC_START (p_hwfn , QED_LL2_QUEUE ));
1347
1371
1348
1372
return 0 ;
1349
1373
}
@@ -2133,6 +2157,98 @@ int qed_fw_rss_eng(struct qed_hwfn *p_hwfn, u8 src_id, u8 *dst_id)
2133
2157
return 0 ;
2134
2158
}
2135
2159
2160
+ static void qed_llh_mac_to_filter (u32 * p_high , u32 * p_low ,
2161
+ u8 * p_filter )
2162
+ {
2163
+ * p_high = p_filter [1 ] | (p_filter [0 ] << 8 );
2164
+ * p_low = p_filter [5 ] | (p_filter [4 ] << 8 ) |
2165
+ (p_filter [3 ] << 16 ) | (p_filter [2 ] << 24 );
2166
+ }
2167
+
2168
+ int qed_llh_add_mac_filter (struct qed_hwfn * p_hwfn ,
2169
+ struct qed_ptt * p_ptt , u8 * p_filter )
2170
+ {
2171
+ u32 high = 0 , low = 0 , en ;
2172
+ int i ;
2173
+
2174
+ if (!(IS_MF_SI (p_hwfn ) || IS_MF_DEFAULT (p_hwfn )))
2175
+ return 0 ;
2176
+
2177
+ qed_llh_mac_to_filter (& high , & low , p_filter );
2178
+
2179
+ /* Find a free entry and utilize it */
2180
+ for (i = 0 ; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE ; i ++ ) {
2181
+ en = qed_rd (p_hwfn , p_ptt ,
2182
+ NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof (u32 ));
2183
+ if (en )
2184
+ continue ;
2185
+ qed_wr (p_hwfn , p_ptt ,
2186
+ NIG_REG_LLH_FUNC_FILTER_VALUE +
2187
+ 2 * i * sizeof (u32 ), low );
2188
+ qed_wr (p_hwfn , p_ptt ,
2189
+ NIG_REG_LLH_FUNC_FILTER_VALUE +
2190
+ (2 * i + 1 ) * sizeof (u32 ), high );
2191
+ qed_wr (p_hwfn , p_ptt ,
2192
+ NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof (u32 ), 0 );
2193
+ qed_wr (p_hwfn , p_ptt ,
2194
+ NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
2195
+ i * sizeof (u32 ), 0 );
2196
+ qed_wr (p_hwfn , p_ptt ,
2197
+ NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof (u32 ), 1 );
2198
+ break ;
2199
+ }
2200
+ if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE ) {
2201
+ DP_NOTICE (p_hwfn ,
2202
+ "Failed to find an empty LLH filter to utilize\n" );
2203
+ return - EINVAL ;
2204
+ }
2205
+
2206
+ DP_VERBOSE (p_hwfn , NETIF_MSG_HW ,
2207
+ "mac: %pM is added at %d\n" ,
2208
+ p_filter , i );
2209
+
2210
+ return 0 ;
2211
+ }
2212
+
2213
+ void qed_llh_remove_mac_filter (struct qed_hwfn * p_hwfn ,
2214
+ struct qed_ptt * p_ptt , u8 * p_filter )
2215
+ {
2216
+ u32 high = 0 , low = 0 ;
2217
+ int i ;
2218
+
2219
+ if (!(IS_MF_SI (p_hwfn ) || IS_MF_DEFAULT (p_hwfn )))
2220
+ return ;
2221
+
2222
+ qed_llh_mac_to_filter (& high , & low , p_filter );
2223
+
2224
+ /* Find the entry and clean it */
2225
+ for (i = 0 ; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE ; i ++ ) {
2226
+ if (qed_rd (p_hwfn , p_ptt ,
2227
+ NIG_REG_LLH_FUNC_FILTER_VALUE +
2228
+ 2 * i * sizeof (u32 )) != low )
2229
+ continue ;
2230
+ if (qed_rd (p_hwfn , p_ptt ,
2231
+ NIG_REG_LLH_FUNC_FILTER_VALUE +
2232
+ (2 * i + 1 ) * sizeof (u32 )) != high )
2233
+ continue ;
2234
+
2235
+ qed_wr (p_hwfn , p_ptt ,
2236
+ NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof (u32 ), 0 );
2237
+ qed_wr (p_hwfn , p_ptt ,
2238
+ NIG_REG_LLH_FUNC_FILTER_VALUE + 2 * i * sizeof (u32 ), 0 );
2239
+ qed_wr (p_hwfn , p_ptt ,
2240
+ NIG_REG_LLH_FUNC_FILTER_VALUE +
2241
+ (2 * i + 1 ) * sizeof (u32 ), 0 );
2242
+
2243
+ DP_VERBOSE (p_hwfn , NETIF_MSG_HW ,
2244
+ "mac: %pM is removed from %d\n" ,
2245
+ p_filter , i );
2246
+ break ;
2247
+ }
2248
+ if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE )
2249
+ DP_NOTICE (p_hwfn , "Tried to remove a non-configured filter\n" );
2250
+ }
2251
+
2136
2252
static int qed_set_coalesce (struct qed_hwfn * p_hwfn , struct qed_ptt * p_ptt ,
2137
2253
u32 hw_addr , void * p_eth_qzone ,
2138
2254
size_t eth_qzone_size , u8 timeset )
0 commit comments