aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Li <benli@broadcom.com>2008-07-15 01:39:52 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-15 01:39:52 -0400
commit5fcaed0124cde73124227542bfce4ed57fccbb50 (patch)
tree408431b6e281b4c7db2fabced90493ee3bc80b56
parent7c62e83beb1446d690ed921beddb0dcf34c9baa9 (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>
-rw-r--r--drivers/net/bnx2.c35
-rw-r--r--drivers/net/bnx2.h5
2 files changed, 32 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
2453static void 2453static void
2454bnx2_set_mac_addr(struct bnx2 *bp) 2454bnx2_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
2469static inline int 2468static 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;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 7b882fd9d57f..bb7b5d5471dd 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6440,6 +6440,11 @@ struct l2_fhdr {
6440 6440
6441#define BNX2_MISC_ENABLE_DEFAULT 0x17ffffff 6441#define BNX2_MISC_ENABLE_DEFAULT 0x17ffffff
6442 6442
6443#define BNX2_START_UNICAST_ADDRESS_INDEX 4
6444#define BNX2_END_UNICAST_ADDRESS_INDEX 7
6445#define BNX2_MAX_UNICAST_ADDRESSES (BNX2_END_UNICAST_ADDRESS_INDEX - \
6446 BNX2_START_UNICAST_ADDRESS_INDEX + 1)
6447
6443#define DMA_READ_CHANS 5 6448#define DMA_READ_CHANS 5
6444#define DMA_WRITE_CHANS 3 6449#define DMA_WRITE_CHANS 3
6445 6450