diff options
author | Christopher Leech <christopher.leech@intel.com> | 2008-08-26 07:27:02 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 10:03:32 -0400 |
commit | 2c5645cf65dc6dce15dac47a7cdfabb85224fede (patch) | |
tree | cda97b5ea34d1a6b6928fbdee495292a6502bb63 /drivers/net/ixgbe/ixgbe_common.c | |
parent | 9da09bb1b806a85a0bc4fb5426fb3022f56aad19 (diff) |
ixgbe: Implement HAVE_SET_RX_MODE
Implement HAVE_SET_RX_MODE in the driver for MC and UC lists.
Signed-off-by: Christopher Leech <christopher.leech@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_common.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.c | 123 |
1 files changed, 112 insertions, 11 deletions
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 7fd6aeb1b021..a9f4d0e58e1c 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c | |||
@@ -661,7 +661,7 @@ s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind, | |||
661 | static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) | 661 | static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) |
662 | { | 662 | { |
663 | u32 i; | 663 | u32 i; |
664 | u32 rar_entries = hw->mac.num_rx_addrs; | 664 | u32 rar_entries = hw->mac.num_rar_entries; |
665 | 665 | ||
666 | /* | 666 | /* |
667 | * If the current mac address is valid, assume it is a software override | 667 | * If the current mac address is valid, assume it is a software override |
@@ -705,13 +705,114 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) | |||
705 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); | 705 | IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); |
706 | 706 | ||
707 | hw_dbg(hw, " Clearing MTA\n"); | 707 | hw_dbg(hw, " Clearing MTA\n"); |
708 | for (i = 0; i < IXGBE_MC_TBL_SIZE; i++) | 708 | for (i = 0; i < hw->mac.mcft_size; i++) |
709 | IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); | 709 | IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); |
710 | 710 | ||
711 | return 0; | 711 | return 0; |
712 | } | 712 | } |
713 | 713 | ||
714 | /** | 714 | /** |
715 | * ixgbe_add_uc_addr - Adds a secondary unicast address. | ||
716 | * @hw: pointer to hardware structure | ||
717 | * @addr: new address | ||
718 | * | ||
719 | * Adds it to unused receive address register or goes into promiscuous mode. | ||
720 | **/ | ||
721 | void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr) | ||
722 | { | ||
723 | u32 rar_entries = hw->mac.num_rar_entries; | ||
724 | u32 rar; | ||
725 | |||
726 | hw_dbg(hw, " UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", | ||
727 | addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); | ||
728 | |||
729 | /* | ||
730 | * Place this address in the RAR if there is room, | ||
731 | * else put the controller into promiscuous mode | ||
732 | */ | ||
733 | if (hw->addr_ctrl.rar_used_count < rar_entries) { | ||
734 | rar = hw->addr_ctrl.rar_used_count - | ||
735 | hw->addr_ctrl.mc_addr_in_rar_count; | ||
736 | ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV); | ||
737 | hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); | ||
738 | hw->addr_ctrl.rar_used_count++; | ||
739 | } else { | ||
740 | hw->addr_ctrl.overflow_promisc++; | ||
741 | } | ||
742 | |||
743 | hw_dbg(hw, "ixgbe_add_uc_addr Complete\n"); | ||
744 | } | ||
745 | |||
746 | /** | ||
747 | * ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses | ||
748 | * @hw: pointer to hardware structure | ||
749 | * @addr_list: the list of new addresses | ||
750 | * @addr_count: number of addresses | ||
751 | * @next: iterator function to walk the address list | ||
752 | * | ||
753 | * The given list replaces any existing list. Clears the secondary addrs from | ||
754 | * receive address registers. Uses unused receive address registers for the | ||
755 | * first secondary addresses, and falls back to promiscuous mode as needed. | ||
756 | * | ||
757 | * Drivers using secondary unicast addresses must set user_set_promisc when | ||
758 | * manually putting the device into promiscuous mode. | ||
759 | **/ | ||
760 | s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, | ||
761 | u32 addr_count, ixgbe_mc_addr_itr next) | ||
762 | { | ||
763 | u8 *addr; | ||
764 | u32 i; | ||
765 | u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc; | ||
766 | u32 uc_addr_in_use; | ||
767 | u32 fctrl; | ||
768 | u32 vmdq; | ||
769 | |||
770 | /* | ||
771 | * Clear accounting of old secondary address list, | ||
772 | * don't count RAR[0] | ||
773 | */ | ||
774 | uc_addr_in_use = hw->addr_ctrl.rar_used_count - | ||
775 | hw->addr_ctrl.mc_addr_in_rar_count - 1; | ||
776 | hw->addr_ctrl.rar_used_count -= uc_addr_in_use; | ||
777 | hw->addr_ctrl.overflow_promisc = 0; | ||
778 | |||
779 | /* Zero out the other receive addresses */ | ||
780 | hw_dbg(hw, "Clearing RAR[1-%d]\n", uc_addr_in_use); | ||
781 | for (i = 1; i <= uc_addr_in_use; i++) { | ||
782 | IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); | ||
783 | IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); | ||
784 | } | ||
785 | |||
786 | /* Add the new addresses */ | ||
787 | for (i = 0; i < addr_count; i++) { | ||
788 | hw_dbg(hw, " Adding the secondary addresses:\n"); | ||
789 | addr = next(hw, &addr_list, &vmdq); | ||
790 | ixgbe_add_uc_addr(hw, addr); | ||
791 | } | ||
792 | |||
793 | if (hw->addr_ctrl.overflow_promisc) { | ||
794 | /* enable promisc if not already in overflow or set by user */ | ||
795 | if (!old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { | ||
796 | hw_dbg(hw, " Entering address overflow promisc mode\n"); | ||
797 | fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); | ||
798 | fctrl |= IXGBE_FCTRL_UPE; | ||
799 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); | ||
800 | } | ||
801 | } else { | ||
802 | /* only disable if set by overflow, not by user */ | ||
803 | if (old_promisc_setting && !hw->addr_ctrl.user_set_promisc) { | ||
804 | hw_dbg(hw, " Leaving address overflow promisc mode\n"); | ||
805 | fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); | ||
806 | fctrl &= ~IXGBE_FCTRL_UPE; | ||
807 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); | ||
808 | } | ||
809 | } | ||
810 | |||
811 | hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n"); | ||
812 | return 0; | ||
813 | } | ||
814 | |||
815 | /** | ||
715 | * ixgbe_mta_vector - Determines bit-vector in multicast table to set | 816 | * ixgbe_mta_vector - Determines bit-vector in multicast table to set |
716 | * @hw: pointer to hardware structure | 817 | * @hw: pointer to hardware structure |
717 | * @mc_addr: the multicast address | 818 | * @mc_addr: the multicast address |
@@ -794,7 +895,7 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) | |||
794 | **/ | 895 | **/ |
795 | static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) | 896 | static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) |
796 | { | 897 | { |
797 | u32 rar_entries = hw->mac.num_rx_addrs; | 898 | u32 rar_entries = hw->mac.num_rar_entries; |
798 | 899 | ||
799 | hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", | 900 | hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", |
800 | mc_addr[0], mc_addr[1], mc_addr[2], | 901 | mc_addr[0], mc_addr[1], mc_addr[2], |
@@ -823,7 +924,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) | |||
823 | * @hw: pointer to hardware structure | 924 | * @hw: pointer to hardware structure |
824 | * @mc_addr_list: the list of new multicast addresses | 925 | * @mc_addr_list: the list of new multicast addresses |
825 | * @mc_addr_count: number of addresses | 926 | * @mc_addr_count: number of addresses |
826 | * @pad: number of bytes between addresses in the list | 927 | * @next: iterator function to walk the multicast address list |
827 | * | 928 | * |
828 | * The given list replaces any existing list. Clears the MC addrs from receive | 929 | * The given list replaces any existing list. Clears the MC addrs from receive |
829 | * address registers and the multicast table. Uses unsed receive address | 930 | * address registers and the multicast table. Uses unsed receive address |
@@ -831,10 +932,11 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) | |||
831 | * multicast table. | 932 | * multicast table. |
832 | **/ | 933 | **/ |
833 | s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, | 934 | s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, |
834 | u32 mc_addr_count, u32 pad) | 935 | u32 mc_addr_count, ixgbe_mc_addr_itr next) |
835 | { | 936 | { |
836 | u32 i; | 937 | u32 i; |
837 | u32 rar_entries = hw->mac.num_rx_addrs; | 938 | u32 rar_entries = hw->mac.num_rar_entries; |
939 | u32 vmdq; | ||
838 | 940 | ||
839 | /* | 941 | /* |
840 | * Set the new number of MC addresses that we are being requested to | 942 | * Set the new number of MC addresses that we are being requested to |
@@ -854,14 +956,13 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, | |||
854 | 956 | ||
855 | /* Clear the MTA */ | 957 | /* Clear the MTA */ |
856 | hw_dbg(hw, " Clearing MTA\n"); | 958 | hw_dbg(hw, " Clearing MTA\n"); |
857 | for (i = 0; i < IXGBE_MC_TBL_SIZE; i++) | 959 | for (i = 0; i < hw->mac.mcft_size; i++) |
858 | IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); | 960 | IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); |
859 | 961 | ||
860 | /* Add the new addresses */ | 962 | /* Add the new addresses */ |
861 | for (i = 0; i < mc_addr_count; i++) { | 963 | for (i = 0; i < mc_addr_count; i++) { |
862 | hw_dbg(hw, " Adding the multicast addresses:\n"); | 964 | hw_dbg(hw, " Adding the multicast addresses:\n"); |
863 | ixgbe_add_mc_addr(hw, mc_addr_list + | 965 | ixgbe_add_mc_addr(hw, next(hw, &mc_addr_list, &vmdq)); |
864 | (i * (IXGBE_ETH_LENGTH_OF_ADDRESS + pad))); | ||
865 | } | 966 | } |
866 | 967 | ||
867 | /* Enable mta */ | 968 | /* Enable mta */ |
@@ -884,11 +985,11 @@ static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw) | |||
884 | u32 offset; | 985 | u32 offset; |
885 | u32 vlanbyte; | 986 | u32 vlanbyte; |
886 | 987 | ||
887 | for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++) | 988 | for (offset = 0; offset < hw->mac.vft_size; offset++) |
888 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | 989 | IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); |
889 | 990 | ||
890 | for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) | 991 | for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) |
891 | for (offset = 0; offset < IXGBE_VLAN_FILTER_TBL_SIZE; offset++) | 992 | for (offset = 0; offset < hw->mac.vft_size; offset++) |
892 | IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), | 993 | IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), |
893 | 0); | 994 | 0); |
894 | 995 | ||