Skip to content

Commit

Permalink
sky2: accept multicast pause frames
Browse files Browse the repository at this point in the history
When using flow control, the PHY needs to accept multicast pause frames.
Without this fix, these frames were getting discarded by the PHY before
doing any flow control.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
  • Loading branch information
Stephen Hemminger committed Oct 17, 2006
1 parent 52c89ca commit a052b52
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions drivers/net/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2850,6 +2850,14 @@ static int sky2_set_mac_address(struct net_device *dev, void *p)
return 0;
}

static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
{
u32 bit;

bit = ether_crc(ETH_ALEN, addr) & 63;
filter[bit >> 3] |= 1 << (bit & 7);
}

static void sky2_set_multicast(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
Expand All @@ -2858,26 +2866,30 @@ static void sky2_set_multicast(struct net_device *dev)
struct dev_mc_list *list = dev->mc_list;
u16 reg;
u8 filter[8];
int rx_pause;
static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0, 0x1 };

rx_pause = (sky2->flow_status == FC_RX || sky2->flow_status == FC_BOTH);
memset(filter, 0, sizeof(filter));

reg = gma_read16(hw, port, GM_RX_CTRL);
reg |= GM_RXCR_UCF_ENA;

if (dev->flags & IFF_PROMISC) /* promiscuous */
reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16) /* all multicast */
else if (dev->flags & IFF_ALLMULTI)
memset(filter, 0xff, sizeof(filter));
else if (dev->mc_count == 0) /* no multicast */
else if (dev->mc_count == 0 && !rx_pause)
reg &= ~GM_RXCR_MCF_ENA;
else {
int i;
reg |= GM_RXCR_MCF_ENA;

for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
filter[bit / 8] |= 1 << (bit % 8);
}
if (rx_pause)
sky2_add_filter(filter, pause_mc_addr);

for (i = 0; list && i < dev->mc_count; i++, list = list->next)
sky2_add_filter(filter, list->dmi_addr);
}

gma_write16(hw, port, GM_MC_ADDR_H1,
Expand Down

0 comments on commit a052b52

Please sign in to comment.