mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Staging: sxg: Add multicast support for Sahara SXG driver
* Add multicast support for SXG driver for Alacritech's 10Gbe products. Signed-off-by: LinSysSoft Sahara Team <saharaproj@linsyssoft.com> Signed-off-by: Mithlesh Thukral <mithlesh@linsyssoft.com> Cc: Michael Miles <mmiles@alacritech.com> Cc: Christopher Harrer <charrer@alacritech.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
96e7088c9a
commit
b040b07bb0
@ -119,10 +119,8 @@ static void sxg_complete_slow_send(struct adapter_t *adapter, int irq_context);
|
|||||||
static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
||||||
struct sxg_event *Event);
|
struct sxg_event *Event);
|
||||||
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
|
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
|
||||||
/* See if we need sxg_mac_filter() in future. If not remove it
|
|
||||||
static bool sxg_mac_filter(struct adapter_t *adapter,
|
static bool sxg_mac_filter(struct adapter_t *adapter,
|
||||||
struct ether_header *EtherHdr, ushort length);
|
struct ether_header *EtherHdr, ushort length);
|
||||||
*/
|
|
||||||
static struct net_device_stats *sxg_get_stats(struct net_device * dev);
|
static struct net_device_stats *sxg_get_stats(struct net_device * dev);
|
||||||
void sxg_free_resources(struct adapter_t *adapter);
|
void sxg_free_resources(struct adapter_t *adapter);
|
||||||
void sxg_free_rcvblocks(struct adapter_t *adapter);
|
void sxg_free_rcvblocks(struct adapter_t *adapter);
|
||||||
@ -155,6 +153,7 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
|
|||||||
u32 DevAddr, u32 RegAddr, u32 Value);
|
u32 DevAddr, u32 RegAddr, u32 Value);
|
||||||
static int sxg_read_mdio_reg(struct adapter_t *adapter,
|
static int sxg_read_mdio_reg(struct adapter_t *adapter,
|
||||||
u32 DevAddr, u32 RegAddr, u32 *pValue);
|
u32 DevAddr, u32 RegAddr, u32 *pValue);
|
||||||
|
static void sxg_set_mcast_addr(struct adapter_t *adapter);
|
||||||
|
|
||||||
static unsigned int sxg_first_init = 1;
|
static unsigned int sxg_first_init = 1;
|
||||||
static char *sxg_banner =
|
static char *sxg_banner =
|
||||||
@ -1609,16 +1608,14 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
|
|||||||
#endif
|
#endif
|
||||||
/* Dumb-nic frame. See if it passes our mac filter and update stats */
|
/* Dumb-nic frame. See if it passes our mac filter and update stats */
|
||||||
|
|
||||||
/*
|
if (!sxg_mac_filter(adapter,
|
||||||
* ASK if (!sxg_mac_filter(adapter,
|
(struct ether_header *)(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)),
|
||||||
* SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
|
Event->Length)) {
|
||||||
* Event->Length)) {
|
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
|
||||||
* SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
|
Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
|
||||||
* Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
|
Event->Length, 0);
|
||||||
* Event->Length, 0);
|
goto drop;
|
||||||
* goto drop;
|
}
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
|
Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
|
||||||
SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
|
SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
|
||||||
@ -1728,7 +1725,6 @@ static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* Find out if this code will be needed in future */
|
|
||||||
/*
|
/*
|
||||||
* sxg_mac_filter
|
* sxg_mac_filter
|
||||||
*
|
*
|
||||||
@ -1743,6 +1739,7 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
struct ether_header *EtherHdr, ushort length)
|
struct ether_header *EtherHdr, ushort length)
|
||||||
{
|
{
|
||||||
bool EqualAddr;
|
bool EqualAddr;
|
||||||
|
struct net_device *dev = adapter->netdev;
|
||||||
|
|
||||||
if (SXG_MULTICAST_PACKET(EtherHdr)) {
|
if (SXG_MULTICAST_PACKET(EtherHdr)) {
|
||||||
if (SXG_BROADCAST_PACKET(EtherHdr)) {
|
if (SXG_BROADCAST_PACKET(EtherHdr)) {
|
||||||
@ -1750,8 +1747,6 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
if (adapter->MacFilter & MAC_BCAST) {
|
if (adapter->MacFilter & MAC_BCAST) {
|
||||||
adapter->Stats.DumbRcvBcastPkts++;
|
adapter->Stats.DumbRcvBcastPkts++;
|
||||||
adapter->Stats.DumbRcvBcastBytes += length;
|
adapter->Stats.DumbRcvBcastBytes += length;
|
||||||
adapter->Stats.DumbRcvPkts++;
|
|
||||||
adapter->Stats.DumbRcvBytes += length;
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1759,15 +1754,12 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
if (adapter->MacFilter & MAC_ALLMCAST) {
|
if (adapter->MacFilter & MAC_ALLMCAST) {
|
||||||
adapter->Stats.DumbRcvMcastPkts++;
|
adapter->Stats.DumbRcvMcastPkts++;
|
||||||
adapter->Stats.DumbRcvMcastBytes += length;
|
adapter->Stats.DumbRcvMcastBytes += length;
|
||||||
adapter->Stats.DumbRcvPkts++;
|
|
||||||
adapter->Stats.DumbRcvBytes += length;
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
if (adapter->MacFilter & MAC_MCAST) {
|
if (adapter->MacFilter & MAC_MCAST) {
|
||||||
struct sxg_multicast_address *MulticastAddrs =
|
struct dev_mc_list *mclist = dev->mc_list;
|
||||||
adapter->MulticastAddrs;
|
while (mclist) {
|
||||||
while (MulticastAddrs) {
|
ETHER_EQ_ADDR(mclist->da_addr,
|
||||||
ETHER_EQ_ADDR(MulticastAddrs->Address,
|
|
||||||
EtherHdr->ether_dhost,
|
EtherHdr->ether_dhost,
|
||||||
EqualAddr);
|
EqualAddr);
|
||||||
if (EqualAddr) {
|
if (EqualAddr) {
|
||||||
@ -1775,12 +1767,9 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
DumbRcvMcastPkts++;
|
DumbRcvMcastPkts++;
|
||||||
adapter->Stats.
|
adapter->Stats.
|
||||||
DumbRcvMcastBytes += length;
|
DumbRcvMcastBytes += length;
|
||||||
adapter->Stats.DumbRcvPkts++;
|
|
||||||
adapter->Stats.DumbRcvBytes +=
|
|
||||||
length;
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
MulticastAddrs = MulticastAddrs->Next;
|
mclist = mclist->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1792,20 +1781,15 @@ static bool sxg_mac_filter(struct adapter_t *adapter,
|
|||||||
*/
|
*/
|
||||||
adapter->Stats.DumbRcvUcastPkts++;
|
adapter->Stats.DumbRcvUcastPkts++;
|
||||||
adapter->Stats.DumbRcvUcastBytes += length;
|
adapter->Stats.DumbRcvUcastBytes += length;
|
||||||
adapter->Stats.DumbRcvPkts++;
|
|
||||||
adapter->Stats.DumbRcvBytes += length;
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
if (adapter->MacFilter & MAC_PROMISC) {
|
if (adapter->MacFilter & MAC_PROMISC) {
|
||||||
/* Whatever it is, keep it. */
|
/* Whatever it is, keep it. */
|
||||||
adapter->Stats.DumbRcvPkts++;
|
|
||||||
adapter->Stats.DumbRcvBytes += length;
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
adapter->Stats.RcvDiscards++;
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
static int sxg_register_interrupt(struct adapter_t *adapter)
|
static int sxg_register_interrupt(struct adapter_t *adapter)
|
||||||
{
|
{
|
||||||
if (!adapter->intrregistered) {
|
if (!adapter->intrregistered) {
|
||||||
@ -1885,24 +1869,24 @@ static int sxg_if_init(struct adapter_t *adapter)
|
|||||||
ASSERT(adapter->linkstate == LINK_DOWN);
|
ASSERT(adapter->linkstate == LINK_DOWN);
|
||||||
|
|
||||||
adapter->devflags_prev = dev->flags;
|
adapter->devflags_prev = dev->flags;
|
||||||
adapter->macopts = MAC_DIRECTED;
|
adapter->MacFilter = MAC_DIRECTED;
|
||||||
if (dev->flags) {
|
if (dev->flags) {
|
||||||
DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
|
DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
|
||||||
adapter->netdev->name);
|
adapter->netdev->name);
|
||||||
if (dev->flags & IFF_BROADCAST) {
|
if (dev->flags & IFF_BROADCAST) {
|
||||||
adapter->macopts |= MAC_BCAST;
|
adapter->MacFilter |= MAC_BCAST;
|
||||||
DBG_ERROR("BCAST ");
|
DBG_ERROR("BCAST ");
|
||||||
}
|
}
|
||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
adapter->macopts |= MAC_PROMISC;
|
adapter->MacFilter |= MAC_PROMISC;
|
||||||
DBG_ERROR("PROMISC ");
|
DBG_ERROR("PROMISC ");
|
||||||
}
|
}
|
||||||
if (dev->flags & IFF_ALLMULTI) {
|
if (dev->flags & IFF_ALLMULTI) {
|
||||||
adapter->macopts |= MAC_ALLMCAST;
|
adapter->MacFilter |= MAC_ALLMCAST;
|
||||||
DBG_ERROR("ALL_MCAST ");
|
DBG_ERROR("ALL_MCAST ");
|
||||||
}
|
}
|
||||||
if (dev->flags & IFF_MULTICAST) {
|
if (dev->flags & IFF_MULTICAST) {
|
||||||
adapter->macopts |= MAC_MCAST;
|
adapter->MacFilter |= MAC_MCAST;
|
||||||
DBG_ERROR("MCAST ");
|
DBG_ERROR("MCAST ");
|
||||||
}
|
}
|
||||||
DBG_ERROR("\n");
|
DBG_ERROR("\n");
|
||||||
@ -3036,9 +3020,7 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
|
|||||||
* complemented), we must then transpose the value and return bits 30-23.
|
* complemented), we must then transpose the value and return bits 30-23.
|
||||||
*/
|
*/
|
||||||
static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */
|
static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */
|
||||||
#if XXXTODO
|
|
||||||
static u32 sxg_crc_init; /* Is table initialized */
|
static u32 sxg_crc_init; /* Is table initialized */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Contruct the CRC32 table */
|
/* Contruct the CRC32 table */
|
||||||
static void sxg_mcast_init_crc32(void)
|
static void sxg_mcast_init_crc32(void)
|
||||||
@ -3063,7 +3045,6 @@ static void sxg_mcast_init_crc32(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XXXTODO
|
|
||||||
/*
|
/*
|
||||||
* Return the MAC hast as described above.
|
* Return the MAC hast as described above.
|
||||||
*/
|
*/
|
||||||
@ -3091,13 +3072,12 @@ static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
|
|||||||
|
|
||||||
return (machash);
|
return (machash);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void sxg_mcast_set_mask(struct adapter_t *adapter)
|
static void sxg_mcast_set_mask(struct adapter_t *adapter)
|
||||||
{
|
{
|
||||||
struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
|
struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
|
||||||
|
|
||||||
DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
|
DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __FUNCTION__,
|
||||||
adapter->netdev->name, (unsigned int)adapter->MacFilter,
|
adapter->netdev->name, (unsigned int)adapter->MacFilter,
|
||||||
adapter->MulticastMask);
|
adapter->MulticastMask);
|
||||||
|
|
||||||
@ -3107,7 +3087,7 @@ static void sxg_mcast_set_mask(struct adapter_t *adapter)
|
|||||||
* promiscuous mode as well as ALLMCAST mode. It saves the
|
* promiscuous mode as well as ALLMCAST mode. It saves the
|
||||||
* Microcode from having keep state about the MAC configuration
|
* Microcode from having keep state about the MAC configuration
|
||||||
*/
|
*/
|
||||||
/* DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n
|
/* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \
|
||||||
* SLUT MODE!!!\n",__func__);
|
* SLUT MODE!!!\n",__func__);
|
||||||
*/
|
*/
|
||||||
WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
|
WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
|
||||||
@ -3135,39 +3115,6 @@ static void sxg_mcast_set_mask(struct adapter_t *adapter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XXXTODO
|
|
||||||
/*
|
|
||||||
* Allocate a mcast_address structure to hold the multicast address.
|
|
||||||
* Link it in.
|
|
||||||
*/
|
|
||||||
static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
|
|
||||||
{
|
|
||||||
struct mcast_address *mcaddr, *mlist;
|
|
||||||
bool equaladdr;
|
|
||||||
|
|
||||||
/* Check to see if it already exists */
|
|
||||||
mlist = adapter->mcastaddrs;
|
|
||||||
while (mlist) {
|
|
||||||
ETHER_EQ_ADDR(mlist->address, address, equaladdr);
|
|
||||||
if (equaladdr) {
|
|
||||||
return (STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
mlist = mlist->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Doesn't already exist. Allocate a structure to hold it */
|
|
||||||
mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
|
|
||||||
if (mcaddr == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
memcpy(mcaddr->address, address, 6);
|
|
||||||
|
|
||||||
mcaddr->next = adapter->mcastaddrs;
|
|
||||||
adapter->mcastaddrs = mcaddr;
|
|
||||||
|
|
||||||
return (STATUS_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
|
static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
|
||||||
{
|
{
|
||||||
unsigned char crcpoly;
|
unsigned char crcpoly;
|
||||||
@ -3184,7 +3131,25 @@ static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
|
|||||||
/* OR in the new bit into our 64 bit mask. */
|
/* OR in the new bit into our 64 bit mask. */
|
||||||
adapter->MulticastMask |= (u64) 1 << crcpoly;
|
adapter->MulticastMask |= (u64) 1 << crcpoly;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/*
|
||||||
|
* Function takes MAC addresses from dev_mc_list and generates the Mask
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void sxg_set_mcast_addr(struct adapter_t *adapter)
|
||||||
|
{
|
||||||
|
struct dev_mc_list *mclist;
|
||||||
|
struct net_device *dev = adapter->netdev;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) {
|
||||||
|
for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
|
||||||
|
i++, mclist = mclist->next) {
|
||||||
|
sxg_mcast_set_bit(adapter,mclist->da_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sxg_mcast_set_mask(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
static void sxg_mcast_set_list(struct net_device *dev)
|
static void sxg_mcast_set_list(struct net_device *dev)
|
||||||
{
|
{
|
||||||
@ -3194,8 +3159,16 @@ static void sxg_mcast_set_list(struct net_device *dev)
|
|||||||
if (dev->flags & IFF_PROMISC) {
|
if (dev->flags & IFF_PROMISC) {
|
||||||
adapter->MacFilter |= MAC_PROMISC;
|
adapter->MacFilter |= MAC_PROMISC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->flags & IFF_MULTICAST)
|
||||||
|
adapter->MacFilter |= MAC_MCAST;
|
||||||
|
|
||||||
|
if (dev->flags & IFF_ALLMULTI) {
|
||||||
|
adapter->MacFilter |= MAC_ALLMCAST;
|
||||||
|
}
|
||||||
|
|
||||||
//XXX handle other flags as well
|
//XXX handle other flags as well
|
||||||
sxg_mcast_set_mask(adapter);
|
sxg_set_mcast_addr(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XXXTODO
|
#if XXXTODO
|
||||||
|
@ -99,9 +99,9 @@ static struct sxg_nic_stats sxg_nic_gstrings_stats[] = {
|
|||||||
/* May be need in future */
|
/* May be need in future */
|
||||||
/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)},
|
/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)},
|
||||||
{"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)},
|
{"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)},
|
||||||
{"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)},
|
*/ {"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)},
|
||||||
{"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)},
|
{"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)},
|
||||||
{"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)},
|
/* {"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)},
|
||||||
{"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)},
|
{"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)},
|
||||||
*/
|
*/
|
||||||
{"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)},
|
{"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user