aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAjit Khaparde <ajitkhaparde@gmail.com>2010-02-08 20:34:57 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-12 15:27:59 -0500
commit82903e4bfca1578336a91c0c17839b484c12295d (patch)
tree05788518e497b647076fcbb6d8d068b86ae17316 /drivers
parent205859a2ff922d0587a819b08007398cbd0a6a30 (diff)
be2net: fix to limit max vlans supported in certain skews
In certain skews the ASIC can support only 16 vlans per interface. Once the limit is crossed, the ASIC is programmed in vlan promiscuous mode. Switch off the vlan promiscuous mode once the number of vlans falls back to the max vlans supported. Signed-off-by: Ajit Khaparde <ajitk@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/benet/be.h3
-rw-r--r--drivers/net/benet/be_main.c30
2 files changed, 19 insertions, 14 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 242013157f20..476a5c455794 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -250,7 +250,8 @@ struct be_adapter {
250 bool rx_post_starved; /* Zero rx frags have been posted to BE */ 250 bool rx_post_starved; /* Zero rx frags have been posted to BE */
251 251
252 struct vlan_group *vlan_grp; 252 struct vlan_group *vlan_grp;
253 u16 num_vlans; 253 u16 vlans_added;
254 u16 max_vlans; /* Number of vlans supported */
254 u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; 255 u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
255 struct be_dma_mem mc_cmd_mem; 256 struct be_dma_mem mc_cmd_mem;
256 257
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 1951d7620a88..92c55f679466 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -488,17 +488,16 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
488} 488}
489 489
490/* 490/*
491 * if there are BE_NUM_VLANS_SUPPORTED or lesser number of VLANS configured, 491 * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE.
492 * program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured, 492 * If the user configures more, place BE in vlan promiscuous mode.
493 * set the BE in promiscuous VLAN mode.
494 */ 493 */
495static int be_vid_config(struct be_adapter *adapter) 494static int be_vid_config(struct be_adapter *adapter)
496{ 495{
497 u16 vtag[BE_NUM_VLANS_SUPPORTED]; 496 u16 vtag[BE_NUM_VLANS_SUPPORTED];
498 u16 ntags = 0, i; 497 u16 ntags = 0, i;
499 int status; 498 int status = 0;
500 499
501 if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED) { 500 if (adapter->vlans_added <= adapter->max_vlans) {
502 /* Construct VLAN Table to give to HW */ 501 /* Construct VLAN Table to give to HW */
503 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { 502 for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
504 if (adapter->vlan_tag[i]) { 503 if (adapter->vlan_tag[i]) {
@@ -532,21 +531,21 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
532{ 531{
533 struct be_adapter *adapter = netdev_priv(netdev); 532 struct be_adapter *adapter = netdev_priv(netdev);
534 533
535 adapter->num_vlans++;
536 adapter->vlan_tag[vid] = 1; 534 adapter->vlan_tag[vid] = 1;
537 535 adapter->vlans_added++;
538 be_vid_config(adapter); 536 if (adapter->vlans_added <= (adapter->max_vlans + 1))
537 be_vid_config(adapter);
539} 538}
540 539
541static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) 540static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
542{ 541{
543 struct be_adapter *adapter = netdev_priv(netdev); 542 struct be_adapter *adapter = netdev_priv(netdev);
544 543
545 adapter->num_vlans--;
546 adapter->vlan_tag[vid] = 0; 544 adapter->vlan_tag[vid] = 0;
547
548 vlan_group_set_device(adapter->vlan_grp, vid, NULL); 545 vlan_group_set_device(adapter->vlan_grp, vid, NULL);
549 be_vid_config(adapter); 546 adapter->vlans_added--;
547 if (adapter->vlans_added <= adapter->max_vlans)
548 be_vid_config(adapter);
550} 549}
551 550
552static void be_set_multicast_list(struct net_device *netdev) 551static void be_set_multicast_list(struct net_device *netdev)
@@ -786,7 +785,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
786 skb->dev = adapter->netdev; 785 skb->dev = adapter->netdev;
787 786
788 if (vlanf) { 787 if (vlanf) {
789 if (!adapter->vlan_grp || adapter->num_vlans == 0) { 788 if (!adapter->vlan_grp || adapter->vlans_added == 0) {
790 kfree_skb(skb); 789 kfree_skb(skb);
791 return; 790 return;
792 } 791 }
@@ -866,7 +865,7 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
866 vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); 865 vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
867 vid = be16_to_cpu(vid); 866 vid = be16_to_cpu(vid);
868 867
869 if (!adapter->vlan_grp || adapter->num_vlans == 0) 868 if (!adapter->vlan_grp || adapter->vlans_added == 0)
870 return; 869 return;
871 870
872 vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); 871 vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
@@ -2241,6 +2240,11 @@ static int be_get_config(struct be_adapter *adapter)
2241 memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); 2240 memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
2242 memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); 2241 memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
2243 2242
2243 if (adapter->cap & 0x400)
2244 adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/4;
2245 else
2246 adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
2247
2244 return 0; 2248 return 0;
2245} 2249}
2246 2250