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_main.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_main.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 72 |
1 files changed, 40 insertions, 32 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b14192f369db..87ef2db8c430 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -1619,23 +1619,37 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) | |||
1619 | } | 1619 | } |
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | static u8 *ixgbe_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr, u32 *vmdq) | ||
1623 | { | ||
1624 | struct dev_mc_list *mc_ptr; | ||
1625 | u8 *addr = *mc_addr_ptr; | ||
1626 | *vmdq = 0; | ||
1627 | |||
1628 | mc_ptr = container_of(addr, struct dev_mc_list, dmi_addr[0]); | ||
1629 | if (mc_ptr->next) | ||
1630 | *mc_addr_ptr = mc_ptr->next->dmi_addr; | ||
1631 | else | ||
1632 | *mc_addr_ptr = NULL; | ||
1633 | |||
1634 | return addr; | ||
1635 | } | ||
1636 | |||
1622 | /** | 1637 | /** |
1623 | * ixgbe_set_multi - Multicast and Promiscuous mode set | 1638 | * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set |
1624 | * @netdev: network interface device structure | 1639 | * @netdev: network interface device structure |
1625 | * | 1640 | * |
1626 | * The set_multi entry point is called whenever the multicast address | 1641 | * The set_rx_method entry point is called whenever the unicast/multicast |
1627 | * list or the network interface flags are updated. This routine is | 1642 | * address list or the network interface flags are updated. This routine is |
1628 | * responsible for configuring the hardware for proper multicast, | 1643 | * responsible for configuring the hardware for proper unicast, multicast and |
1629 | * promiscuous mode, and all-multi behavior. | 1644 | * promiscuous mode. |
1630 | **/ | 1645 | **/ |
1631 | static void ixgbe_set_multi(struct net_device *netdev) | 1646 | static void ixgbe_set_rx_mode(struct net_device *netdev) |
1632 | { | 1647 | { |
1633 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 1648 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
1634 | struct ixgbe_hw *hw = &adapter->hw; | 1649 | struct ixgbe_hw *hw = &adapter->hw; |
1635 | struct dev_mc_list *mc_ptr; | ||
1636 | u8 *mta_list; | ||
1637 | u32 fctrl, vlnctrl; | 1650 | u32 fctrl, vlnctrl; |
1638 | int i; | 1651 | u8 *addr_list = NULL; |
1652 | int addr_count = 0; | ||
1639 | 1653 | ||
1640 | /* Check for Promiscuous and All Multicast modes */ | 1654 | /* Check for Promiscuous and All Multicast modes */ |
1641 | 1655 | ||
@@ -1643,6 +1657,7 @@ static void ixgbe_set_multi(struct net_device *netdev) | |||
1643 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); | 1657 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); |
1644 | 1658 | ||
1645 | if (netdev->flags & IFF_PROMISC) { | 1659 | if (netdev->flags & IFF_PROMISC) { |
1660 | hw->addr_ctrl.user_set_promisc = 1; | ||
1646 | fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); | 1661 | fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); |
1647 | vlnctrl &= ~IXGBE_VLNCTRL_VFE; | 1662 | vlnctrl &= ~IXGBE_VLNCTRL_VFE; |
1648 | } else { | 1663 | } else { |
@@ -1653,33 +1668,25 @@ static void ixgbe_set_multi(struct net_device *netdev) | |||
1653 | fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); | 1668 | fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); |
1654 | } | 1669 | } |
1655 | vlnctrl |= IXGBE_VLNCTRL_VFE; | 1670 | vlnctrl |= IXGBE_VLNCTRL_VFE; |
1671 | hw->addr_ctrl.user_set_promisc = 0; | ||
1656 | } | 1672 | } |
1657 | 1673 | ||
1658 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); | 1674 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); |
1659 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 1675 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
1660 | 1676 | ||
1661 | if (netdev->mc_count) { | 1677 | /* reprogram secondary unicast list */ |
1662 | mta_list = kcalloc(netdev->mc_count, ETH_ALEN, GFP_ATOMIC); | 1678 | addr_count = netdev->uc_count; |
1663 | if (!mta_list) | 1679 | if (addr_count) |
1664 | return; | 1680 | addr_list = netdev->uc_list->dmi_addr; |
1665 | 1681 | ixgbe_update_uc_addr_list(hw, addr_list, addr_count, | |
1666 | /* Shared function expects packed array of only addresses. */ | 1682 | ixgbe_addr_list_itr); |
1667 | mc_ptr = netdev->mc_list; | ||
1668 | |||
1669 | for (i = 0; i < netdev->mc_count; i++) { | ||
1670 | if (!mc_ptr) | ||
1671 | break; | ||
1672 | memcpy(mta_list + (i * ETH_ALEN), mc_ptr->dmi_addr, | ||
1673 | ETH_ALEN); | ||
1674 | mc_ptr = mc_ptr->next; | ||
1675 | } | ||
1676 | |||
1677 | ixgbe_update_mc_addr_list(hw, mta_list, i, 0); | ||
1678 | kfree(mta_list); | ||
1679 | } else { | ||
1680 | ixgbe_update_mc_addr_list(hw, NULL, 0, 0); | ||
1681 | } | ||
1682 | 1683 | ||
1684 | /* reprogram multicast list */ | ||
1685 | addr_count = netdev->mc_count; | ||
1686 | if (addr_count) | ||
1687 | addr_list = netdev->mc_list->dmi_addr; | ||
1688 | ixgbe_update_mc_addr_list(hw, addr_list, addr_count, | ||
1689 | ixgbe_addr_list_itr); | ||
1683 | } | 1690 | } |
1684 | 1691 | ||
1685 | static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) | 1692 | static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) |
@@ -1723,7 +1730,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) | |||
1723 | struct net_device *netdev = adapter->netdev; | 1730 | struct net_device *netdev = adapter->netdev; |
1724 | int i; | 1731 | int i; |
1725 | 1732 | ||
1726 | ixgbe_set_multi(netdev); | 1733 | ixgbe_set_rx_mode(netdev); |
1727 | 1734 | ||
1728 | ixgbe_restore_vlan(adapter); | 1735 | ixgbe_restore_vlan(adapter); |
1729 | 1736 | ||
@@ -3508,7 +3515,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
3508 | netdev->stop = &ixgbe_close; | 3515 | netdev->stop = &ixgbe_close; |
3509 | netdev->hard_start_xmit = &ixgbe_xmit_frame; | 3516 | netdev->hard_start_xmit = &ixgbe_xmit_frame; |
3510 | netdev->get_stats = &ixgbe_get_stats; | 3517 | netdev->get_stats = &ixgbe_get_stats; |
3511 | netdev->set_multicast_list = &ixgbe_set_multi; | 3518 | netdev->set_rx_mode = &ixgbe_set_rx_mode; |
3519 | netdev->set_multicast_list = &ixgbe_set_rx_mode; | ||
3512 | netdev->set_mac_address = &ixgbe_set_mac; | 3520 | netdev->set_mac_address = &ixgbe_set_mac; |
3513 | netdev->change_mtu = &ixgbe_change_mtu; | 3521 | netdev->change_mtu = &ixgbe_change_mtu; |
3514 | ixgbe_set_ethtool_ops(netdev); | 3522 | ixgbe_set_ethtool_ops(netdev); |