Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 279108
b: refs/heads/master
c: c0d2b83
h: refs/heads/master
v: v3
  • Loading branch information
Joshua Kinard authored and David S. Miller committed Dec 27, 2011
1 parent eb501a5 commit 0e4fa22
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 65cb5df51acaa6b1070a81d6c2e0a1535d3a7b8d
refs/heads/master: c0d2b8376ae2d74aa862e946a372502603e9066d
2 changes: 1 addition & 1 deletion trunk/arch/mips/include/asm/ip32/mace.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ struct mace_video {
* Ethernet interface
*/
struct mace_ethernet {
volatile unsigned long mac_ctrl;
volatile u64 mac_ctrl;
volatile unsigned long int_stat;
volatile unsigned long dma_ctrl;
volatile unsigned long timer;
Expand Down
48 changes: 47 additions & 1 deletion trunk/drivers/net/ethernet/sgi/meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/tcp.h> /* struct tcphdr */
#include <linux/skbuff.h>
#include <linux/mii.h> /* MII definitions */
#include <linux/crc32.h>

#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
Expand Down Expand Up @@ -57,13 +58,20 @@ static const char *meth_str="SGI O2 Fast Ethernet";
static int timeout = TX_TIMEOUT;
module_param(timeout, int, 0);

/*
* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
* MACE Ethernet uses a 64 element hash table based on the Ethernet CRC.
*/
#define METH_MCF_LIMIT 32

/*
* This structure is private to each device. It is used to pass
* packets in and out, so there is place for a packet
*/
struct meth_private {
/* in-memory copy of MAC Control register */
unsigned long mac_ctrl;
u64 mac_ctrl;

/* in-memory copy of DMA Control register */
unsigned long dma_ctrl;
/* address of PHY, used by mdio_* functions, initialized in mdio_probe */
Expand All @@ -79,6 +87,9 @@ struct meth_private {
struct sk_buff *rx_skbs[RX_RING_ENTRIES];
unsigned long rx_write;

/* Multicast filter. */
u64 mcast_filter;

spinlock_t meth_lock;
};

Expand Down Expand Up @@ -765,6 +776,40 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
}
}

static void meth_set_rx_mode(struct net_device *dev)
{
struct meth_private *priv = netdev_priv(dev);
unsigned long flags;

netif_stop_queue(dev);
spin_lock_irqsave(&priv->meth_lock, flags);
priv->mac_ctrl &= ~METH_PROMISC;

if (dev->flags & IFF_PROMISC) {
priv->mac_ctrl |= METH_PROMISC;
priv->mcast_filter = 0xffffffffffffffffUL;
} else if ((netdev_mc_count(dev) > METH_MCF_LIMIT) ||
(dev->flags & IFF_ALLMULTI)) {
priv->mac_ctrl |= METH_ACCEPT_AMCAST;
priv->mcast_filter = 0xffffffffffffffffUL;
} else {
struct netdev_hw_addr *ha;
priv->mac_ctrl |= METH_ACCEPT_MCAST;

netdev_for_each_mc_addr(ha, dev)
set_bit((ether_crc(ETH_ALEN, ha->addr) >> 26),
(volatile unsigned long *)&priv->mcast_filter);
}

/* Write the changes to the chip registers. */
mace->eth.mac_ctrl = priv->mac_ctrl;
mace->eth.mcast_filter = priv->mcast_filter;

/* Done! */
spin_unlock_irqrestore(&priv->meth_lock, flags);
netif_wake_queue(dev);
}

static const struct net_device_ops meth_netdev_ops = {
.ndo_open = meth_open,
.ndo_stop = meth_release,
Expand All @@ -774,6 +819,7 @@ static const struct net_device_ops meth_netdev_ops = {
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
.ndo_set_rx_mode = meth_set_rx_mode,
};

/*
Expand Down

0 comments on commit 0e4fa22

Please sign in to comment.