aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-27 10:47:23 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-27 10:47:23 -0400
commit776d7c5f69ebae12bde4383bea177c3e16732077 (patch)
tree396d887c6726d2fe71bcf38c20e9b9e7b2996e87
parent8daf1a2d7e40685054ebae680733d822ced6df62 (diff)
parent0c6d9b44145d8134ebe4e9ebfa02e0dd23744723 (diff)
Merge branch 'net-mvpp2-Remove-unnecessary-dynamic-allocs'
Maxime Chevallier says: ==================== net: mvpp2: Remove unnecessary dynamic allocs Some utility functions in mvpp2 make use of dynamic alloc to exchange temporary objects representing Parser Entries (which are generic filtering entries in the PPv2 controller). These objects are small (44 bytes each), we can use the stack to exchange them. Some previous discussion on this topic showed that the mvpp2_prs_hw_read, which initializes a struct mvpp2_prs_entry based on one of its fields, can easily lead to erroneous code if we don't zero-out the struct beforehand : https://lkml.org/lkml/2018/3/21/739 To fix this, I propose to rename mvpp2_prs_hw_read into mvpp2_prs_init_from_hw, make it zero-out the struct and take the index as a parameter. That's what's done in the first patch of the series. The second patch is the V3 of ("net: mvpp2: Don't use dynamic allocs for local variables"), making use of mvpp2_prs_init_from_hw and taking previous comments into account. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/marvell/mvpp2.c320
1 files changed, 137 insertions, 183 deletions
diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index f8bc3d4a39ff..7075e5ab78f3 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -1582,14 +1582,18 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
1582 return 0; 1582 return 0;
1583} 1583}
1584 1584
1585/* Read tcam entry from hw */ 1585/* Initialize tcam entry from hw */
1586static int mvpp2_prs_hw_read(struct mvpp2 *priv, struct mvpp2_prs_entry *pe) 1586static int mvpp2_prs_init_from_hw(struct mvpp2 *priv,
1587 struct mvpp2_prs_entry *pe, int tid)
1587{ 1588{
1588 int i; 1589 int i;
1589 1590
1590 if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1) 1591 if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
1591 return -EINVAL; 1592 return -EINVAL;
1592 1593
1594 memset(pe, 0, sizeof(*pe));
1595 pe->index = tid;
1596
1593 /* Write tcam index - indirect access */ 1597 /* Write tcam index - indirect access */
1594 mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index); 1598 mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);
1595 1599
@@ -1913,16 +1917,11 @@ static void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe,
1913} 1917}
1914 1918
1915/* Find parser flow entry */ 1919/* Find parser flow entry */
1916static struct mvpp2_prs_entry *mvpp2_prs_flow_find(struct mvpp2 *priv, int flow) 1920static int mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
1917{ 1921{
1918 struct mvpp2_prs_entry *pe; 1922 struct mvpp2_prs_entry pe;
1919 int tid; 1923 int tid;
1920 1924
1921 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
1922 if (!pe)
1923 return NULL;
1924 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
1925
1926 /* Go through the all entires with MVPP2_PRS_LU_FLOWS */ 1925 /* Go through the all entires with MVPP2_PRS_LU_FLOWS */
1927 for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) { 1926 for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) {
1928 u8 bits; 1927 u8 bits;
@@ -1931,17 +1930,15 @@ static struct mvpp2_prs_entry *mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
1931 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS) 1930 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
1932 continue; 1931 continue;
1933 1932
1934 pe->index = tid; 1933 mvpp2_prs_init_from_hw(priv, &pe, tid);
1935 mvpp2_prs_hw_read(priv, pe); 1934 bits = mvpp2_prs_sram_ai_get(&pe);
1936 bits = mvpp2_prs_sram_ai_get(pe);
1937 1935
1938 /* Sram store classification lookup ID in AI bits [5:0] */ 1936 /* Sram store classification lookup ID in AI bits [5:0] */
1939 if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow) 1937 if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow)
1940 return pe; 1938 return tid;
1941 } 1939 }
1942 kfree(pe);
1943 1940
1944 return NULL; 1941 return -ENOENT;
1945} 1942}
1946 1943
1947/* Return first free tcam index, seeking from start to end */ 1944/* Return first free tcam index, seeking from start to end */
@@ -1971,8 +1968,7 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
1971 1968
1972 if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) { 1969 if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {
1973 /* Entry exist - update port only */ 1970 /* Entry exist - update port only */
1974 pe.index = MVPP2_PE_DROP_ALL; 1971 mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
1975 mvpp2_prs_hw_read(priv, &pe);
1976 } else { 1972 } else {
1977 /* Entry doesn't exist - create new */ 1973 /* Entry doesn't exist - create new */
1978 memset(&pe, 0, sizeof(pe)); 1974 memset(&pe, 0, sizeof(pe));
@@ -2020,8 +2016,7 @@ static void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
2020 2016
2021 /* promiscuous mode - Accept unknown unicast or multicast packets */ 2017 /* promiscuous mode - Accept unknown unicast or multicast packets */
2022 if (priv->prs_shadow[tid].valid) { 2018 if (priv->prs_shadow[tid].valid) {
2023 pe.index = tid; 2019 mvpp2_prs_init_from_hw(priv, &pe, tid);
2024 mvpp2_prs_hw_read(priv, &pe);
2025 } else { 2020 } else {
2026 memset(&pe, 0, sizeof(pe)); 2021 memset(&pe, 0, sizeof(pe));
2027 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 2022 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
@@ -2071,8 +2066,7 @@ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
2071 2066
2072 if (priv->prs_shadow[tid].valid) { 2067 if (priv->prs_shadow[tid].valid) {
2073 /* Entry exist - update port only */ 2068 /* Entry exist - update port only */
2074 pe.index = tid; 2069 mvpp2_prs_init_from_hw(priv, &pe, tid);
2075 mvpp2_prs_hw_read(priv, &pe);
2076 } else { 2070 } else {
2077 /* Entry doesn't exist - create new */ 2071 /* Entry doesn't exist - create new */
2078 memset(&pe, 0, sizeof(pe)); 2072 memset(&pe, 0, sizeof(pe));
@@ -2140,8 +2134,7 @@ static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
2140 2134
2141 if (priv->prs_shadow[tid].valid) { 2135 if (priv->prs_shadow[tid].valid) {
2142 /* Entry exist - update port only */ 2136 /* Entry exist - update port only */
2143 pe.index = tid; 2137 mvpp2_prs_init_from_hw(priv, &pe, tid);
2144 mvpp2_prs_hw_read(priv, &pe);
2145 } else { 2138 } else {
2146 /* Entry doesn't exist - create new */ 2139 /* Entry doesn't exist - create new */
2147 memset(&pe, 0, sizeof(pe)); 2140 memset(&pe, 0, sizeof(pe));
@@ -2189,17 +2182,11 @@ static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
2189} 2182}
2190 2183
2191/* Search for existing single/triple vlan entry */ 2184/* Search for existing single/triple vlan entry */
2192static struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2 *priv, 2185static int mvpp2_prs_vlan_find(struct mvpp2 *priv, unsigned short tpid, int ai)
2193 unsigned short tpid, int ai)
2194{ 2186{
2195 struct mvpp2_prs_entry *pe; 2187 struct mvpp2_prs_entry pe;
2196 int tid; 2188 int tid;
2197 2189
2198 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
2199 if (!pe)
2200 return NULL;
2201 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
2202
2203 /* Go through the all entries with MVPP2_PRS_LU_VLAN */ 2190 /* Go through the all entries with MVPP2_PRS_LU_VLAN */
2204 for (tid = MVPP2_PE_FIRST_FREE_TID; 2191 for (tid = MVPP2_PE_FIRST_FREE_TID;
2205 tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 2192 tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
@@ -2210,19 +2197,17 @@ static struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2 *priv,
2210 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN) 2197 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
2211 continue; 2198 continue;
2212 2199
2213 pe->index = tid; 2200 mvpp2_prs_init_from_hw(priv, &pe, tid);
2214 2201 match = mvpp2_prs_tcam_data_cmp(&pe, 0, swab16(tpid));
2215 mvpp2_prs_hw_read(priv, pe);
2216 match = mvpp2_prs_tcam_data_cmp(pe, 0, swab16(tpid));
2217 if (!match) 2202 if (!match)
2218 continue; 2203 continue;
2219 2204
2220 /* Get vlan type */ 2205 /* Get vlan type */
2221 ri_bits = mvpp2_prs_sram_ri_get(pe); 2206 ri_bits = mvpp2_prs_sram_ri_get(&pe);
2222 ri_bits &= MVPP2_PRS_RI_VLAN_MASK; 2207 ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
2223 2208
2224 /* Get current ai value from tcam */ 2209 /* Get current ai value from tcam */
2225 ai_bits = mvpp2_prs_tcam_ai_get(pe); 2210 ai_bits = mvpp2_prs_tcam_ai_get(&pe);
2226 /* Clear double vlan bit */ 2211 /* Clear double vlan bit */
2227 ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT; 2212 ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT;
2228 2213
@@ -2231,34 +2216,31 @@ static struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2 *priv,
2231 2216
2232 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE || 2217 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
2233 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE) 2218 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
2234 return pe; 2219 return tid;
2235 } 2220 }
2236 kfree(pe);
2237 2221
2238 return NULL; 2222 return -ENOENT;
2239} 2223}
2240 2224
2241/* Add/update single/triple vlan entry */ 2225/* Add/update single/triple vlan entry */
2242static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai, 2226static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
2243 unsigned int port_map) 2227 unsigned int port_map)
2244{ 2228{
2245 struct mvpp2_prs_entry *pe; 2229 struct mvpp2_prs_entry pe;
2246 int tid_aux, tid; 2230 int tid_aux, tid;
2247 int ret = 0; 2231 int ret = 0;
2248 2232
2249 pe = mvpp2_prs_vlan_find(priv, tpid, ai); 2233 memset(&pe, 0, sizeof(pe));
2234
2235 tid = mvpp2_prs_vlan_find(priv, tpid, ai);
2250 2236
2251 if (!pe) { 2237 if (tid < 0) {
2252 /* Create new tcam entry */ 2238 /* Create new tcam entry */
2253 tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_LAST_FREE_TID, 2239 tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_LAST_FREE_TID,
2254 MVPP2_PE_FIRST_FREE_TID); 2240 MVPP2_PE_FIRST_FREE_TID);
2255 if (tid < 0) 2241 if (tid < 0)
2256 return tid; 2242 return tid;
2257 2243
2258 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
2259 if (!pe)
2260 return -ENOMEM;
2261
2262 /* Get last double vlan tid */ 2244 /* Get last double vlan tid */
2263 for (tid_aux = MVPP2_PE_LAST_FREE_TID; 2245 for (tid_aux = MVPP2_PE_LAST_FREE_TID;
2264 tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) { 2246 tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) {
@@ -2268,49 +2250,46 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
2268 priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN) 2250 priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
2269 continue; 2251 continue;
2270 2252
2271 pe->index = tid_aux; 2253 mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
2272 mvpp2_prs_hw_read(priv, pe); 2254 ri_bits = mvpp2_prs_sram_ri_get(&pe);
2273 ri_bits = mvpp2_prs_sram_ri_get(pe);
2274 if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) == 2255 if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
2275 MVPP2_PRS_RI_VLAN_DOUBLE) 2256 MVPP2_PRS_RI_VLAN_DOUBLE)
2276 break; 2257 break;
2277 } 2258 }
2278 2259
2279 if (tid <= tid_aux) { 2260 if (tid <= tid_aux)
2280 ret = -EINVAL; 2261 return -EINVAL;
2281 goto free_pe;
2282 }
2283 2262
2284 memset(pe, 0, sizeof(*pe)); 2263 memset(&pe, 0, sizeof(pe));
2285 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 2264 pe.index = tid;
2286 pe->index = tid; 2265 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
2287 2266
2288 mvpp2_prs_match_etype(pe, 0, tpid); 2267 mvpp2_prs_match_etype(&pe, 0, tpid);
2289 2268
2290 /* VLAN tag detected, proceed with VID filtering */ 2269 /* VLAN tag detected, proceed with VID filtering */
2291 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VID); 2270 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);
2292 2271
2293 /* Clear all ai bits for next iteration */ 2272 /* Clear all ai bits for next iteration */
2294 mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK); 2273 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);
2295 2274
2296 if (ai == MVPP2_PRS_SINGLE_VLAN_AI) { 2275 if (ai == MVPP2_PRS_SINGLE_VLAN_AI) {
2297 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_SINGLE, 2276 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_SINGLE,
2298 MVPP2_PRS_RI_VLAN_MASK); 2277 MVPP2_PRS_RI_VLAN_MASK);
2299 } else { 2278 } else {
2300 ai |= MVPP2_PRS_DBL_VLAN_AI_BIT; 2279 ai |= MVPP2_PRS_DBL_VLAN_AI_BIT;
2301 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_TRIPLE, 2280 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_TRIPLE,
2302 MVPP2_PRS_RI_VLAN_MASK); 2281 MVPP2_PRS_RI_VLAN_MASK);
2303 } 2282 }
2304 mvpp2_prs_tcam_ai_update(pe, ai, MVPP2_PRS_SRAM_AI_MASK); 2283 mvpp2_prs_tcam_ai_update(&pe, ai, MVPP2_PRS_SRAM_AI_MASK);
2305 2284
2306 mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_VLAN); 2285 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
2286 } else {
2287 mvpp2_prs_init_from_hw(priv, &pe, tid);
2307 } 2288 }
2308 /* Update ports' mask */ 2289 /* Update ports' mask */
2309 mvpp2_prs_tcam_port_map_set(pe, port_map); 2290 mvpp2_prs_tcam_port_map_set(&pe, port_map);
2310 2291
2311 mvpp2_prs_hw_write(priv, pe); 2292 mvpp2_prs_hw_write(priv, &pe);
2312free_pe:
2313 kfree(pe);
2314 2293
2315 return ret; 2294 return ret;
2316} 2295}
@@ -2329,18 +2308,12 @@ static int mvpp2_prs_double_vlan_ai_free_get(struct mvpp2 *priv)
2329} 2308}
2330 2309
2331/* Search for existing double vlan entry */ 2310/* Search for existing double vlan entry */
2332static struct mvpp2_prs_entry *mvpp2_prs_double_vlan_find(struct mvpp2 *priv, 2311static int mvpp2_prs_double_vlan_find(struct mvpp2 *priv, unsigned short tpid1,
2333 unsigned short tpid1, 2312 unsigned short tpid2)
2334 unsigned short tpid2)
2335{ 2313{
2336 struct mvpp2_prs_entry *pe; 2314 struct mvpp2_prs_entry pe;
2337 int tid; 2315 int tid;
2338 2316
2339 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
2340 if (!pe)
2341 return NULL;
2342 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN);
2343
2344 /* Go through the all entries with MVPP2_PRS_LU_VLAN */ 2317 /* Go through the all entries with MVPP2_PRS_LU_VLAN */
2345 for (tid = MVPP2_PE_FIRST_FREE_TID; 2318 for (tid = MVPP2_PE_FIRST_FREE_TID;
2346 tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 2319 tid <= MVPP2_PE_LAST_FREE_TID; tid++) {
@@ -2351,22 +2324,20 @@ static struct mvpp2_prs_entry *mvpp2_prs_double_vlan_find(struct mvpp2 *priv,
2351 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN) 2324 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
2352 continue; 2325 continue;
2353 2326
2354 pe->index = tid; 2327 mvpp2_prs_init_from_hw(priv, &pe, tid);
2355 mvpp2_prs_hw_read(priv, pe);
2356 2328
2357 match = mvpp2_prs_tcam_data_cmp(pe, 0, swab16(tpid1)) 2329 match = mvpp2_prs_tcam_data_cmp(&pe, 0, swab16(tpid1)) &&
2358 && mvpp2_prs_tcam_data_cmp(pe, 4, swab16(tpid2)); 2330 mvpp2_prs_tcam_data_cmp(&pe, 4, swab16(tpid2));
2359 2331
2360 if (!match) 2332 if (!match)
2361 continue; 2333 continue;
2362 2334
2363 ri_mask = mvpp2_prs_sram_ri_get(pe) & MVPP2_PRS_RI_VLAN_MASK; 2335 ri_mask = mvpp2_prs_sram_ri_get(&pe) & MVPP2_PRS_RI_VLAN_MASK;
2364 if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE) 2336 if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE)
2365 return pe; 2337 return tid;
2366 } 2338 }
2367 kfree(pe);
2368 2339
2369 return NULL; 2340 return -ENOENT;
2370} 2341}
2371 2342
2372/* Add or update double vlan entry */ 2343/* Add or update double vlan entry */
@@ -2374,28 +2345,24 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
2374 unsigned short tpid2, 2345 unsigned short tpid2,
2375 unsigned int port_map) 2346 unsigned int port_map)
2376{ 2347{
2377 struct mvpp2_prs_entry *pe;
2378 int tid_aux, tid, ai, ret = 0; 2348 int tid_aux, tid, ai, ret = 0;
2349 struct mvpp2_prs_entry pe;
2379 2350
2380 pe = mvpp2_prs_double_vlan_find(priv, tpid1, tpid2); 2351 memset(&pe, 0, sizeof(pe));
2381 2352
2382 if (!pe) { 2353 tid = mvpp2_prs_double_vlan_find(priv, tpid1, tpid2);
2354
2355 if (tid < 0) {
2383 /* Create new tcam entry */ 2356 /* Create new tcam entry */
2384 tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID, 2357 tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,
2385 MVPP2_PE_LAST_FREE_TID); 2358 MVPP2_PE_LAST_FREE_TID);
2386 if (tid < 0) 2359 if (tid < 0)
2387 return tid; 2360 return tid;
2388 2361
2389 pe = kzalloc(sizeof(*pe), GFP_KERNEL);
2390 if (!pe)
2391 return -ENOMEM;
2392
2393 /* Set ai value for new double vlan entry */ 2362 /* Set ai value for new double vlan entry */
2394 ai = mvpp2_prs_double_vlan_ai_free_get(priv); 2363 ai = mvpp2_prs_double_vlan_ai_free_get(priv);
2395 if (ai < 0) { 2364 if (ai < 0)
2396 ret = ai; 2365 return ai;
2397 goto free_pe;
2398 }
2399 2366
2400 /* Get first single/triple vlan tid */ 2367 /* Get first single/triple vlan tid */
2401 for (tid_aux = MVPP2_PE_FIRST_FREE_TID; 2368 for (tid_aux = MVPP2_PE_FIRST_FREE_TID;
@@ -2406,46 +2373,44 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
2406 priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN) 2373 priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
2407 continue; 2374 continue;
2408 2375
2409 pe->index = tid_aux; 2376 mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
2410 mvpp2_prs_hw_read(priv, pe); 2377 ri_bits = mvpp2_prs_sram_ri_get(&pe);
2411 ri_bits = mvpp2_prs_sram_ri_get(pe);
2412 ri_bits &= MVPP2_PRS_RI_VLAN_MASK; 2378 ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
2413 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE || 2379 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
2414 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE) 2380 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)
2415 break; 2381 break;
2416 } 2382 }
2417 2383
2418 if (tid >= tid_aux) { 2384 if (tid >= tid_aux)
2419 ret = -ERANGE; 2385 return -ERANGE;
2420 goto free_pe;
2421 }
2422 2386
2423 memset(pe, 0, sizeof(*pe)); 2387 memset(&pe, 0, sizeof(pe));
2424 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 2388 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);
2425 pe->index = tid; 2389 pe.index = tid;
2426 2390
2427 priv->prs_double_vlans[ai] = true; 2391 priv->prs_double_vlans[ai] = true;
2428 2392
2429 mvpp2_prs_match_etype(pe, 0, tpid1); 2393 mvpp2_prs_match_etype(&pe, 0, tpid1);
2430 mvpp2_prs_match_etype(pe, 4, tpid2); 2394 mvpp2_prs_match_etype(&pe, 4, tpid2);
2431 2395
2432 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN); 2396 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);
2433 /* Shift 4 bytes - skip outer vlan tag */ 2397 /* Shift 4 bytes - skip outer vlan tag */
2434 mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN, 2398 mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_LEN,
2435 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 2399 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2436 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE, 2400 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,
2437 MVPP2_PRS_RI_VLAN_MASK); 2401 MVPP2_PRS_RI_VLAN_MASK);
2438 mvpp2_prs_sram_ai_update(pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT, 2402 mvpp2_prs_sram_ai_update(&pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT,
2439 MVPP2_PRS_SRAM_AI_MASK); 2403 MVPP2_PRS_SRAM_AI_MASK);
2440 2404
2441 mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_VLAN); 2405 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
2406 } else {
2407 mvpp2_prs_init_from_hw(priv, &pe, tid);
2442 } 2408 }
2443 2409
2444 /* Update ports' mask */ 2410 /* Update ports' mask */
2445 mvpp2_prs_tcam_port_map_set(pe, port_map); 2411 mvpp2_prs_tcam_port_map_set(&pe, port_map);
2446 mvpp2_prs_hw_write(priv, pe); 2412 mvpp2_prs_hw_write(priv, &pe);
2447free_pe: 2413
2448 kfree(pe);
2449 return ret; 2414 return ret;
2450} 2415}
2451 2416
@@ -3513,9 +3478,8 @@ static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,
3513 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID) 3478 priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
3514 continue; 3479 continue;
3515 3480
3516 pe.index = tid; 3481 mvpp2_prs_init_from_hw(priv, &pe, tid);
3517 3482
3518 mvpp2_prs_hw_read(priv, &pe);
3519 mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]); 3483 mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
3520 mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]); 3484 mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
3521 3485
@@ -3528,7 +3492,7 @@ static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,
3528 return tid; 3492 return tid;
3529 } 3493 }
3530 3494
3531 return 0; 3495 return -ENOENT;
3532} 3496}
3533 3497
3534/* Write parser entry for VID filtering */ 3498/* Write parser entry for VID filtering */
@@ -3541,6 +3505,8 @@ static int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
3541 struct mvpp2_prs_entry pe; 3505 struct mvpp2_prs_entry pe;
3542 int tid; 3506 int tid;
3543 3507
3508 memset(&pe, 0, sizeof(pe));
3509
3544 /* Scan TCAM and see if entry with this <vid,port> already exist */ 3510 /* Scan TCAM and see if entry with this <vid,port> already exist */
3545 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, mask); 3511 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, mask);
3546 3512
@@ -3551,8 +3517,7 @@ static int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
3551 shift = MVPP2_VLAN_TAG_LEN; 3517 shift = MVPP2_VLAN_TAG_LEN;
3552 3518
3553 /* No such entry */ 3519 /* No such entry */
3554 if (!tid) { 3520 if (tid < 0) {
3555 memset(&pe, 0, sizeof(pe));
3556 3521
3557 /* Go through all entries from first to last in vlan range */ 3522 /* Go through all entries from first to last in vlan range */
3558 tid = mvpp2_prs_tcam_first_free(priv, vid_start, 3523 tid = mvpp2_prs_tcam_first_free(priv, vid_start,
@@ -3569,7 +3534,7 @@ static int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
3569 /* Mask all ports */ 3534 /* Mask all ports */
3570 mvpp2_prs_tcam_port_map_set(&pe, 0); 3535 mvpp2_prs_tcam_port_map_set(&pe, 0);
3571 } else { 3536 } else {
3572 mvpp2_prs_hw_read(priv, &pe); 3537 mvpp2_prs_init_from_hw(priv, &pe, tid);
3573 } 3538 }
3574 3539
3575 /* Enable the current port */ 3540 /* Enable the current port */
@@ -3604,7 +3569,7 @@ static void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
3604 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, 0xfff); 3569 tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, 0xfff);
3605 3570
3606 /* No such entry */ 3571 /* No such entry */
3607 if (tid) 3572 if (tid < 0)
3608 return; 3573 return;
3609 3574
3610 mvpp2_prs_hw_inv(priv, tid); 3575 mvpp2_prs_hw_inv(priv, tid);
@@ -3771,18 +3736,13 @@ static bool mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe,
3771} 3736}
3772 3737
3773/* Find tcam entry with matched pair <MAC DA, port> */ 3738/* Find tcam entry with matched pair <MAC DA, port> */
3774static struct mvpp2_prs_entry * 3739static int
3775mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da, 3740mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
3776 unsigned char *mask, int udf_type) 3741 unsigned char *mask, int udf_type)
3777{ 3742{
3778 struct mvpp2_prs_entry *pe; 3743 struct mvpp2_prs_entry pe;
3779 int tid; 3744 int tid;
3780 3745
3781 pe = kzalloc(sizeof(*pe), GFP_ATOMIC);
3782 if (!pe)
3783 return NULL;
3784 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
3785
3786 /* Go through the all entires with MVPP2_PRS_LU_MAC */ 3746 /* Go through the all entires with MVPP2_PRS_LU_MAC */
3787 for (tid = MVPP2_PE_MAC_RANGE_START; 3747 for (tid = MVPP2_PE_MAC_RANGE_START;
3788 tid <= MVPP2_PE_MAC_RANGE_END; tid++) { 3748 tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
@@ -3793,17 +3753,15 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
3793 (priv->prs_shadow[tid].udf != udf_type)) 3753 (priv->prs_shadow[tid].udf != udf_type))
3794 continue; 3754 continue;
3795 3755
3796 pe->index = tid; 3756 mvpp2_prs_init_from_hw(priv, &pe, tid);
3797 mvpp2_prs_hw_read(priv, pe); 3757 entry_pmap = mvpp2_prs_tcam_port_map_get(&pe);
3798 entry_pmap = mvpp2_prs_tcam_port_map_get(pe);
3799 3758
3800 if (mvpp2_prs_mac_range_equals(pe, da, mask) && 3759 if (mvpp2_prs_mac_range_equals(&pe, da, mask) &&
3801 entry_pmap == pmap) 3760 entry_pmap == pmap)
3802 return pe; 3761 return tid;
3803 } 3762 }
3804 kfree(pe);
3805 3763
3806 return NULL; 3764 return -ENOENT;
3807} 3765}
3808 3766
3809/* Update parser's mac da entry */ 3767/* Update parser's mac da entry */
@@ -3813,15 +3771,17 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da,
3813 unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 3771 unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3814 struct mvpp2 *priv = port->priv; 3772 struct mvpp2 *priv = port->priv;
3815 unsigned int pmap, len, ri; 3773 unsigned int pmap, len, ri;
3816 struct mvpp2_prs_entry *pe; 3774 struct mvpp2_prs_entry pe;
3817 int tid; 3775 int tid;
3818 3776
3777 memset(&pe, 0, sizeof(pe));
3778
3819 /* Scan TCAM and see if entry with this <MAC DA, port> already exist */ 3779 /* Scan TCAM and see if entry with this <MAC DA, port> already exist */
3820 pe = mvpp2_prs_mac_da_range_find(priv, BIT(port->id), da, mask, 3780 tid = mvpp2_prs_mac_da_range_find(priv, BIT(port->id), da, mask,
3821 MVPP2_PRS_UDF_MAC_DEF); 3781 MVPP2_PRS_UDF_MAC_DEF);
3822 3782
3823 /* No such entry */ 3783 /* No such entry */
3824 if (!pe) { 3784 if (tid < 0) {
3825 if (!add) 3785 if (!add)
3826 return 0; 3786 return 0;
3827 3787
@@ -3833,39 +3793,37 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da,
3833 if (tid < 0) 3793 if (tid < 0)
3834 return tid; 3794 return tid;
3835 3795
3836 pe = kzalloc(sizeof(*pe), GFP_ATOMIC); 3796 pe.index = tid;
3837 if (!pe)
3838 return -ENOMEM;
3839 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC);
3840 pe->index = tid;
3841 3797
3842 /* Mask all ports */ 3798 /* Mask all ports */
3843 mvpp2_prs_tcam_port_map_set(pe, 0); 3799 mvpp2_prs_tcam_port_map_set(&pe, 0);
3800 } else {
3801 mvpp2_prs_init_from_hw(priv, &pe, tid);
3844 } 3802 }
3845 3803
3804 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
3805
3846 /* Update port mask */ 3806 /* Update port mask */
3847 mvpp2_prs_tcam_port_set(pe, port->id, add); 3807 mvpp2_prs_tcam_port_set(&pe, port->id, add);
3848 3808
3849 /* Invalidate the entry if no ports are left enabled */ 3809 /* Invalidate the entry if no ports are left enabled */
3850 pmap = mvpp2_prs_tcam_port_map_get(pe); 3810 pmap = mvpp2_prs_tcam_port_map_get(&pe);
3851 if (pmap == 0) { 3811 if (pmap == 0) {
3852 if (add) { 3812 if (add)
3853 kfree(pe);
3854 return -EINVAL; 3813 return -EINVAL;
3855 } 3814
3856 mvpp2_prs_hw_inv(priv, pe->index); 3815 mvpp2_prs_hw_inv(priv, pe.index);
3857 priv->prs_shadow[pe->index].valid = false; 3816 priv->prs_shadow[pe.index].valid = false;
3858 kfree(pe);
3859 return 0; 3817 return 0;
3860 } 3818 }
3861 3819
3862 /* Continue - set next lookup */ 3820 /* Continue - set next lookup */
3863 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_DSA); 3821 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);
3864 3822
3865 /* Set match on DA */ 3823 /* Set match on DA */
3866 len = ETH_ALEN; 3824 len = ETH_ALEN;
3867 while (len--) 3825 while (len--)
3868 mvpp2_prs_tcam_data_byte_set(pe, len, da[len], 0xff); 3826 mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff);
3869 3827
3870 /* Set result info bits */ 3828 /* Set result info bits */
3871 if (is_broadcast_ether_addr(da)) { 3829 if (is_broadcast_ether_addr(da)) {
@@ -3879,21 +3837,19 @@ static int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da,
3879 ri |= MVPP2_PRS_RI_MAC_ME_MASK; 3837 ri |= MVPP2_PRS_RI_MAC_ME_MASK;
3880 } 3838 }
3881 3839
3882 mvpp2_prs_sram_ri_update(pe, ri, MVPP2_PRS_RI_L2_CAST_MASK | 3840 mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK |
3883 MVPP2_PRS_RI_MAC_ME_MASK); 3841 MVPP2_PRS_RI_MAC_ME_MASK);
3884 mvpp2_prs_shadow_ri_set(priv, pe->index, ri, MVPP2_PRS_RI_L2_CAST_MASK | 3842 mvpp2_prs_shadow_ri_set(priv, pe.index, ri, MVPP2_PRS_RI_L2_CAST_MASK |
3885 MVPP2_PRS_RI_MAC_ME_MASK); 3843 MVPP2_PRS_RI_MAC_ME_MASK);
3886 3844
3887 /* Shift to ethertype */ 3845 /* Shift to ethertype */
3888 mvpp2_prs_sram_shift_set(pe, 2 * ETH_ALEN, 3846 mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,
3889 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 3847 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
3890 3848
3891 /* Update shadow table and hw entry */ 3849 /* Update shadow table and hw entry */
3892 priv->prs_shadow[pe->index].udf = MVPP2_PRS_UDF_MAC_DEF; 3850 priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_MAC_DEF;
3893 mvpp2_prs_shadow_set(priv, pe->index, MVPP2_PRS_LU_MAC); 3851 mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);
3894 mvpp2_prs_hw_write(priv, pe); 3852 mvpp2_prs_hw_write(priv, &pe);
3895
3896 kfree(pe);
3897 3853
3898 return 0; 3854 return 0;
3899} 3855}
@@ -3935,8 +3891,7 @@ static void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
3935 (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)) 3891 (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
3936 continue; 3892 continue;
3937 3893
3938 pe.index = tid; 3894 mvpp2_prs_init_from_hw(priv, &pe, tid);
3939 mvpp2_prs_hw_read(priv, &pe);
3940 3895
3941 pmap = mvpp2_prs_tcam_port_map_get(&pe); 3896 pmap = mvpp2_prs_tcam_port_map_get(&pe);
3942 3897
@@ -4014,13 +3969,15 @@ static int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
4014/* Set prs flow for the port */ 3969/* Set prs flow for the port */
4015static int mvpp2_prs_def_flow(struct mvpp2_port *port) 3970static int mvpp2_prs_def_flow(struct mvpp2_port *port)
4016{ 3971{
4017 struct mvpp2_prs_entry *pe; 3972 struct mvpp2_prs_entry pe;
4018 int tid; 3973 int tid;
4019 3974
4020 pe = mvpp2_prs_flow_find(port->priv, port->id); 3975 memset(&pe, 0, sizeof(pe));
3976
3977 tid = mvpp2_prs_flow_find(port->priv, port->id);
4021 3978
4022 /* Such entry not exist */ 3979 /* Such entry not exist */
4023 if (!pe) { 3980 if (tid < 0) {
4024 /* Go through the all entires from last to first */ 3981 /* Go through the all entires from last to first */
4025 tid = mvpp2_prs_tcam_first_free(port->priv, 3982 tid = mvpp2_prs_tcam_first_free(port->priv,
4026 MVPP2_PE_LAST_FREE_TID, 3983 MVPP2_PE_LAST_FREE_TID,
@@ -4028,24 +3985,21 @@ static int mvpp2_prs_def_flow(struct mvpp2_port *port)
4028 if (tid < 0) 3985 if (tid < 0)
4029 return tid; 3986 return tid;
4030 3987
4031 pe = kzalloc(sizeof(*pe), GFP_KERNEL); 3988 pe.index = tid;
4032 if (!pe)
4033 return -ENOMEM;
4034
4035 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_FLOWS);
4036 pe->index = tid;
4037 3989
4038 /* Set flow ID*/ 3990 /* Set flow ID*/
4039 mvpp2_prs_sram_ai_update(pe, port->id, MVPP2_PRS_FLOW_ID_MASK); 3991 mvpp2_prs_sram_ai_update(&pe, port->id, MVPP2_PRS_FLOW_ID_MASK);
4040 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1); 3992 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
4041 3993
4042 /* Update shadow table */ 3994 /* Update shadow table */
4043 mvpp2_prs_shadow_set(port->priv, pe->index, MVPP2_PRS_LU_FLOWS); 3995 mvpp2_prs_shadow_set(port->priv, pe.index, MVPP2_PRS_LU_FLOWS);
3996 } else {
3997 mvpp2_prs_init_from_hw(port->priv, &pe, tid);
4044 } 3998 }
4045 3999
4046 mvpp2_prs_tcam_port_map_set(pe, (1 << port->id)); 4000 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
4047 mvpp2_prs_hw_write(port->priv, pe); 4001 mvpp2_prs_tcam_port_map_set(&pe, (1 << port->id));
4048 kfree(pe); 4002 mvpp2_prs_hw_write(port->priv, &pe);
4049 4003
4050 return 0; 4004 return 0;
4051} 4005}