diff options
author | Murali Karicheri | 2017-03-15 16:38:48 -0500 |
---|---|---|
committer | Murali Karicheri | 2017-03-15 16:38:48 -0500 |
commit | c63ff3daab5fea3f6e446bfac48468c43cb4fddc (patch) | |
tree | 796908c0fb7fd1cc04bf2b8c0edc7733eeae4297 | |
parent | 97e880b69f9477266679c32b37d2638d25fb21ba (diff) | |
parent | b392aeb0ea8740633e39209aaf3f8f6e078cdb3f (diff) | |
download | linux-v3.10.72/master-rt.tar.gz linux-v3.10.72/master-rt.tar.xz linux-v3.10.72/master-rt.zip |
Merge branch 'v3.10.72/rebuild/24-drivers-net' into v3.10.72/master-rtv3.10.72/master-rt
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.c | 115 | ||||
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_ale.h | 1 |
2 files changed, 84 insertions, 32 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index b0c4292ef90..ac0db490d9f 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c | |||
@@ -171,6 +171,9 @@ static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry) | |||
171 | 171 | ||
172 | WARN_ON(idx > ale->params.ale_entries); | 172 | WARN_ON(idx > ale->params.ale_entries); |
173 | 173 | ||
174 | /* Caller must hold ale_lock */ | ||
175 | assert_spin_locked(&ale->ale_lock); | ||
176 | |||
174 | for (i = 0; i < ALE_ENTRY_WORDS; i++) | 177 | for (i = 0; i < ALE_ENTRY_WORDS; i++) |
175 | __raw_writel(ale_entry[i], ale->params.ale_regs + | 178 | __raw_writel(ale_entry[i], ale->params.ale_regs + |
176 | ALE_TABLE + 4 * i); | 179 | ALE_TABLE + 4 * i); |
@@ -274,6 +277,7 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | |||
274 | u32 ale_entry[ALE_ENTRY_WORDS]; | 277 | u32 ale_entry[ALE_ENTRY_WORDS]; |
275 | int ret, idx; | 278 | int ret, idx; |
276 | 279 | ||
280 | spin_lock_bh(&ale->ale_lock); | ||
277 | for (idx = 0; idx < ale->params.ale_entries; idx++) { | 281 | for (idx = 0; idx < ale->params.ale_entries; idx++) { |
278 | cpsw_ale_read(ale, idx, ale_entry); | 282 | cpsw_ale_read(ale, idx, ale_entry); |
279 | ret = cpsw_ale_get_entry_type(ale_entry); | 283 | ret = cpsw_ale_get_entry_type(ale_entry); |
@@ -290,6 +294,7 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | |||
290 | 294 | ||
291 | cpsw_ale_write(ale, idx, ale_entry); | 295 | cpsw_ale_write(ale, idx, ale_entry); |
292 | } | 296 | } |
297 | spin_unlock_bh(&ale->ale_lock); | ||
293 | return 0; | 298 | return 0; |
294 | } | 299 | } |
295 | 300 | ||
@@ -309,6 +314,7 @@ int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask) | |||
309 | u32 ale_entry[ALE_ENTRY_WORDS]; | 314 | u32 ale_entry[ALE_ENTRY_WORDS]; |
310 | int ret, idx; | 315 | int ret, idx; |
311 | 316 | ||
317 | spin_lock_bh(&ale->ale_lock); | ||
312 | for (idx = 0; idx < ale->params.ale_entries; idx++) { | 318 | for (idx = 0; idx < ale->params.ale_entries; idx++) { |
313 | cpsw_ale_read(ale, idx, ale_entry); | 319 | cpsw_ale_read(ale, idx, ale_entry); |
314 | ret = cpsw_ale_get_entry_type(ale_entry); | 320 | ret = cpsw_ale_get_entry_type(ale_entry); |
@@ -322,6 +328,7 @@ int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask) | |||
322 | 328 | ||
323 | cpsw_ale_write(ale, idx, ale_entry); | 329 | cpsw_ale_write(ale, idx, ale_entry); |
324 | } | 330 | } |
331 | spin_unlock_bh(&ale->ale_lock); | ||
325 | return 0; | 332 | return 0; |
326 | } | 333 | } |
327 | 334 | ||
@@ -340,7 +347,9 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, | |||
340 | int flags, u16 vid) | 347 | int flags, u16 vid) |
341 | { | 348 | { |
342 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 349 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
343 | int idx; | 350 | int idx, retval = 0; |
351 | |||
352 | spin_lock_bh(&ale->ale_lock); | ||
344 | 353 | ||
345 | cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); | 354 | cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid); |
346 | 355 | ||
@@ -355,34 +364,44 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, | |||
355 | idx = cpsw_ale_match_free(ale); | 364 | idx = cpsw_ale_match_free(ale); |
356 | if (idx < 0) | 365 | if (idx < 0) |
357 | idx = cpsw_ale_find_ageable(ale); | 366 | idx = cpsw_ale_find_ageable(ale); |
358 | if (idx < 0) | 367 | if (idx < 0) { |
359 | return -ENOMEM; | 368 | retval = -ENOMEM; |
369 | goto out_unlock; | ||
370 | } | ||
360 | 371 | ||
361 | cpsw_ale_write(ale, idx, ale_entry); | 372 | cpsw_ale_write(ale, idx, ale_entry); |
362 | return 0; | 373 | out_unlock: |
374 | spin_unlock_bh(&ale->ale_lock); | ||
375 | return retval; | ||
363 | } | 376 | } |
364 | 377 | ||
365 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, | 378 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, |
366 | int flags, u16 vid) | 379 | int flags, u16 vid) |
367 | { | 380 | { |
368 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 381 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
369 | int idx; | 382 | int idx, retval = 0; |
370 | 383 | ||
384 | spin_lock_bh(&ale->ale_lock); | ||
371 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); | 385 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); |
372 | if (idx < 0) | 386 | if (idx < 0) { |
373 | return -ENOENT; | 387 | retval = -ENOENT; |
388 | goto out_unlock; | ||
389 | } | ||
374 | 390 | ||
375 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | 391 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); |
376 | cpsw_ale_write(ale, idx, ale_entry); | 392 | cpsw_ale_write(ale, idx, ale_entry); |
377 | return 0; | 393 | out_unlock: |
394 | spin_unlock_bh(&ale->ale_lock); | ||
395 | return retval; | ||
378 | } | 396 | } |
379 | 397 | ||
380 | int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, | 398 | int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, |
381 | int flags, u16 vid, int mcast_state) | 399 | int flags, u16 vid, int mcast_state) |
382 | { | 400 | { |
383 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 401 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
384 | int idx, mask; | 402 | int idx, mask, retval = 0; |
385 | 403 | ||
404 | spin_lock_bh(&ale->ale_lock); | ||
386 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); | 405 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); |
387 | if (idx >= 0) | 406 | if (idx >= 0) |
388 | cpsw_ale_read(ale, idx, ale_entry); | 407 | cpsw_ale_read(ale, idx, ale_entry); |
@@ -401,22 +420,29 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, | |||
401 | idx = cpsw_ale_match_free(ale); | 420 | idx = cpsw_ale_match_free(ale); |
402 | if (idx < 0) | 421 | if (idx < 0) |
403 | idx = cpsw_ale_find_ageable(ale); | 422 | idx = cpsw_ale_find_ageable(ale); |
404 | if (idx < 0) | 423 | if (idx < 0) { |
405 | return -ENOMEM; | 424 | retval = -ENOMEM; |
425 | goto out_unlock; | ||
426 | } | ||
406 | 427 | ||
407 | cpsw_ale_write(ale, idx, ale_entry); | 428 | cpsw_ale_write(ale, idx, ale_entry); |
408 | return 0; | 429 | out_unlock: |
430 | spin_unlock_bh(&ale->ale_lock); | ||
431 | return retval; | ||
409 | } | 432 | } |
410 | 433 | ||
411 | int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, | 434 | int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, |
412 | int flags, u16 vid) | 435 | int flags, u16 vid) |
413 | { | 436 | { |
414 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 437 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
415 | int idx; | 438 | int idx, retval = 0; |
416 | 439 | ||
440 | spin_lock_bh(&ale->ale_lock); | ||
417 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); | 441 | idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0); |
418 | if (idx < 0) | 442 | if (idx < 0) { |
419 | return -EINVAL; | 443 | retval = -EINVAL; |
444 | goto out_unlock; | ||
445 | } | ||
420 | 446 | ||
421 | cpsw_ale_read(ale, idx, ale_entry); | 447 | cpsw_ale_read(ale, idx, ale_entry); |
422 | 448 | ||
@@ -426,7 +452,9 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask, | |||
426 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | 452 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); |
427 | 453 | ||
428 | cpsw_ale_write(ale, idx, ale_entry); | 454 | cpsw_ale_write(ale, idx, ale_entry); |
429 | return 0; | 455 | out_unlock: |
456 | spin_unlock_bh(&ale->ale_lock); | ||
457 | return retval; | ||
430 | } | 458 | } |
431 | 459 | ||
432 | /* ALE Rev 1.4 specific vlan functions */ | 460 | /* ALE Rev 1.4 specific vlan functions */ |
@@ -465,8 +493,9 @@ int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, | |||
465 | int reg_mcast, int unreg_mcast) | 493 | int reg_mcast, int unreg_mcast) |
466 | { | 494 | { |
467 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 495 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
468 | int idx; | 496 | int idx, retval = 0; |
469 | 497 | ||
498 | spin_lock_bh(&ale->ale_lock); | ||
470 | idx = cpsw_ale_match_vlan(ale, vid); | 499 | idx = cpsw_ale_match_vlan(ale, vid); |
471 | if (idx >= 0) | 500 | if (idx >= 0) |
472 | cpsw_ale_read(ale, idx, ale_entry); | 501 | cpsw_ale_read(ale, idx, ale_entry); |
@@ -486,21 +515,28 @@ int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag, | |||
486 | idx = cpsw_ale_match_free(ale); | 515 | idx = cpsw_ale_match_free(ale); |
487 | if (idx < 0) | 516 | if (idx < 0) |
488 | idx = cpsw_ale_find_ageable(ale); | 517 | idx = cpsw_ale_find_ageable(ale); |
489 | if (idx < 0) | 518 | if (idx < 0) { |
490 | return -ENOMEM; | 519 | retval = -ENOMEM; |
520 | goto out_unlock; | ||
521 | } | ||
491 | 522 | ||
492 | cpsw_ale_write(ale, idx, ale_entry); | 523 | cpsw_ale_write(ale, idx, ale_entry); |
493 | return 0; | 524 | out_unlock: |
525 | spin_unlock_bh(&ale->ale_lock); | ||
526 | return retval; | ||
494 | } | 527 | } |
495 | 528 | ||
496 | int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) | 529 | int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) |
497 | { | 530 | { |
498 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 531 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
499 | int idx; | 532 | int idx, retval = 0; |
500 | 533 | ||
534 | spin_lock_bh(&ale->ale_lock); | ||
501 | idx = cpsw_ale_match_vlan(ale, vid); | 535 | idx = cpsw_ale_match_vlan(ale, vid); |
502 | if (idx < 0) | 536 | if (idx < 0) { |
503 | return -ENOENT; | 537 | retval = -ENOENT; |
538 | goto out_unlock; | ||
539 | } | ||
504 | 540 | ||
505 | cpsw_ale_read(ale, idx, ale_entry); | 541 | cpsw_ale_read(ale, idx, ale_entry); |
506 | 542 | ||
@@ -510,7 +546,9 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask) | |||
510 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | 546 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); |
511 | 547 | ||
512 | cpsw_ale_write(ale, idx, ale_entry); | 548 | cpsw_ale_write(ale, idx, ale_entry); |
513 | return 0; | 549 | out_unlock: |
550 | spin_unlock_bh(&ale->ale_lock); | ||
551 | return retval; | ||
514 | } | 552 | } |
515 | 553 | ||
516 | struct ale_control_info { | 554 | struct ale_control_info { |
@@ -1292,7 +1330,9 @@ int cpsw_ale_table_store_vm_proc(struct cpsw_ale *ale, | |||
1292 | int cpsw_ale_add_oui(struct cpsw_ale *ale, u8 *addr) | 1330 | int cpsw_ale_add_oui(struct cpsw_ale *ale, u8 *addr) |
1293 | { | 1331 | { |
1294 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; | 1332 | u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0}; |
1295 | int idx; | 1333 | int idx, retval = 0; |
1334 | |||
1335 | spin_lock_bh(&ale->ale_lock); | ||
1296 | 1336 | ||
1297 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); | 1337 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR); |
1298 | 1338 | ||
@@ -1304,11 +1344,15 @@ int cpsw_ale_add_oui(struct cpsw_ale *ale, u8 *addr) | |||
1304 | idx = cpsw_ale_match_free(ale); | 1344 | idx = cpsw_ale_match_free(ale); |
1305 | if (idx < 0) | 1345 | if (idx < 0) |
1306 | idx = cpsw_ale_find_ageable(ale); | 1346 | idx = cpsw_ale_find_ageable(ale); |
1307 | if (idx < 0) | 1347 | if (idx < 0) { |
1308 | return -ENOMEM; | 1348 | retval = -ENOMEM; |
1349 | goto out_unlock; | ||
1350 | } | ||
1309 | 1351 | ||
1310 | cpsw_ale_write(ale, idx, ale_entry); | 1352 | cpsw_ale_write(ale, idx, ale_entry); |
1311 | return 0; | 1353 | out_unlock: |
1354 | spin_unlock_bh(&ale->ale_lock); | ||
1355 | return retval; | ||
1312 | } | 1356 | } |
1313 | 1357 | ||
1314 | int cpsw_ale_table_store_oui(struct cpsw_ale *ale, | 1358 | int cpsw_ale_table_store_oui(struct cpsw_ale *ale, |
@@ -1337,22 +1381,28 @@ int cpsw_ale_table_store_oui(struct cpsw_ale *ale, | |||
1337 | int cpsw_ale_table_store_del(struct cpsw_ale *ale, int idx) | 1381 | int cpsw_ale_table_store_del(struct cpsw_ale *ale, int idx) |
1338 | { | 1382 | { |
1339 | u32 ale_entry[ALE_ENTRY_WORDS]; | 1383 | u32 ale_entry[ALE_ENTRY_WORDS]; |
1340 | int type; | 1384 | int type, retval = 0; |
1341 | 1385 | ||
1342 | dev_dbg(ale->params.dev, "deleting entry[%d] ...\n", idx); | 1386 | dev_dbg(ale->params.dev, "deleting entry[%d] ...\n", idx); |
1343 | 1387 | ||
1344 | if (idx >= ale->params.ale_entries) | 1388 | if (idx >= ale->params.ale_entries) |
1345 | return -EINVAL; | 1389 | return -EINVAL; |
1346 | 1390 | ||
1391 | spin_lock_bh(&ale->ale_lock); | ||
1392 | |||
1347 | cpsw_ale_read(ale, idx, ale_entry); | 1393 | cpsw_ale_read(ale, idx, ale_entry); |
1348 | 1394 | ||
1349 | type = cpsw_ale_get_entry_type(ale_entry); | 1395 | type = cpsw_ale_get_entry_type(ale_entry); |
1350 | if (type == ALE_TYPE_FREE) | 1396 | if (type == ALE_TYPE_FREE) { |
1351 | return -EINVAL; | 1397 | retval = -EINVAL; |
1398 | goto out_unlock; | ||
1399 | } | ||
1352 | 1400 | ||
1353 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | 1401 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); |
1354 | cpsw_ale_write(ale, idx, ale_entry); | 1402 | cpsw_ale_write(ale, idx, ale_entry); |
1355 | return 0; | 1403 | out_unlock: |
1404 | spin_unlock_bh(&ale->ale_lock); | ||
1405 | return retval; | ||
1356 | } | 1406 | } |
1357 | 1407 | ||
1358 | static struct ale_table_cmd ale_table_cmds[] = { | 1408 | static struct ale_table_cmd ale_table_cmds[] = { |
@@ -1611,6 +1661,7 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) | |||
1611 | 1661 | ||
1612 | ale->params = *params; | 1662 | ale->params = *params; |
1613 | ale->ageout = ale->params.ale_ageout * HZ; | 1663 | ale->ageout = ale->params.ale_ageout * HZ; |
1664 | spin_lock_init(&ale->ale_lock); | ||
1614 | 1665 | ||
1615 | return ale; | 1666 | return ale; |
1616 | } | 1667 | } |
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index 9f156ed6ebe..d13e84c5d70 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h | |||
@@ -39,6 +39,7 @@ struct cpsw_ale { | |||
39 | int show_next; | 39 | int show_next; |
40 | int raw_show_next; | 40 | int raw_show_next; |
41 | u32 revision; | 41 | u32 revision; |
42 | spinlock_t ale_lock; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | enum cpsw_ale_control { | 45 | enum cpsw_ale_control { |