diff options
author | Benjamin Li <benli@broadcom.com> | 2008-07-15 01:39:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-15 01:39:52 -0400 |
commit | 5fcaed0124cde73124227542bfce4ed57fccbb50 (patch) | |
tree | 408431b6e281b4c7db2fabced90493ee3bc80b56 /drivers/net/bnx2.c | |
parent | 7c62e83beb1446d690ed921beddb0dcf34c9baa9 (diff) |
bnx2: Support secondary MAC addresses.
Add support for configuring secondary unicast addresses. There
are 4 additional perfect match filters which can be used for
secondary unicast address support.
* Modified bnx2_set_mac_addr() to be more generic in handling
the setting of the perfect match filters
* Changed bnx2_set_rx_mode() to handle the unicast dev_addr_list
Signed-off-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 2d0213ed6e7d..0d0bb93d1cf8 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -2451,19 +2451,18 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp) | |||
2451 | } | 2451 | } |
2452 | 2452 | ||
2453 | static void | 2453 | static void |
2454 | bnx2_set_mac_addr(struct bnx2 *bp) | 2454 | bnx2_set_mac_addr(struct bnx2 *bp, u8 *mac_addr, u32 pos) |
2455 | { | 2455 | { |
2456 | u32 val; | 2456 | u32 val; |
2457 | u8 *mac_addr = bp->dev->dev_addr; | ||
2458 | 2457 | ||
2459 | val = (mac_addr[0] << 8) | mac_addr[1]; | 2458 | val = (mac_addr[0] << 8) | mac_addr[1]; |
2460 | 2459 | ||
2461 | REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val); | 2460 | REG_WR(bp, BNX2_EMAC_MAC_MATCH0 + (pos * 8), val); |
2462 | 2461 | ||
2463 | val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | | 2462 | val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | |
2464 | (mac_addr[4] << 8) | mac_addr[5]; | 2463 | (mac_addr[4] << 8) | mac_addr[5]; |
2465 | 2464 | ||
2466 | REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val); | 2465 | REG_WR(bp, BNX2_EMAC_MAC_MATCH1 + (pos * 8), val); |
2467 | } | 2466 | } |
2468 | 2467 | ||
2469 | static inline int | 2468 | static inline int |
@@ -3223,6 +3222,7 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3223 | { | 3222 | { |
3224 | struct bnx2 *bp = netdev_priv(dev); | 3223 | struct bnx2 *bp = netdev_priv(dev); |
3225 | u32 rx_mode, sort_mode; | 3224 | u32 rx_mode, sort_mode; |
3225 | struct dev_addr_list *uc_ptr; | ||
3226 | int i; | 3226 | int i; |
3227 | 3227 | ||
3228 | spin_lock_bh(&bp->phy_lock); | 3228 | spin_lock_bh(&bp->phy_lock); |
@@ -3278,6 +3278,25 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3278 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; | 3278 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; |
3279 | } | 3279 | } |
3280 | 3280 | ||
3281 | uc_ptr = NULL; | ||
3282 | if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { | ||
3283 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; | ||
3284 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | | ||
3285 | BNX2_RPM_SORT_USER0_PROM_VLAN; | ||
3286 | } else if (!(dev->flags & IFF_PROMISC)) { | ||
3287 | uc_ptr = dev->uc_list; | ||
3288 | |||
3289 | /* Add all entries into to the match filter list */ | ||
3290 | for (i = 0; i < dev->uc_count; i++) { | ||
3291 | bnx2_set_mac_addr(bp, uc_ptr->da_addr, | ||
3292 | i + BNX2_START_UNICAST_ADDRESS_INDEX); | ||
3293 | sort_mode |= (1 << | ||
3294 | (i + BNX2_START_UNICAST_ADDRESS_INDEX)); | ||
3295 | uc_ptr = uc_ptr->next; | ||
3296 | } | ||
3297 | |||
3298 | } | ||
3299 | |||
3281 | if (rx_mode != bp->rx_mode) { | 3300 | if (rx_mode != bp->rx_mode) { |
3282 | bp->rx_mode = rx_mode; | 3301 | bp->rx_mode = rx_mode; |
3283 | REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode); | 3302 | REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode); |
@@ -3562,7 +3581,7 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) | |||
3562 | bp->autoneg = autoneg; | 3581 | bp->autoneg = autoneg; |
3563 | bp->advertising = advertising; | 3582 | bp->advertising = advertising; |
3564 | 3583 | ||
3565 | bnx2_set_mac_addr(bp); | 3584 | bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0); |
3566 | 3585 | ||
3567 | val = REG_RD(bp, BNX2_EMAC_MODE); | 3586 | val = REG_RD(bp, BNX2_EMAC_MODE); |
3568 | 3587 | ||
@@ -4472,7 +4491,7 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4472 | 4491 | ||
4473 | bnx2_init_nvram(bp); | 4492 | bnx2_init_nvram(bp); |
4474 | 4493 | ||
4475 | bnx2_set_mac_addr(bp); | 4494 | bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0); |
4476 | 4495 | ||
4477 | val = REG_RD(bp, BNX2_MQ_CONFIG); | 4496 | val = REG_RD(bp, BNX2_MQ_CONFIG); |
4478 | val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; | 4497 | val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; |
@@ -7100,7 +7119,7 @@ bnx2_change_mac_addr(struct net_device *dev, void *p) | |||
7100 | 7119 | ||
7101 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 7120 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
7102 | if (netif_running(dev)) | 7121 | if (netif_running(dev)) |
7103 | bnx2_set_mac_addr(bp); | 7122 | bnx2_set_mac_addr(bp, bp->dev->dev_addr, 0); |
7104 | 7123 | ||
7105 | return 0; | 7124 | return 0; |
7106 | } | 7125 | } |
@@ -7643,7 +7662,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7643 | dev->hard_start_xmit = bnx2_start_xmit; | 7662 | dev->hard_start_xmit = bnx2_start_xmit; |
7644 | dev->stop = bnx2_close; | 7663 | dev->stop = bnx2_close; |
7645 | dev->get_stats = bnx2_get_stats; | 7664 | dev->get_stats = bnx2_get_stats; |
7646 | dev->set_multicast_list = bnx2_set_rx_mode; | 7665 | dev->set_rx_mode = bnx2_set_rx_mode; |
7647 | dev->do_ioctl = bnx2_ioctl; | 7666 | dev->do_ioctl = bnx2_ioctl; |
7648 | dev->set_mac_address = bnx2_change_mac_addr; | 7667 | dev->set_mac_address = bnx2_change_mac_addr; |
7649 | dev->change_mtu = bnx2_change_mtu; | 7668 | dev->change_mtu = bnx2_change_mtu; |