/*
* Copyright (c) 2003-2012 Broadcom Corporation
* All Rights Reserved
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the Broadcom
* license below:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/phy.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/smp.h>
#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/mipsregs.h>
/*
* fmn.h - For FMN credit configuration and registering fmn_handler.
* FMN is communication mechanism that allows processing agents within
* XLR/XLS to communicate each other.
*/
#include <asm/netlogic/xlr/fmn.h>
#include "platform_net.h"
#include "xlr_net.h"
/*
* The readl/writel implementation byteswaps on XLR/XLS, so
* we need to use __raw_ IO to read the NAE registers
* because they are in the big-endian MMIO area on the SoC.
*/
static inline void xlr_nae_wreg(u32 __iomem *base, unsigned int reg, u32 val)
{
__raw_writel(val, base + reg);
}
static inline u32 xlr_nae_rdreg(u32 __iomem *base, unsigned int reg)
{
return __raw_readl(base + reg);
}
static inline void xlr_reg_update(u32 *base_addr, u32 off, u32 val, u32 mask)
{
u32 tmp;
tmp = xlr_nae_rdreg(base_addr, off);
xlr_nae_wreg(base_addr, off, (tmp & ~mask) | (val & mask));
}
#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES
static int send_to_rfr_fifo(struct xlr_net_priv *priv, void *addr)
{
struct nlm_fmn_msg msg;
int ret = 0, num_try = 0, stnid;
unsigned long paddr, mflags;
paddr = virt_to_bus(addr);
msg.msg0 = (u64)paddr & 0xffffffffe0ULL;
msg.msg1 = 0;
msg.msg2 = 0;
msg.msg3 = 0;
stnid = priv->nd->rfr_station;
do {
mflags = nlm_cop2_enable_irqsave();
ret = nlm_fmn_send(1, 0, stnid, &msg);
nlm_cop2_disable_irqrestore(mflags);
if (ret == 0)
return 0;
} while (++num_try < 10000);
netdev_err(priv->ndev, "Send to RFR failed in RX path\n");
return ret;
}
static inline unsigned char *xlr_alloc_skb(void)
{
struct sk_buff *skb;
int buf_len = sizeof(struct sk_buff *);
unsigned char *skb_data;
/* skb->data is cache aligned */
skb = alloc_skb(XLR_RX_BUF_SIZE, GFP_ATOMIC);
if (!skb)
return NULL;
skb_data = skb->data;
skb_put(skb, MAC_SKB_BACK_PTR_SIZE);
skb_pull(skb, MAC_SKB_BACK_PTR_SIZE);
memcpy(skb_data, &skb, buf_len);
return skb->data;
}
static void xlr_net_fmn_handler(int bkt, int src_stnid, int size, int code