| .. | .. |
|---|
| 453 | 453 | if (vid > 4095) |
|---|
| 454 | 454 | return -EINVAL; |
|---|
| 455 | 455 | |
|---|
| 456 | | - if (hw->promisc) { |
|---|
| 457 | | - netdev_err(dev, |
|---|
| 458 | | - "Adding VLAN in promisc mode not supported\n"); |
|---|
| 459 | | - return -EPERM; |
|---|
| 460 | | - } |
|---|
| 461 | | - |
|---|
| 462 | 456 | /* Single Rx VLAN Filter */ |
|---|
| 463 | 457 | if (hw->num_vlan == 1) { |
|---|
| 464 | 458 | /* For single VLAN filter, VID 0 means VLAN promiscuous */ |
|---|
| .. | .. |
|---|
| 508 | 502 | { |
|---|
| 509 | 503 | int i, ret = 0; |
|---|
| 510 | 504 | |
|---|
| 511 | | - if (hw->promisc) { |
|---|
| 512 | | - netdev_err(dev, |
|---|
| 513 | | - "Deleting VLAN in promisc mode not supported\n"); |
|---|
| 514 | | - return -EPERM; |
|---|
| 515 | | - } |
|---|
| 516 | | - |
|---|
| 517 | 505 | /* Single Rx VLAN Filter */ |
|---|
| 518 | 506 | if (hw->num_vlan == 1) { |
|---|
| 519 | 507 | if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) { |
|---|
| .. | .. |
|---|
| 536 | 524 | } |
|---|
| 537 | 525 | |
|---|
| 538 | 526 | return ret; |
|---|
| 539 | | -} |
|---|
| 540 | | - |
|---|
| 541 | | -static void dwmac4_vlan_promisc_enable(struct net_device *dev, |
|---|
| 542 | | - struct mac_device_info *hw) |
|---|
| 543 | | -{ |
|---|
| 544 | | - void __iomem *ioaddr = hw->pcsr; |
|---|
| 545 | | - u32 value; |
|---|
| 546 | | - u32 hash; |
|---|
| 547 | | - u32 val; |
|---|
| 548 | | - int i; |
|---|
| 549 | | - |
|---|
| 550 | | - /* Single Rx VLAN Filter */ |
|---|
| 551 | | - if (hw->num_vlan == 1) { |
|---|
| 552 | | - dwmac4_write_single_vlan(dev, 0); |
|---|
| 553 | | - return; |
|---|
| 554 | | - } |
|---|
| 555 | | - |
|---|
| 556 | | - /* Extended Rx VLAN Filter Enable */ |
|---|
| 557 | | - for (i = 0; i < hw->num_vlan; i++) { |
|---|
| 558 | | - if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) { |
|---|
| 559 | | - val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN; |
|---|
| 560 | | - dwmac4_write_vlan_filter(dev, hw, i, val); |
|---|
| 561 | | - } |
|---|
| 562 | | - } |
|---|
| 563 | | - |
|---|
| 564 | | - hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE); |
|---|
| 565 | | - if (hash & GMAC_VLAN_VLHT) { |
|---|
| 566 | | - value = readl(ioaddr + GMAC_VLAN_TAG); |
|---|
| 567 | | - if (value & GMAC_VLAN_VTHM) { |
|---|
| 568 | | - value &= ~GMAC_VLAN_VTHM; |
|---|
| 569 | | - writel(value, ioaddr + GMAC_VLAN_TAG); |
|---|
| 570 | | - } |
|---|
| 571 | | - } |
|---|
| 572 | 527 | } |
|---|
| 573 | 528 | |
|---|
| 574 | 529 | static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev, |
|---|
| .. | .. |
|---|
| 690 | 645 | } |
|---|
| 691 | 646 | |
|---|
| 692 | 647 | /* VLAN filtering */ |
|---|
| 693 | | - if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) |
|---|
| 648 | + if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) |
|---|
| 649 | + value &= ~GMAC_PACKET_FILTER_VTFE; |
|---|
| 650 | + else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER) |
|---|
| 694 | 651 | value |= GMAC_PACKET_FILTER_VTFE; |
|---|
| 695 | 652 | |
|---|
| 696 | 653 | writel(value, ioaddr + GMAC_PACKET_FILTER); |
|---|
| 697 | | - |
|---|
| 698 | | - if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) { |
|---|
| 699 | | - if (!hw->promisc) { |
|---|
| 700 | | - hw->promisc = 1; |
|---|
| 701 | | - dwmac4_vlan_promisc_enable(dev, hw); |
|---|
| 702 | | - } |
|---|
| 703 | | - } else { |
|---|
| 704 | | - if (hw->promisc) { |
|---|
| 705 | | - hw->promisc = 0; |
|---|
| 706 | | - dwmac4_restore_hw_vlan_rx_fltr(dev, hw); |
|---|
| 707 | | - } |
|---|
| 708 | | - } |
|---|
| 709 | 654 | } |
|---|
| 710 | 655 | |
|---|
| 711 | 656 | static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, |
|---|