mirror of https://github.com/hak5/openwrt.git
2095 lines
72 KiB
Diff
2095 lines
72 KiB
Diff
|
--- a/drivers/net/sl351x_gmac.c
|
||
|
+++ b/drivers/net/sl351x_gmac.c
|
||
|
@@ -43,9 +43,13 @@
|
||
|
|
||
|
#include <linux/mtd/kvctl.h>
|
||
|
|
||
|
+#define GET_RPTR(x) ((x) & 0xFFFF)
|
||
|
+#define GET_WPTR(x) ((x) >> 16)
|
||
|
+
|
||
|
#define MIDWAY
|
||
|
#define SL_LEPUS
|
||
|
-#define VITESSE_G5SWITCH 1
|
||
|
+// #define VITESSE_G5SWITCH 1
|
||
|
+#undef VITESSE_G5SWITCH
|
||
|
|
||
|
#ifndef CONFIG_SL351x_RXTOE
|
||
|
//#define CONFIG_SL351x_RXTOE 1
|
||
|
@@ -126,7 +130,6 @@
|
||
|
*************************************************************/
|
||
|
static int gmac_initialized = 0;
|
||
|
TOE_INFO_T toe_private_data;
|
||
|
-static int do_again = 0;
|
||
|
static int rx_poll_enabled;
|
||
|
spinlock_t gmac_fq_lock;
|
||
|
unsigned int FLAG_SWITCH;
|
||
|
@@ -190,7 +193,7 @@
|
||
|
void mac_set_sw_tx_weight(struct net_device *dev, char *weight);
|
||
|
void mac_get_hw_tx_weight(struct net_device *dev, char *weight);
|
||
|
void mac_set_hw_tx_weight(struct net_device *dev, char *weight);
|
||
|
-static inline void toe_gmac_fill_free_q(void);
|
||
|
+static inline void toe_gmac_fill_free_q(int count);
|
||
|
|
||
|
#ifdef VITESSE_G5SWITCH
|
||
|
extern int Get_Set_port_status(void);
|
||
|
@@ -295,12 +298,14 @@
|
||
|
for(j = 0; i<CONFIG_MAC_NUM; j++)
|
||
|
{
|
||
|
i=j;
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
if(Giga_switch){ // if gswitch present, swap eth0/1
|
||
|
if(j==0)
|
||
|
i=1;
|
||
|
else if(j==1)
|
||
|
i=0;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
tp = (GMAC_INFO_T *)&toe_private_data.gmac[i];
|
||
|
tp->dev = NULL;
|
||
|
@@ -459,7 +464,7 @@
|
||
|
toe->gmac[1].dma_base_addr = TOE_GMAC1_DMA_BASE;
|
||
|
toe->gmac[0].auto_nego_cfg = 1;
|
||
|
toe->gmac[1].auto_nego_cfg = 1;
|
||
|
-#ifdef CONFIG_SL3516_ASIC
|
||
|
+#ifndef CONFIG_SL3516_ASIC
|
||
|
toe->gmac[0].speed_cfg = GMAC_SPEED_1000;
|
||
|
toe->gmac[1].speed_cfg = GMAC_SPEED_1000;
|
||
|
#else
|
||
|
@@ -508,7 +513,7 @@
|
||
|
// Write GLOBAL_QUEUE_THRESHOLD_REG
|
||
|
threshold.bits32 = 0;
|
||
|
threshold.bits.swfq_empty = (TOE_SW_FREEQ_DESC_NUM > 256) ? 255 :
|
||
|
- TOE_SW_FREEQ_DESC_NUM/2;
|
||
|
+ TOE_SW_FREEQ_DESC_NUM/16;
|
||
|
threshold.bits.hwfq_empty = (TOE_HW_FREEQ_DESC_NUM > 256) ? 256/4 :
|
||
|
TOE_HW_FREEQ_DESC_NUM/4;
|
||
|
threshold.bits.toe_class = (TOE_TOE_DESC_NUM > 256) ? 256/4 :
|
||
|
@@ -613,18 +618,25 @@
|
||
|
rwptr_reg.bits.rptr = 0;
|
||
|
toe->fq_rx_rwptr.bits32 = rwptr_reg.bits32;
|
||
|
writel(rwptr_reg.bits32, TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
+ printk("SWFQ: %08X\n", readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG));
|
||
|
|
||
|
// SW Free Queue Descriptors
|
||
|
for (i=0; i<TOE_SW_FREEQ_DESC_NUM; i++)
|
||
|
{
|
||
|
+ void *data = NULL;
|
||
|
sw_desc_ptr->word0.bits.buffer_size = SW_RX_BUF_SIZE;
|
||
|
- sw_desc_ptr->word1.bits.sw_id = i; // used to locate skb
|
||
|
+ sw_desc_ptr->word1.bits.sw_id = 0; // used to locate skb
|
||
|
if ( (skb = dev_alloc_skb(SW_RX_BUF_SIZE))==NULL) /* allocate socket buffer */
|
||
|
{
|
||
|
printk("%s::skb buffer allocation fail !\n",__func__); while(1);
|
||
|
}
|
||
|
- REG32(skb->data) = (unsigned int)skb;
|
||
|
+
|
||
|
+ data = skb->data;
|
||
|
skb_reserve(skb, SKB_RESERVE_BYTES);
|
||
|
+
|
||
|
+ REG32(data + 0) = (unsigned int)skb;
|
||
|
+ REG32(data + 4) = (unsigned short)i;
|
||
|
+
|
||
|
// toe->rx_skb[i] = skb;
|
||
|
sw_desc_ptr->word2.buf_adr = (unsigned int)__pa(skb->data);
|
||
|
// consistent_sync((unsigned int)desc_ptr, sizeof(GMAC_RXDESC_T), PCI_DMA_TODEVICE);
|
||
|
@@ -851,14 +863,14 @@
|
||
|
*----------------------------------------------------------------------*/
|
||
|
static void toe_init_default_queue(void)
|
||
|
{
|
||
|
- TOE_INFO_T *toe;
|
||
|
+ TOE_INFO_T *toe;
|
||
|
volatile NONTOE_QHDR_T *qhdr;
|
||
|
- GMAC_RXDESC_T *desc_ptr;
|
||
|
- DMA_SKB_SIZE_T skb_size;
|
||
|
+ GMAC_RXDESC_T *desc_ptr;
|
||
|
+ DMA_SKB_SIZE_T skb_size;
|
||
|
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T)),
|
||
|
- (dma_addr_t *)&toe->gmac[0].default_desc_base_dma);
|
||
|
+ (dma_addr_t *)&toe->gmac[0].default_desc_base_dma);
|
||
|
if (!desc_ptr)
|
||
|
{
|
||
|
printk("%s::DMA_MALLOC fail !\n",__func__);
|
||
|
@@ -866,14 +878,17 @@
|
||
|
}
|
||
|
memset((void *)desc_ptr, 0, TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T));
|
||
|
toe->gmac[0].default_desc_base = (unsigned int)desc_ptr;
|
||
|
+ printk("toe->gmac[0].default_desc_base_dma: %08X\n", toe->gmac[0].default_desc_base_dma);
|
||
|
+
|
||
|
toe->gmac[0].default_desc_num = TOE_DEFAULT_Q0_DESC_NUM;
|
||
|
qhdr = (volatile NONTOE_QHDR_T *)TOE_DEFAULT_Q0_HDR_BASE;
|
||
|
qhdr->word0.base_size = ((unsigned int)toe->gmac[0].default_desc_base_dma & NONTOE_QHDR0_BASE_MASK) | TOE_DEFAULT_Q0_DESC_POWER;
|
||
|
qhdr->word1.bits32 = 0;
|
||
|
toe->gmac[0].rx_rwptr.bits32 = 0;
|
||
|
toe->gmac[0].default_qhdr = (NONTOE_QHDR_T *)qhdr;
|
||
|
+
|
||
|
desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q1_DESC_NUM * sizeof(GMAC_RXDESC_T)),
|
||
|
- (dma_addr_t *)&toe->gmac[1].default_desc_base_dma);
|
||
|
+ (dma_addr_t *)&toe->gmac[1].default_desc_base_dma);
|
||
|
if (!desc_ptr)
|
||
|
{
|
||
|
printk("%s::DMA_MALLOC fail !\n",__func__);
|
||
|
@@ -1071,12 +1086,16 @@
|
||
|
|
||
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) & ~tp->intr0_selected;
|
||
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
|
||
|
+
|
||
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG) & ~tp->intr1_selected;
|
||
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG);
|
||
|
+
|
||
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG) & ~tp->intr2_selected;
|
||
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG);
|
||
|
+
|
||
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG) & ~tp->intr3_selected;
|
||
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG);
|
||
|
+
|
||
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG) & ~tp->intr4_selected;
|
||
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
}
|
||
|
@@ -1176,11 +1195,11 @@
|
||
|
GMAC_CONFIG2_T config2_val;
|
||
|
GMAC_CONFIG0_T config0,config0_mask;
|
||
|
GMAC_CONFIG1_T config1;
|
||
|
- #ifdef CONFIG_SL351x_NAT
|
||
|
GMAC_CONFIG3_T config3_val;
|
||
|
- #endif
|
||
|
GMAC_TX_WCR0_T hw_weigh;
|
||
|
GMAC_TX_WCR1_T sw_weigh;
|
||
|
+
|
||
|
+ uint32_t weight = 0;
|
||
|
// GMAC_HASH_ENABLE_REG0_T hash_ctrl;
|
||
|
//
|
||
|
#if 0 /* mac address will be set in late_initcall */
|
||
|
@@ -1202,24 +1221,23 @@
|
||
|
// config1.bits32 = 0x002004; //next version
|
||
|
/* set flow control threshold */
|
||
|
config1.bits32 = 0;
|
||
|
- config1.bits.set_threshold = 32 / 2;
|
||
|
- config1.bits.rel_threshold = 32 / 4 * 3;
|
||
|
+ config1.bits.set_threshold = (32 / 2);
|
||
|
+ config1.bits.rel_threshold = (32 / 4) * 3;
|
||
|
gmac_write_reg(tp->base_addr, GMAC_CONFIG1, config1.bits32, 0xffffffff);
|
||
|
|
||
|
- /* set flow control threshold */
|
||
|
+ /* TODO: set flow control threshold */
|
||
|
config2_val.bits32 = 0;
|
||
|
- config2_val.bits.set_threshold = TOE_SW_FREEQ_DESC_NUM/2;
|
||
|
- config2_val.bits.rel_threshold = TOE_SW_FREEQ_DESC_NUM*3/4;
|
||
|
+ config2_val.bits.set_threshold = TOE_SW_FREEQ_DESC_NUM/4;
|
||
|
+ config2_val.bits.rel_threshold = TOE_SW_FREEQ_DESC_NUM/2;
|
||
|
gmac_write_reg(tp->base_addr, GMAC_CONFIG2, config2_val.bits32,0xffffffff);
|
||
|
|
||
|
- #ifdef CONFIG_SL351x_NAT
|
||
|
- /* set HW free queue flow control threshold */
|
||
|
+ /* TODO: set HW free queue flow control threshold */
|
||
|
config3_val.bits32 = 0;
|
||
|
config3_val.bits.set_threshold = PAUSE_SET_HW_FREEQ;
|
||
|
config3_val.bits.rel_threshold = PAUSE_REL_HW_FREEQ;
|
||
|
gmac_write_reg(tp->base_addr, GMAC_CONFIG3, config3_val.bits32,0xffffffff);
|
||
|
- #endif
|
||
|
- /* set_mcast_filter mask*/
|
||
|
+
|
||
|
+ /* TODO: set_mcast_filter mask*/
|
||
|
// gmac_write_reg(tp->base_addr,GMAC_MCAST_FIL0,0x0,0xffffffff);
|
||
|
// gmac_write_reg(tp->base_addr,GMAC_MCAST_FIL1,0x0,0xffffffff);
|
||
|
|
||
|
@@ -1249,7 +1267,7 @@
|
||
|
config0.bits.dis_rx = 1; /* disable rx */
|
||
|
config0.bits.dis_tx = 1; /* disable tx */
|
||
|
config0.bits.loop_back = 0; /* enable/disable GMAC loopback */
|
||
|
- config0.bits.rx_err_detect = 1;
|
||
|
+ config0.bits.rx_err_detect = 1; /* TODO: was 1, means disabled, 0 enabled ! */
|
||
|
config0.bits.rgmii_en = 0;
|
||
|
config0.bits.rgmm_edge = 1;
|
||
|
config0.bits.rxc_inv = 0;
|
||
|
@@ -1342,6 +1360,9 @@
|
||
|
gmac_write_reg(tp->dma_base_addr, GMAC_AHB_WEIGHT_REG, ahb_weight.bits32, ahb_weight_mask.bits32);
|
||
|
#endif
|
||
|
|
||
|
+ weight = gmac_read_reg(tp->dma_base_addr, GMAC_AHB_WEIGHT_REG);
|
||
|
+ printk("====> %08X\n", weight);
|
||
|
+
|
||
|
#if defined(CONFIG_SL351x_NAT) || defined(CONFIG_SL351x_RXTOE)
|
||
|
gmac_write_reg(tp->dma_base_addr, GMAC_SPR0, IPPROTO_TCP, 0xffffffff);
|
||
|
#endif
|
||
|
@@ -1552,7 +1573,7 @@
|
||
|
rwptr.bits32 = readl(swtxq->rwptr_reg);
|
||
|
if (rwptr.bits.rptr == swtxq->finished_idx)
|
||
|
break;
|
||
|
- curr_desc = (volatile GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
|
||
|
+ curr_desc = (volatile GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
|
||
|
// consistent_sync((void *)curr_desc, sizeof(GMAC_TXDESC_T), PCI_DMA_FROMDEVICE);
|
||
|
word0.bits32 = curr_desc->word0.bits32;
|
||
|
word1.bits32 = curr_desc->word1.bits32;
|
||
|
@@ -1573,6 +1594,7 @@
|
||
|
swtxq->finished_idx = RWPTR_ADVANCE_ONE(swtxq->finished_idx, swtxq->total_desc_num);
|
||
|
curr_desc = (GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
|
||
|
word0.bits32 = curr_desc->word0.bits32;
|
||
|
+
|
||
|
#ifdef _DUMP_TX_TCP_CONTENT
|
||
|
if (curr_desc->word0.bits.buffer_size < 16)
|
||
|
{
|
||
|
@@ -1592,12 +1614,12 @@
|
||
|
word0.bits.status_tx_ok = 0;
|
||
|
if (swtxq->tx_skb[swtxq->finished_idx])
|
||
|
{
|
||
|
- if (interrupt)
|
||
|
- dev_kfree_skb_irq(swtxq->tx_skb[swtxq->finished_idx]);
|
||
|
- else
|
||
|
- dev_kfree_skb(swtxq->tx_skb[swtxq->finished_idx]);
|
||
|
+ dev_kfree_skb(swtxq->tx_skb[swtxq->finished_idx]);
|
||
|
swtxq->tx_skb[swtxq->finished_idx] = NULL;
|
||
|
+ } else {
|
||
|
+ BUG();
|
||
|
}
|
||
|
+
|
||
|
curr_desc->word0.bits32 = word0.bits32;
|
||
|
swtxq->curr_finished_desc = (GMAC_TXDESC_T *)curr_desc;
|
||
|
swtxq->total_finished++;
|
||
|
@@ -1624,31 +1646,29 @@
|
||
|
*----------------------------------------------------------------------*/
|
||
|
static int gmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||
|
{
|
||
|
- GMAC_INFO_T *tp= dev->priv;
|
||
|
-// static unsigned int pcount = 0;
|
||
|
-// unsigned int tx_qid;
|
||
|
- DMA_RWPTR_T rwptr;
|
||
|
- volatile GMAC_TXDESC_T *curr_desc;
|
||
|
- int snd_pages = skb_shinfo(skb)->nr_frags + 1; /* get number of descriptor */
|
||
|
- int frag_id = 0;
|
||
|
- int len, total_len = skb->len;
|
||
|
+ GMAC_INFO_T *tp= dev->priv;
|
||
|
+ DMA_RWPTR_T rwptr;
|
||
|
+ GMAC_TXDESC_T *curr_desc;
|
||
|
+ int snd_pages = skb_shinfo(skb)->nr_frags + 1; /* get number of descriptor */
|
||
|
+ int frag_id = 0;
|
||
|
+ int len, total_len = skb->len;
|
||
|
struct net_device_stats *isPtr;
|
||
|
- unsigned int free_desc;
|
||
|
- GMAC_SWTXQ_T *swtxq;
|
||
|
+ unsigned int free_desc;
|
||
|
+ GMAC_SWTXQ_T *swtxq;
|
||
|
register unsigned long word0, word1, word2, word3;
|
||
|
unsigned short wptr, rptr;
|
||
|
#ifdef L2_jumbo_frame
|
||
|
int header_len = skb->len;
|
||
|
struct iphdr *ip_hdr;
|
||
|
- struct tcphdr *tcp_hdr;
|
||
|
- int tcp_hdr_len;
|
||
|
- unsigned char *ptr;
|
||
|
- int data_len,a;
|
||
|
- unsigned int val;
|
||
|
+ struct tcphdr *tcp_hdr;
|
||
|
+ int tcp_hdr_len;
|
||
|
+ unsigned char *ptr;
|
||
|
+ int data_len,a;
|
||
|
+ unsigned int val;
|
||
|
#endif
|
||
|
|
||
|
#ifdef GMAC_LEN_1_2_ISSUE
|
||
|
- int total_pages;
|
||
|
+ int total_pages;
|
||
|
total_pages = snd_pages;
|
||
|
#endif
|
||
|
|
||
|
@@ -1664,13 +1684,6 @@
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
-#if 0
|
||
|
- if (storlink_ctl.recvfile==2)
|
||
|
- {
|
||
|
- printk("snd_pages=%d skb->len=%d\n",snd_pages,skb->len);
|
||
|
- }
|
||
|
-#endif
|
||
|
-
|
||
|
#ifdef GMAC_USE_TXQ0
|
||
|
#define tx_qid 0
|
||
|
#endif
|
||
|
@@ -1703,9 +1716,9 @@
|
||
|
toe_gmac_tx_complete(tp, tx_qid, dev, 0);
|
||
|
|
||
|
if (wptr >= swtxq->finished_idx)
|
||
|
- free_desc = swtxq->total_desc_num - wptr - 1 + swtxq->finished_idx;
|
||
|
+ free_desc = swtxq->total_desc_num - wptr + swtxq->finished_idx;
|
||
|
else
|
||
|
- free_desc = swtxq->finished_idx - wptr - 1;
|
||
|
+ free_desc = swtxq->finished_idx - wptr;
|
||
|
if (free_desc < snd_pages)
|
||
|
{
|
||
|
// spin_unlock(&tp->tx_mutex);
|
||
|
@@ -2063,9 +2076,10 @@
|
||
|
struct net_device_stats * gmac_get_stats(struct net_device *dev)
|
||
|
{
|
||
|
GMAC_INFO_T *tp = (GMAC_INFO_T *)dev->priv;
|
||
|
+#if 0 /* don't read stats from hardware, scary numbers. */
|
||
|
// unsigned int flags;
|
||
|
- unsigned int pkt_drop;
|
||
|
- unsigned int pkt_error;
|
||
|
+ unsigned int pkt_drop = 0;
|
||
|
+ unsigned int pkt_error = 0;
|
||
|
|
||
|
if (netif_running(dev))
|
||
|
{
|
||
|
@@ -2073,10 +2087,14 @@
|
||
|
// spin_lock_irqsave(&tp->lock,flags);
|
||
|
pkt_drop = gmac_read_reg(tp->base_addr,GMAC_IN_DISCARDS);
|
||
|
pkt_error = gmac_read_reg(tp->base_addr,GMAC_IN_ERRORS);
|
||
|
+ printk("**** stack: %lu, hw: %lu\n", tp->ifStatics.rx_dropped, pkt_drop);
|
||
|
+
|
||
|
tp->ifStatics.rx_dropped = tp->ifStatics.rx_dropped + pkt_drop;
|
||
|
tp->ifStatics.rx_errors = tp->ifStatics.rx_errors + pkt_error;
|
||
|
// spin_unlock_irqrestore(&tp->lock,flags);
|
||
|
}
|
||
|
+#endif
|
||
|
+
|
||
|
return &tp->ifStatics;
|
||
|
}
|
||
|
|
||
|
@@ -2401,36 +2419,63 @@
|
||
|
* toe_gmac_fill_free_q
|
||
|
* allocate buffers for free queue.
|
||
|
*----------------------------------------------------------------------*/
|
||
|
-static inline void toe_gmac_fill_free_q(void)
|
||
|
+static inline void toe_gmac_fill_free_q(int count)
|
||
|
{
|
||
|
struct sk_buff *skb;
|
||
|
volatile DMA_RWPTR_T fq_rwptr;
|
||
|
volatile GMAC_RXDESC_T *fq_desc;
|
||
|
- unsigned long flags;
|
||
|
+ unsigned long flags;
|
||
|
+ unsigned short index;
|
||
|
+ int filled = 0;
|
||
|
+ static int entered;
|
||
|
// unsigned short max_cnt=TOE_SW_FREEQ_DESC_NUM>>1;
|
||
|
|
||
|
+ BUG_ON(entered == 1);
|
||
|
+
|
||
|
+ entered = 1;
|
||
|
+
|
||
|
+
|
||
|
fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
// spin_lock_irqsave(&gmac_fq_lock, flags);
|
||
|
//while ((max_cnt--) && (unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
|
||
|
// TOE_SW_FREEQ_DESC_NUM) != fq_rwptr.bits.rptr) {
|
||
|
- while ((unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
|
||
|
- TOE_SW_FREEQ_DESC_NUM) != fq_rwptr.bits.rptr) {
|
||
|
+ index = fq_rwptr.bits.wptr;
|
||
|
+#if 0
|
||
|
+ printk("wptr: %hu, rptr: %hu, refill idx: %hu\n",
|
||
|
+ GET_RPTR(fq_rwptr.bits32),
|
||
|
+ GET_WPTR(fq_rwptr.bits32),
|
||
|
+ index);
|
||
|
+#endif
|
||
|
+
|
||
|
+ index = RWPTR_ADVANCE_ONE(index, TOE_SW_FREEQ_DESC_NUM);
|
||
|
+ fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base + index;
|
||
|
+ while (fq_desc->word2.buf_adr == 0) {
|
||
|
+ void *data = NULL;
|
||
|
+
|
||
|
if ((skb = dev_alloc_skb(SW_RX_BUF_SIZE)) == NULL) {
|
||
|
printk("%s::skb allocation fail!\n", __func__);
|
||
|
- //while(1);
|
||
|
- break;
|
||
|
+ goto out;
|
||
|
}
|
||
|
- REG32(skb->data) = (unsigned int)skb;
|
||
|
+ ++ filled;
|
||
|
+ data = skb->data;
|
||
|
skb_reserve(skb, SKB_RESERVE_BYTES);
|
||
|
- // fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- fq_rwptr.bits.wptr = RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
|
||
|
- TOE_SW_FREEQ_DESC_NUM);
|
||
|
- fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base+fq_rwptr.bits.wptr;
|
||
|
+
|
||
|
+ REG32(data + 0) = (unsigned int)skb;
|
||
|
+ REG32(data + 4) = (unsigned short)index;
|
||
|
+
|
||
|
+ // printk("refill skb: %p, idx: %hu\n", skb, index);
|
||
|
fq_desc->word2.buf_adr = (unsigned int)__pa(skb->data);
|
||
|
- SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, fq_rwptr.bits.wptr);
|
||
|
- toe_private_data.fq_rx_rwptr.bits32 = fq_rwptr.bits32;
|
||
|
+ writel(0x07960202, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
+ SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, index);
|
||
|
+ writel(0x07960200, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
+
|
||
|
+ index = RWPTR_ADVANCE_ONE(index, TOE_SW_FREEQ_DESC_NUM);
|
||
|
+ fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base+index;
|
||
|
}
|
||
|
+out:
|
||
|
// spin_unlock_irqrestore(&gmac_fq_lock, flags);
|
||
|
+
|
||
|
+ entered = 0;
|
||
|
}
|
||
|
// EXPORT_SYMBOL(toe_gmac_fill_free_q);
|
||
|
|
||
|
@@ -2442,14 +2487,14 @@
|
||
|
unsigned int status3;
|
||
|
unsigned int status4;
|
||
|
|
||
|
- printk("%s\n", message);
|
||
|
-
|
||
|
status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
|
||
|
status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
|
||
|
status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
|
||
|
status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
|
||
|
+ printk("%s\n", message);
|
||
|
+
|
||
|
printk("status: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
|
||
|
status0, status1, status2, status3, status4);
|
||
|
|
||
|
@@ -2468,8 +2513,9 @@
|
||
|
status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG);
|
||
|
status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
|
||
|
- printk("select: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
|
||
|
- status0, status1, status2, status3, status4);
|
||
|
+ if (status0 || status1 || status2 || status3 || status4)
|
||
|
+ printk("select: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
|
||
|
+ status0, status1, status2, status3, status4);
|
||
|
}
|
||
|
/*----------------------------------------------------------------------
|
||
|
* toe_gmac_interrupt
|
||
|
@@ -2485,75 +2531,44 @@
|
||
|
unsigned int status3;
|
||
|
unsigned int status4;
|
||
|
|
||
|
-// struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
-// handle NAPI
|
||
|
-#ifdef CONFIG_SL_NAPI
|
||
|
- /* XXX: check this, changed from 'storlink_ctl.pauseoff == 1' to if (1) */
|
||
|
-if (1)
|
||
|
-{
|
||
|
-/* disable GMAC interrupt */
|
||
|
- //toe_gmac_disable_interrupt(tp->irq);
|
||
|
|
||
|
-// isPtr->interrupts++;
|
||
|
+ if (0 && rx_poll_enabled) {
|
||
|
+ gmac_registers("interrupt handler");
|
||
|
+ }
|
||
|
+
|
||
|
/* read Interrupt status */
|
||
|
status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
|
||
|
status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
|
||
|
status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
|
||
|
status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
- // prompt warning if status bit ON but not enabled
|
||
|
+
|
||
|
#if 0
|
||
|
- if (status0 & ~tp->intr0_enabled)
|
||
|
- printk("Intr 0 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status0, tp->intr0_enabled);
|
||
|
- if (status1 & ~tp->intr1_enabled)
|
||
|
- printk("Intr 1 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status1, tp->intr1_enabled);
|
||
|
- if (status2 & ~tp->intr2_enabled)
|
||
|
- printk("Intr 2 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status2, tp->intr2_enabled);
|
||
|
- if (status3 & ~tp->intr3_enabled)
|
||
|
- printk("Intr 3 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status3, tp->intr3_enabled);
|
||
|
- if (status4 & ~tp->intr4_enabled)
|
||
|
- printk("Intr 4 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status4, tp->intr4_enabled);
|
||
|
+ /* handle freeq interrupt first */
|
||
|
+ if (status4 & SWFQ_EMPTY_INT_BIT)
|
||
|
+ {
|
||
|
+ toe_gmac_fill_free_q();
|
||
|
+ writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+ tp->sw_fq_empty_cnt++;
|
||
|
+ }
|
||
|
#endif
|
||
|
|
||
|
+ if (status4 & GMAC0_MIB_INT_BIT)
|
||
|
+ writel(GMAC0_MIB_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+
|
||
|
+ if (status4 & GMAC0_RX_OVERRUN_INT_BIT)
|
||
|
+ writel(GMAC0_RX_OVERRUN_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+
|
||
|
if (status0)
|
||
|
writel(status0 & tp->intr0_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_0_REG);
|
||
|
- if (status1)
|
||
|
- writel(status1 & tp->intr1_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
if (status2)
|
||
|
writel(status2 & tp->intr2_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_2_REG);
|
||
|
if (status3)
|
||
|
writel(status3 & tp->intr3_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_3_REG);
|
||
|
- if (status4)
|
||
|
- writel(status4 & tp->intr4_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
-
|
||
|
-#if 0
|
||
|
- /* handle freeq interrupt first */
|
||
|
- if (status4 & tp->intr4_enabled) {
|
||
|
- if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
|
||
|
- {
|
||
|
- // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
|
||
|
- // tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
|
||
|
-
|
||
|
- if (toe->gmac[0].dev && netif_running(toe->gmac[0].dev))
|
||
|
- toe_gmac_handle_default_rxq(toe->gmac[0].dev,&toe->gmac[0]);
|
||
|
- if (toe->gmac[1].dev && netif_running(toe->gmac[1].dev))
|
||
|
- toe_gmac_handle_default_rxq(toe->gmac[1].dev,&toe->gmac[1]);
|
||
|
- printk("\nfreeq int\n");
|
||
|
- toe_gmac_fill_free_q();
|
||
|
- tp->sw_fq_empty_cnt++;
|
||
|
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
// Interrupt Status 1
|
||
|
- if (status1 & tp->intr1_enabled)
|
||
|
+ if ((status1 & 3) || (status4 & 1))
|
||
|
{
|
||
|
#define G1_INTR0_BITS (GMAC1_HWTQ13_EOF_INT_BIT | GMAC1_HWTQ12_EOF_INT_BIT | GMAC1_HWTQ11_EOF_INT_BIT | GMAC1_HWTQ10_EOF_INT_BIT)
|
||
|
#define G0_INTR0_BITS (GMAC0_HWTQ03_EOF_INT_BIT | GMAC0_HWTQ02_EOF_INT_BIT | GMAC0_HWTQ01_EOF_INT_BIT | GMAC0_HWTQ00_EOF_INT_BIT)
|
||
|
@@ -2563,7 +2578,7 @@
|
||
|
// because they should pass packets to upper layer
|
||
|
if (tp->port_id == 0)
|
||
|
{
|
||
|
- if (netif_running(dev) && (status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS))
|
||
|
+ if (((status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS)) || (status4 & 1))
|
||
|
{
|
||
|
if (status1 & GMAC0_HWTQ03_EOF_INT_BIT)
|
||
|
tp->hwtxq[3].eof_cnt++;
|
||
|
@@ -2574,50 +2589,51 @@
|
||
|
if (status1 & GMAC0_HWTQ00_EOF_INT_BIT)
|
||
|
tp->hwtxq[0].eof_cnt++;
|
||
|
}
|
||
|
- if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
|
||
|
+ if (status1 & DEFAULT_Q0_INT_BIT || status4 & 1)
|
||
|
+ {
|
||
|
+ if (likely(netif_rx_schedule_prep(dev)))
|
||
|
{
|
||
|
- if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
|
||
|
- {
|
||
|
- unsigned int data32;
|
||
|
+ unsigned int data32;
|
||
|
+
|
||
|
+ BUG_ON(rx_poll_enabled == 1);
|
||
|
|
||
|
- if (rx_poll_enabled)
|
||
|
- gmac_registers("check #1");
|
||
|
+ /* Masks GMAC-0 rx interrupt */
|
||
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
+ data32 &= ~(DEFAULT_Q0_INT_BIT);
|
||
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
|
||
|
- BUG_ON(rx_poll_enabled == 1);
|
||
|
+ /* Masks GMAC-0 queue empty interrupt */
|
||
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
+ data32 &= ~DEFAULT_Q0_INT_BIT;
|
||
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
|
||
|
+ __netif_rx_schedule(dev);
|
||
|
+ rx_poll_enabled = 1;
|
||
|
+ } else {
|
||
|
#if 0
|
||
|
- /* Masks GMAC-0 rx interrupt */
|
||
|
- data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- data32 &= ~(DEFAULT_Q0_INT_BIT);
|
||
|
- writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
-
|
||
|
- /* Masks GMAC-0 queue empty interrupt */
|
||
|
- data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
- data32 &= ~DEFAULT_Q0_INT_BIT;
|
||
|
- writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
-
|
||
|
- data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
- data32 &= ~DEFAULT_Q0_INT_BIT;
|
||
|
- writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
-#endif
|
||
|
-
|
||
|
- // class-Q & TOE-Q are implemented in future
|
||
|
- //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //data32 &= ~DEFAULT_Q0_INT_BIT;
|
||
|
- //writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //printk("\%s: DEFAULT_Q0_INT_BIT===================>>>>>>>>>>>>\n",__func__);
|
||
|
- writel(0x0, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //tp->total_q_cnt_napi=0;
|
||
|
- //rx_time = jiffies;
|
||
|
- //rx_old_bytes = isPtr->rx_bytes;
|
||
|
- __netif_rx_schedule(dev);
|
||
|
- rx_poll_enabled = 1;
|
||
|
- }
|
||
|
+ unsigned int data32;
|
||
|
+
|
||
|
+ if (rx_poll_enabled)
|
||
|
+ gmac_registers("->poll() running.");
|
||
|
+ /* Masks GMAC-0 rx interrupt */
|
||
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
+ data32 &= ~(DEFAULT_Q0_INT_BIT);
|
||
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
+
|
||
|
+ /* Masks GMAC-0 queue empty interrupt */
|
||
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
+ data32 &= ~DEFAULT_Q0_INT_BIT;
|
||
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
+#endif
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ if (0)
|
||
|
+ gmac_registers("status1 & DEFAULT_Q0_INT_BIT || status4 & 1");
|
||
|
}
|
||
|
}
|
||
|
- else if (tp->port_id == 1)
|
||
|
+ else if (tp->port_id == 1 && netif_running(dev))
|
||
|
{
|
||
|
- if (netif_running(dev) && (status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
|
||
|
+ if ((status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
|
||
|
{
|
||
|
if (status1 & GMAC1_HWTQ13_EOF_INT_BIT)
|
||
|
tp->hwtxq[3].eof_cnt++;
|
||
|
@@ -2629,14 +2645,14 @@
|
||
|
tp->hwtxq[0].eof_cnt++;
|
||
|
}
|
||
|
|
||
|
- if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
|
||
|
+ if ((status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
|
||
|
{
|
||
|
if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
|
||
|
- {
|
||
|
- unsigned int data32;
|
||
|
+ {
|
||
|
+ unsigned int data32;
|
||
|
|
||
|
if (rx_poll_enabled)
|
||
|
- gmac_registers("check #2");
|
||
|
+ gmac_registers("check #2");
|
||
|
|
||
|
BUG_ON(rx_poll_enabled == 1);
|
||
|
|
||
|
@@ -2646,7 +2662,7 @@
|
||
|
data32 &= ~(DEFAULT_Q1_INT_BIT);
|
||
|
writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
|
||
|
- /* Masks GMAC-1 queue empty interrupt */
|
||
|
+ /* Masks GMAC-1 queue empty interrupt */
|
||
|
data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
data32 &= ~DEFAULT_Q1_INT_BIT;
|
||
|
writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
@@ -2656,24 +2672,21 @@
|
||
|
writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
#endif
|
||
|
|
||
|
- // disable GMAC-0 rx interrupt
|
||
|
- // class-Q & TOE-Q are implemented in future
|
||
|
- //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //data32 &= ~DEFAULT_Q1_INT_BIT;
|
||
|
+ // disable GMAC-0 rx interrupt
|
||
|
+ // class-Q & TOE-Q are implemented in future
|
||
|
+ //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
+ //data32 &= ~DEFAULT_Q1_INT_BIT;
|
||
|
//writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
//printk("\%s: 1111111111--->DEFAULT_Q1_INT_BIT===================>>>>>>>>>>>>\n",__func__);
|
||
|
writel(0x0, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
//tp->total_q_cnt_napi=0;
|
||
|
//rx_time = jiffies;
|
||
|
//rx_old_bytes = isPtr->rx_bytes;
|
||
|
- __netif_rx_schedule(dev);
|
||
|
- rx_poll_enabled = 1;
|
||
|
- }
|
||
|
+ __netif_rx_schedule(dev);
|
||
|
+ rx_poll_enabled = 1;
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
- } else {
|
||
|
-
|
||
|
- gmac_registers("check #3");
|
||
|
}
|
||
|
|
||
|
// Interrupt Status 0
|
||
|
@@ -2814,676 +2827,93 @@
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- //toe_gmac_enable_interrupt(tp->irq);
|
||
|
-#ifdef IxscriptMate_1518
|
||
|
- if (storlink_ctl.pauseoff == 1)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
-#endif
|
||
|
-// enable_irq(gmac_irq[dev_index]);
|
||
|
- //printk("gmac_interrupt complete!\n\n");
|
||
|
-// return IRQ_RETVAL(handled);
|
||
|
return IRQ_RETVAL(1);
|
||
|
}
|
||
|
-else
|
||
|
-{
|
||
|
-#endif //endif NAPI
|
||
|
|
||
|
+/*----------------------------------------------------------------------
|
||
|
+* gmac_get_phy_vendor
|
||
|
+*----------------------------------------------------------------------*/
|
||
|
+static unsigned int gmac_get_phy_vendor(int phy_addr)
|
||
|
+{
|
||
|
+ unsigned int reg_val;
|
||
|
+ reg_val=(mii_read(phy_addr,0x02) << 16) + mii_read(phy_addr,0x03);
|
||
|
+ return reg_val;
|
||
|
+}
|
||
|
|
||
|
- /* disable GMAC interrupt */
|
||
|
- toe_gmac_disable_interrupt(tp->irq);
|
||
|
+/*----------------------------------------------------------------------
|
||
|
+* gmac_set_phy_status
|
||
|
+*----------------------------------------------------------------------*/
|
||
|
+void gmac_set_phy_status(struct net_device *dev)
|
||
|
+{
|
||
|
+ GMAC_INFO_T *tp = dev->priv;
|
||
|
+ GMAC_STATUS_T status;
|
||
|
+ unsigned int reg_val, ability,wan_port_id;
|
||
|
+ unsigned int i = 0;
|
||
|
|
||
|
-// isPtr->interrupts++;
|
||
|
- /* read Interrupt status */
|
||
|
- status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
|
||
|
- status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
- status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
|
||
|
- status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
|
||
|
- status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
- // prompt warning if status bit ON but not enabled
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
+ if((tp->port_id == GMAC_PORT1)&&(Giga_switch==1)){
|
||
|
#if 0
|
||
|
- if (status0 & ~tp->intr0_enabled)
|
||
|
- printk("Intr 0 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status0, tp->intr0_enabled);
|
||
|
- if (status1 & ~tp->intr1_enabled)
|
||
|
- printk("Intr 1 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status1, tp->intr1_enabled);
|
||
|
- if (status2 & ~tp->intr2_enabled)
|
||
|
- printk("Intr 2 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status2, tp->intr2_enabled);
|
||
|
- if (status3 & ~tp->intr3_enabled)
|
||
|
- printk("Intr 3 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status3, tp->intr3_enabled);
|
||
|
- if (status4 & ~tp->intr4_enabled)
|
||
|
- printk("Intr 4 Status error. status = 0x%X, enable = 0x%X\n",
|
||
|
- status4, tp->intr4_enabled);
|
||
|
-#endif
|
||
|
-#define INTERRUPT_SELECT 1
|
||
|
- if (status0)
|
||
|
- writel(status0 & tp->intr0_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_0_REG);
|
||
|
- if (status1)
|
||
|
- writel(status1 & tp->intr1_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
- if (status2)
|
||
|
- writel(status2 & tp->intr2_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_2_REG);
|
||
|
- if (status3)
|
||
|
- writel(status3 & tp->intr3_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_3_REG);
|
||
|
- if (status4)
|
||
|
- writel(status4 & tp->intr4_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
-
|
||
|
- /* handle freeq interrupt first */
|
||
|
- if (status4 & tp->intr4_enabled) {
|
||
|
- if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
|
||
|
- {
|
||
|
- // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
|
||
|
- // tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
|
||
|
-
|
||
|
- //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG,
|
||
|
- // SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
|
||
|
- if (toe->gmac[0].dev && netif_running(toe->gmac[0].dev))
|
||
|
- toe_gmac_handle_default_rxq(toe->gmac[0].dev,&toe->gmac[0]);
|
||
|
- if (toe->gmac[1].dev && netif_running(toe->gmac[1].dev))
|
||
|
- toe_gmac_handle_default_rxq(toe->gmac[1].dev,&toe->gmac[1]);
|
||
|
- printk("\nfreeq int\n");
|
||
|
- toe_gmac_fill_free_q();
|
||
|
- tp->sw_fq_empty_cnt++;
|
||
|
-
|
||
|
- gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
|
||
|
- SWFQ_EMPTY_INT_BIT);
|
||
|
- }
|
||
|
- }
|
||
|
-
|
||
|
- // Interrupt Status 1
|
||
|
- if (status1 & tp->intr1_enabled)
|
||
|
- {
|
||
|
- #define G1_INTR0_BITS (GMAC1_HWTQ13_EOF_INT_BIT | GMAC1_HWTQ12_EOF_INT_BIT | GMAC1_HWTQ11_EOF_INT_BIT | GMAC1_HWTQ10_EOF_INT_BIT)
|
||
|
- #define G0_INTR0_BITS (GMAC0_HWTQ03_EOF_INT_BIT | GMAC0_HWTQ02_EOF_INT_BIT | GMAC0_HWTQ01_EOF_INT_BIT | GMAC0_HWTQ00_EOF_INT_BIT)
|
||
|
- // Handle GMAC 0/1 HW Tx queue 0-3 EOF events
|
||
|
- // Only count
|
||
|
- // TOE, Classification, and default queues interrupts are handled by ISR
|
||
|
- // because they should pass packets to upper layer
|
||
|
- if (tp->port_id == 0)
|
||
|
- {
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- if (netif_running(dev) && (status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS))
|
||
|
- {
|
||
|
- if (status1 & GMAC0_HWTQ03_EOF_INT_BIT)
|
||
|
- tp->hwtxq[3].eof_cnt++;
|
||
|
- if (status1 & GMAC0_HWTQ02_EOF_INT_BIT)
|
||
|
- tp->hwtxq[2].eof_cnt++;
|
||
|
- if (status1 & GMAC0_HWTQ01_EOF_INT_BIT)
|
||
|
- tp->hwtxq[1].eof_cnt++;
|
||
|
- if (status1 & GMAC0_HWTQ00_EOF_INT_BIT)
|
||
|
- tp->hwtxq[0].eof_cnt++;
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- }
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
- if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
|
||
|
- {
|
||
|
- tp->default_q_intr_cnt++;
|
||
|
- toe_gmac_handle_default_rxq(dev, tp);
|
||
|
+ rcv_mask = SPI_read(2,0,0x10); // Receive mask
|
||
|
+ rcv_mask |= 0x4F;
|
||
|
+ for(i=0;i<4;i++){
|
||
|
+ reg_val = BIT(26)|(i<<21)|(10<<16);
|
||
|
+ SPI_write(3,0,1,reg_val);
|
||
|
+ msleep(10);
|
||
|
+ reg_val = SPI_read(3,0,2);
|
||
|
+ if(reg_val & 0x0c00){
|
||
|
+ printk("Port%d:Giga mode\n",i);
|
||
|
+ SPI_write(1,i,0x00,0x300701B1);
|
||
|
+ SPI_write(1,i,0x00,0x10070181);
|
||
|
+ switch_pre_link[i]=LINK_UP;
|
||
|
+ switch_pre_speed[i]=GMAC_SPEED_1000;
|
||
|
}
|
||
|
-#ifdef CONFIG_SL351x_RXTOE
|
||
|
- if (netif_running(dev) && (status1 & TOE_IQ_ALL_BITS) &&
|
||
|
- (tp->intr1_enabled & TOE_IQ_ALL_BITS)) {
|
||
|
- //printk("status %x, bits %x, slct %x\n", status1, TOE_IQ_ALL_BITS, tp->intr1_selected);
|
||
|
- toe_gmac_handle_toeq(dev, tp, status1);
|
||
|
- //toe_gmac_handle_toeq(dev, toe, tp, status1);
|
||
|
+ else{
|
||
|
+ reg_val = BIT(26)|(i<<21)|(5<<16);
|
||
|
+ SPI_write(3,0,1,reg_val);
|
||
|
+ msleep(10);
|
||
|
+ ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;
|
||
|
+ if ((ability & 0x0C)) /* 100M full duplex */
|
||
|
+ {
|
||
|
+ SPI_write(1,i,0x00,0x30050472);
|
||
|
+ SPI_write(1,i,0x00,0x10050442);
|
||
|
+ printk("Port%d:100M\n",i);
|
||
|
+ switch_pre_link[i]=LINK_UP;
|
||
|
+ switch_pre_speed[i]=GMAC_SPEED_100;
|
||
|
+ }
|
||
|
+ else if((ability & 0x03)) /* 10M full duplex */
|
||
|
+ {
|
||
|
+ SPI_write(1,i,0x00,0x30050473);
|
||
|
+ SPI_write(1,i,0x00,0x10050443);
|
||
|
+ printk("Port%d:10M\n",i);
|
||
|
+ switch_pre_link[i]=LINK_UP;
|
||
|
+ switch_pre_speed[i]=GMAC_SPEED_10;
|
||
|
+ }
|
||
|
+ else{
|
||
|
+ SPI_write(1,i,0x00,BIT(16)); // disable RX
|
||
|
+ SPI_write(5,0,0x0E,BIT(i)); // dicard packet
|
||
|
+ while((SPI_read(5,0,0x0C)&BIT(i))==0) // wait to be empty
|
||
|
+ msleep(1);
|
||
|
+
|
||
|
+ SPI_write(1,i,0x00,0x20000030); // PORT_RST
|
||
|
+ switch_pre_link[i]=LINK_DOWN;
|
||
|
+ switch_pre_speed[i]=GMAC_SPEED_10;
|
||
|
+ rcv_mask &= ~BIT(i);
|
||
|
+ SPI_write(2,0,0x10,rcv_mask); // Disable Receive
|
||
|
+ }
|
||
|
}
|
||
|
-#endif
|
||
|
}
|
||
|
- else if (tp->port_id == 1)
|
||
|
- {
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- if (netif_running(dev) && (status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
|
||
|
- {
|
||
|
- if (status1 & GMAC1_HWTQ13_EOF_INT_BIT)
|
||
|
- tp->hwtxq[3].eof_cnt++;
|
||
|
- if (status1 & GMAC1_HWTQ12_EOF_INT_BIT)
|
||
|
- tp->hwtxq[2].eof_cnt++;
|
||
|
- if (status1 & GMAC1_HWTQ11_EOF_INT_BIT)
|
||
|
- tp->hwtxq[1].eof_cnt++;
|
||
|
- if (status1 & GMAC1_HWTQ10_EOF_INT_BIT)
|
||
|
- tp->hwtxq[0].eof_cnt++;
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- }
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
- if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
|
||
|
- {
|
||
|
- tp->default_q_intr_cnt++;
|
||
|
- toe_gmac_handle_default_rxq(dev, tp);
|
||
|
- }
|
||
|
-#ifdef CONFIG_SL351x_RXTOE
|
||
|
- if (netif_running(dev) && (status1 & TOE_IQ_ALL_BITS) &&
|
||
|
- (tp->intr1_enabled & TOE_IQ_ALL_BITS)) {
|
||
|
- //printk("status %x, bits %x, slct %x\n", status1, TOE_IQ_ALL_BITS, tp->intr1_selected);
|
||
|
- toe_gmac_handle_toeq(dev, tp, status1);
|
||
|
- //toe_gmac_handle_toeq(dev, toe, tp, status1);
|
||
|
- }
|
||
|
#endif
|
||
|
- }
|
||
|
+ gmac_get_switch_status(dev);
|
||
|
+ gmac_write_reg(tp->base_addr, GMAC_STATUS, 0x7d, 0x0000007f);
|
||
|
+// SPI_write(2,0,0x10,rcv_mask); // Enable Receive
|
||
|
+ return ;
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
+ reg_val = gmac_get_phy_vendor(tp->phy_addr);
|
||
|
+ printk("GMAC-%d Addr %d Vendor ID: 0x%08x\n", tp->port_id, tp->phy_addr, reg_val);
|
||
|
|
||
|
- // Interrupt Status 0
|
||
|
- if (status0 & tp->intr0_enabled)
|
||
|
- {
|
||
|
-
|
||
|
- #define ERR_INTR_BITS (GMAC0_TXDERR_INT_BIT | GMAC0_TXPERR_INT_BIT | \
|
||
|
- GMAC1_TXDERR_INT_BIT | GMAC1_TXPERR_INT_BIT | \
|
||
|
- GMAC0_RXDERR_INT_BIT | GMAC0_RXPERR_INT_BIT | \
|
||
|
- GMAC1_RXDERR_INT_BIT | GMAC1_RXPERR_INT_BIT)
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- if (status0 & ERR_INTR_BITS)
|
||
|
- {
|
||
|
- if ((status0 & GMAC0_TXDERR_INT_BIT) && (tp->intr0_enabled & GMAC0_TXDERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->txDerr_cnt[0]++;
|
||
|
- printk("GMAC0 TX AHB Bus Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC0_TXPERR_INT_BIT) && (tp->intr0_enabled & GMAC0_TXPERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->txPerr_cnt[0]++;
|
||
|
- printk("GMAC0 Tx Descriptor Protocol Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC1_TXDERR_INT_BIT) && (tp->intr0_enabled & GMAC1_TXDERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->txDerr_cnt[1]++;
|
||
|
- printk("GMAC1 Tx AHB Bus Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC1_TXPERR_INT_BIT) && (tp->intr0_enabled & GMAC1_TXPERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->txPerr_cnt[1]++;
|
||
|
- printk("GMAC1 Tx Descriptor Protocol Error!\n");
|
||
|
- }
|
||
|
-
|
||
|
- if ((status0 & GMAC0_RXDERR_INT_BIT) && (tp->intr0_enabled & GMAC0_RXDERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->RxDerr_cnt[0]++;
|
||
|
- printk("GMAC0 Rx AHB Bus Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC0_RXPERR_INT_BIT) && (tp->intr0_enabled & GMAC0_RXPERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->RxPerr_cnt[0]++;
|
||
|
- printk("GMAC0 Rx Descriptor Protocol Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC1_RXDERR_INT_BIT) && (tp->intr0_enabled & GMAC1_RXDERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->RxDerr_cnt[1]++;
|
||
|
- printk("GMAC1 Rx AHB Bus Error!\n");
|
||
|
- }
|
||
|
- if ((status0 & GMAC1_RXPERR_INT_BIT) && (tp->intr0_enabled & GMAC1_RXPERR_INT_BIT))
|
||
|
- {
|
||
|
- tp->RxPerr_cnt[1]++;
|
||
|
- printk("GMAC1 Rx Descriptor Protocol Error!\n");
|
||
|
- }
|
||
|
- }
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
-#ifndef GMAX_TX_INTR_DISABLED
|
||
|
- if (tp->port_id == 1 && netif_running(dev) &&
|
||
|
- (((status0 & GMAC1_SWTQ10_FIN_INT_BIT) && (tp->intr0_enabled & GMAC1_SWTQ10_FIN_INT_BIT))
|
||
|
- ||
|
||
|
- ((status0 & GMAC1_SWTQ10_EOF_INT_BIT) && (tp->intr0_enabled & GMAC1_SWTQ10_EOF_INT_BIT))))
|
||
|
- {
|
||
|
- toe_gmac_tx_complete(&toe_private_data.gmac[1], 0, dev, 1);
|
||
|
- }
|
||
|
-
|
||
|
- if (tp->port_id == 0 && netif_running(dev) &&
|
||
|
- (((status0 & GMAC0_SWTQ00_FIN_INT_BIT) && (tp->intr0_enabled & GMAC0_SWTQ00_FIN_INT_BIT))
|
||
|
- ||
|
||
|
- ((status0 & GMAC0_SWTQ00_EOF_INT_BIT) && (tp->intr0_enabled & GMAC0_SWTQ00_EOF_INT_BIT))))
|
||
|
- {
|
||
|
- toe_gmac_tx_complete(&toe_private_data.gmac[0], 0, dev, 1);
|
||
|
- }
|
||
|
-#endif
|
||
|
- // clear enabled status bits
|
||
|
- }
|
||
|
- // Interrupt Status 4
|
||
|
-#ifndef INTERRUPT_SELECT
|
||
|
- if (status4 & tp->intr4_enabled)
|
||
|
- {
|
||
|
- #define G1_INTR4_BITS (0xff000000)
|
||
|
- #define G0_INTR4_BITS (0x00ff0000)
|
||
|
-
|
||
|
- if (tp->port_id == 0)
|
||
|
- {
|
||
|
- if ((status4 & G0_INTR4_BITS) && (tp->intr4_enabled & G0_INTR4_BITS))
|
||
|
- {
|
||
|
- if (status4 & GMAC0_RESERVED_INT_BIT)
|
||
|
- printk("GMAC0_RESERVED_INT_BIT is ON\n");
|
||
|
- if (status4 & GMAC0_MIB_INT_BIT)
|
||
|
- tp->mib_full_cnt++;
|
||
|
- if (status4 & GMAC0_RX_PAUSE_ON_INT_BIT)
|
||
|
- tp->rx_pause_on_cnt++;
|
||
|
- if (status4 & GMAC0_TX_PAUSE_ON_INT_BIT)
|
||
|
- tp->tx_pause_on_cnt++;
|
||
|
- if (status4 & GMAC0_RX_PAUSE_OFF_INT_BIT)
|
||
|
- tp->rx_pause_off_cnt++;
|
||
|
- if (status4 & GMAC0_TX_PAUSE_OFF_INT_BIT)
|
||
|
- tp->rx_pause_off_cnt++;
|
||
|
- if (status4 & GMAC0_RX_OVERRUN_INT_BIT)
|
||
|
- tp->rx_overrun_cnt++;
|
||
|
- if (status4 & GMAC0_STATUS_CHANGE_INT_BIT)
|
||
|
- tp->status_changed_cnt++;
|
||
|
- }
|
||
|
- }
|
||
|
- else if (tp->port_id == 1)
|
||
|
- {
|
||
|
- if ((status4 & G1_INTR4_BITS) && (tp->intr4_enabled & G1_INTR4_BITS))
|
||
|
- {
|
||
|
- if (status4 & GMAC1_RESERVED_INT_BIT)
|
||
|
- printk("GMAC1_RESERVED_INT_BIT is ON\n");
|
||
|
- if (status4 & GMAC1_MIB_INT_BIT)
|
||
|
- tp->mib_full_cnt++;
|
||
|
- if (status4 & GMAC1_RX_PAUSE_ON_INT_BIT)
|
||
|
- {
|
||
|
- //printk("Gmac pause on\n");
|
||
|
- tp->rx_pause_on_cnt++;
|
||
|
- }
|
||
|
- if (status4 & GMAC1_TX_PAUSE_ON_INT_BIT)
|
||
|
- {
|
||
|
- //printk("Gmac pause on\n");
|
||
|
- tp->tx_pause_on_cnt++;
|
||
|
- }
|
||
|
- if (status4 & GMAC1_RX_PAUSE_OFF_INT_BIT)
|
||
|
- {
|
||
|
- //printk("Gmac pause off\n");
|
||
|
- tp->rx_pause_off_cnt++;
|
||
|
- }
|
||
|
- if (status4 & GMAC1_TX_PAUSE_OFF_INT_BIT)
|
||
|
- {
|
||
|
- //printk("Gmac pause off\n");
|
||
|
- tp->rx_pause_off_cnt++;
|
||
|
- }
|
||
|
- if (status4 & GMAC1_RX_OVERRUN_INT_BIT)
|
||
|
- {
|
||
|
- //printk("Gmac Rx Overrun \n");
|
||
|
- tp->rx_overrun_cnt++;
|
||
|
- }
|
||
|
- if (status4 & GMAC1_STATUS_CHANGE_INT_BIT)
|
||
|
- tp->status_changed_cnt++;
|
||
|
- }
|
||
|
- }
|
||
|
-#if 0
|
||
|
- if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
|
||
|
- {
|
||
|
- // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
-// mac_stop_rxdma(tp->sc);
|
||
|
- gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
|
||
|
- tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
|
||
|
-
|
||
|
- gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG,
|
||
|
- SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
|
||
|
- toe_gmac_fill_free_q();
|
||
|
- tp->sw_fq_empty_cnt++;
|
||
|
-
|
||
|
- gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
|
||
|
- SWFQ_EMPTY_INT_BIT);
|
||
|
-//#if 0
|
||
|
-/* if (netif_running(dev))
|
||
|
- toe_gmac_handle_default_rxq(dev, tp);
|
||
|
- printk("SWFQ_EMPTY_INT_BIT is ON!\n"); // should not be happened */
|
||
|
-//#endif
|
||
|
- }
|
||
|
-#endif
|
||
|
- }
|
||
|
-#endif //INTERRUPT_SELECT
|
||
|
- toe_gmac_enable_interrupt(tp->irq);
|
||
|
-//enable gmac rx function when do RFC 2544
|
||
|
-#ifdef IxscriptMate_1518
|
||
|
- if (storlink_ctl.pauseoff == 1)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
-#endif
|
||
|
- //printk("gmac_interrupt complete!\n\n");
|
||
|
-// return IRQ_RETVAL(handled);
|
||
|
- return IRQ_RETVAL(1);
|
||
|
-#ifdef CONFIG_SL_NAPI
|
||
|
-}
|
||
|
-#endif
|
||
|
-}
|
||
|
-
|
||
|
-/*----------------------------------------------------------------------
|
||
|
-* toe_gmac_handle_default_rxq
|
||
|
-* (1) Get rx Buffer for default Rx queue
|
||
|
-* (2) notify or call upper-routine to handle it
|
||
|
-* (3) get a new buffer and insert it into SW free queue
|
||
|
-* (4) Note: The SW free queue Read-Write Pointer should be locked when accessing
|
||
|
-*----------------------------------------------------------------------*/
|
||
|
-//static inline void toe_gmac_handle_default_rxq(struct net_device *dev, GMAC_INFO_T *tp)
|
||
|
-static void toe_gmac_handle_default_rxq(struct net_device *dev, GMAC_INFO_T *tp)
|
||
|
-{
|
||
|
- TOE_INFO_T *toe;
|
||
|
- GMAC_RXDESC_T *curr_desc;
|
||
|
- struct sk_buff *skb;
|
||
|
- DMA_RWPTR_T rwptr;
|
||
|
- unsigned int pkt_size;
|
||
|
- int max_cnt;
|
||
|
- unsigned int desc_count;
|
||
|
- unsigned int good_frame, chksum_status, rx_status;
|
||
|
- struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
|
||
|
-
|
||
|
-//when do ixia RFC 2544 test and packet size is select 1518 bytes,disable gmace rx function immediately after one interrupt come in.
|
||
|
-#ifdef IxscriptMate_1518
|
||
|
- if (storlink_ctl.pauseoff == 1)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 1;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 1;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
-#endif
|
||
|
- rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
-#if 0
|
||
|
- if (rwptr.bits.rptr != tp->rx_rwptr.bits.rptr)
|
||
|
- {
|
||
|
- mac_stop_txdma((struct net_device *)tp->dev);
|
||
|
- printk("Default Queue HW RD ptr (0x%x) != SW RD Ptr (0x%x)\n",
|
||
|
- rwptr.bits32, tp->rx_rwptr.bits.rptr);
|
||
|
- while(1);
|
||
|
- }
|
||
|
-#endif
|
||
|
- toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
- max_cnt = DEFAULT_RXQ_MAX_CNT;
|
||
|
- while ((--max_cnt) && rwptr.bits.rptr != rwptr.bits.wptr)
|
||
|
-// while (rwptr.bits.rptr != rwptr.bits.wptr)
|
||
|
- {
|
||
|
-//if packet size is not 1518 for RFC 2544,enable gmac rx function.The other packet size have RX workaround.
|
||
|
-#ifdef IxscriptMate_1518
|
||
|
- if (storlink_ctl.pauseoff == 1)
|
||
|
- {
|
||
|
- if (pkt_size != 1514)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
- curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
|
||
|
-// consistent_sync(curr_desc, sizeof(GMAC_RXDESC_T), PCI_DMA_FROMDEVICE);
|
||
|
- tp->default_q_cnt++;
|
||
|
- tp->rx_curr_desc = (unsigned int)curr_desc;
|
||
|
- rx_status = curr_desc->word0.bits.status;
|
||
|
- chksum_status = curr_desc->word0.bits.chksum_status;
|
||
|
- tp->rx_status_cnt[rx_status]++;
|
||
|
- tp->rx_chksum_cnt[chksum_status]++;
|
||
|
- pkt_size = curr_desc->word1.bits.byte_count; /*total byte count in a frame*/
|
||
|
- desc_count = curr_desc->word0.bits.desc_count; /* get descriptor count per frame */
|
||
|
- good_frame=1;
|
||
|
- if ((curr_desc->word0.bits32 & (GMAC_RXDESC_0_T_derr | GMAC_RXDESC_0_T_perr))
|
||
|
- || (pkt_size < 60)
|
||
|
- || (chksum_status & 0x4)
|
||
|
- || rx_status)
|
||
|
- {
|
||
|
- good_frame = 0;
|
||
|
- if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_derr)
|
||
|
- printk("%s::derr (GMAC-%d)!!!\n", __func__, tp->port_id);
|
||
|
- if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_perr)
|
||
|
- printk("%s::perr (GMAC-%d)!!!\n", __func__, tp->port_id);
|
||
|
- if (rx_status)
|
||
|
- {
|
||
|
- if (rx_status == 4 || rx_status == 7)
|
||
|
- isPtr->rx_crc_errors++;
|
||
|
-// printk("%s::Status=%d (GMAC-%d)!!!\n", __func__, rx_status, tp->port_id);
|
||
|
- }
|
||
|
-#ifdef SL351x_GMAC_WORKAROUND
|
||
|
- else if (pkt_size < 60)
|
||
|
- {
|
||
|
- if (tp->short_frames_cnt < GMAC_SHORT_FRAME_THRESHOLD)
|
||
|
- tp->short_frames_cnt++;
|
||
|
- if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 1;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 1;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
-// if (chksum_status)
|
||
|
-// printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
|
||
|
- skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
|
||
|
- dev_kfree_skb_irq(skb);
|
||
|
- }
|
||
|
- if (good_frame)
|
||
|
- {
|
||
|
- if (curr_desc->word0.bits.drop)
|
||
|
- printk("%s::Drop (GMAC-%d)!!!\n", __func__, tp->port_id);
|
||
|
-// if (chksum_status)
|
||
|
-// printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
|
||
|
-
|
||
|
- /* get frame information from the first descriptor of the frame */
|
||
|
-#ifdef SL351x_GMAC_WORKAROUND
|
||
|
- if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
|
||
|
- {
|
||
|
- GMAC_CONFIG0_T config0;
|
||
|
- config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- config0.bits.dis_rx = 0;
|
||
|
- writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- }
|
||
|
- tp->short_frames_cnt = 0;
|
||
|
-#endif
|
||
|
- isPtr->rx_packets++;
|
||
|
- skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr - SKB_RESERVE_BYTES)));
|
||
|
- if (!skb)
|
||
|
- {
|
||
|
- printk("Fatal Error!!skb==NULL\n");
|
||
|
- goto next_rx;
|
||
|
- }
|
||
|
- tp->curr_rx_skb = skb;
|
||
|
- // consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
|
||
|
-
|
||
|
- // curr_desc->word2.buf_adr = 0;
|
||
|
-
|
||
|
- skb_reserve (skb, RX_INSERT_BYTES); /* 16 byte align the IP fields. */
|
||
|
- skb_put(skb, pkt_size);
|
||
|
- skb->dev = dev;
|
||
|
- if (chksum_status == RX_CHKSUM_IP_UDP_TCP_OK)
|
||
|
- {
|
||
|
- skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||
|
-#ifdef CONFIG_SL351x_NAT
|
||
|
- if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
|
||
|
- {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
-#endif
|
||
|
- skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
-#if 0
|
||
|
-#ifdef CONFIG_SL351x_RXTOE
|
||
|
- if (storlink_ctl.rx_max_pktsize) {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- struct tcphdr *tcp_hdr;
|
||
|
- int ip_hdrlen;
|
||
|
-
|
||
|
- ip_hdr = (struct iphdr*)&(skb->data[0]);
|
||
|
- if ((skb->protocol == __constant_htons(ETH_P_IP)) &&
|
||
|
- ((ip_hdr->protocol & 0x00ff) == IPPROTO_TCP)) {
|
||
|
- ip_hdrlen = ip_hdr->ihl << 2;
|
||
|
- tcp_hdr = (struct tcphdr*)&(skb->data[ip_hdrlen]);
|
||
|
- if (tcp_hdr->syn) {
|
||
|
- struct toe_conn* connection = init_toeq(ip_hdr->version,
|
||
|
- ip_hdr, tcp_hdr, toe, &(skb->data[0]) - 14);
|
||
|
- TCP_SKB_CB(skb)->connection = connection;
|
||
|
- // hash_dump_entry(TCP_SKB_CB(skb)->connection->hash_entry_index);
|
||
|
- // printk("%s::skb data %x, conn %x, mode %x\n",
|
||
|
- // __func__, skb->data, connection, connection->mode);
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
-#endif
|
||
|
- }
|
||
|
- else if (chksum_status == RX_CHKSUM_IP_OK_ONLY)
|
||
|
- {
|
||
|
- skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||
|
-#ifdef CONFIG_SL351x_NAT
|
||
|
- if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
|
||
|
- {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- //struct tcphdr *tcp_hdr;
|
||
|
- ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
|
||
|
- //tcp_hdr = (struct tcphdr *)&(skb->data[curr_desc->word3.bits.l4_offset]);
|
||
|
- if (ip_hdr->protocol == IPPROTO_UDP)
|
||
|
- {
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
- else if (ip_hdr->protocol == IPPROTO_GRE)
|
||
|
- {
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
- skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
- }
|
||
|
- else
|
||
|
- {
|
||
|
- skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
- }
|
||
|
-
|
||
|
- netif_rx(skb); /* socket rx */
|
||
|
- dev->last_rx = jiffies;
|
||
|
-
|
||
|
- isPtr->rx_bytes += pkt_size;
|
||
|
-
|
||
|
- }
|
||
|
-
|
||
|
-next_rx:
|
||
|
- // advance one for Rx default Q 0/1
|
||
|
- rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
|
||
|
- SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
|
||
|
- tp->rx_rwptr.bits32 = rwptr.bits32;
|
||
|
-
|
||
|
- }
|
||
|
-
|
||
|
- /* Handles first available packets only then refill the queue. */
|
||
|
- toe_gmac_fill_free_q();
|
||
|
-}
|
||
|
-
|
||
|
-/*----------------------------------------------------------------------
|
||
|
-* gmac_get_phy_vendor
|
||
|
-*----------------------------------------------------------------------*/
|
||
|
-static unsigned int gmac_get_phy_vendor(int phy_addr)
|
||
|
-{
|
||
|
- unsigned int reg_val;
|
||
|
- reg_val=(mii_read(phy_addr,0x02) << 16) + mii_read(phy_addr,0x03);
|
||
|
- return reg_val;
|
||
|
-}
|
||
|
-
|
||
|
-/*----------------------------------------------------------------------
|
||
|
-* gmac_set_phy_status
|
||
|
-*----------------------------------------------------------------------*/
|
||
|
-void gmac_set_phy_status(struct net_device *dev)
|
||
|
-{
|
||
|
- GMAC_INFO_T *tp = dev->priv;
|
||
|
- GMAC_STATUS_T status;
|
||
|
- unsigned int reg_val, ability,wan_port_id;
|
||
|
- unsigned int i = 0;
|
||
|
-
|
||
|
-#ifdef VITESSE_G5SWITCH
|
||
|
- if((tp->port_id == GMAC_PORT1)&&(Giga_switch==1)){
|
||
|
-#if 0
|
||
|
- rcv_mask = SPI_read(2,0,0x10); // Receive mask
|
||
|
- rcv_mask |= 0x4F;
|
||
|
- for(i=0;i<4;i++){
|
||
|
- reg_val = BIT(26)|(i<<21)|(10<<16);
|
||
|
- SPI_write(3,0,1,reg_val);
|
||
|
- msleep(10);
|
||
|
- reg_val = SPI_read(3,0,2);
|
||
|
- if(reg_val & 0x0c00){
|
||
|
- printk("Port%d:Giga mode\n",i);
|
||
|
- SPI_write(1,i,0x00,0x300701B1);
|
||
|
- SPI_write(1,i,0x00,0x10070181);
|
||
|
- switch_pre_link[i]=LINK_UP;
|
||
|
- switch_pre_speed[i]=GMAC_SPEED_1000;
|
||
|
- }
|
||
|
- else{
|
||
|
- reg_val = BIT(26)|(i<<21)|(5<<16);
|
||
|
- SPI_write(3,0,1,reg_val);
|
||
|
- msleep(10);
|
||
|
- ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;
|
||
|
- if ((ability & 0x0C)) /* 100M full duplex */
|
||
|
- {
|
||
|
- SPI_write(1,i,0x00,0x30050472);
|
||
|
- SPI_write(1,i,0x00,0x10050442);
|
||
|
- printk("Port%d:100M\n",i);
|
||
|
- switch_pre_link[i]=LINK_UP;
|
||
|
- switch_pre_speed[i]=GMAC_SPEED_100;
|
||
|
- }
|
||
|
- else if((ability & 0x03)) /* 10M full duplex */
|
||
|
- {
|
||
|
- SPI_write(1,i,0x00,0x30050473);
|
||
|
- SPI_write(1,i,0x00,0x10050443);
|
||
|
- printk("Port%d:10M\n",i);
|
||
|
- switch_pre_link[i]=LINK_UP;
|
||
|
- switch_pre_speed[i]=GMAC_SPEED_10;
|
||
|
- }
|
||
|
- else{
|
||
|
- SPI_write(1,i,0x00,BIT(16)); // disable RX
|
||
|
- SPI_write(5,0,0x0E,BIT(i)); // dicard packet
|
||
|
- while((SPI_read(5,0,0x0C)&BIT(i))==0) // wait to be empty
|
||
|
- msleep(1);
|
||
|
-
|
||
|
- SPI_write(1,i,0x00,0x20000030); // PORT_RST
|
||
|
- switch_pre_link[i]=LINK_DOWN;
|
||
|
- switch_pre_speed[i]=GMAC_SPEED_10;
|
||
|
- rcv_mask &= ~BIT(i);
|
||
|
- SPI_write(2,0,0x10,rcv_mask); // Disable Receive
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
- gmac_get_switch_status(dev);
|
||
|
- gmac_write_reg(tp->base_addr, GMAC_STATUS, 0x7d, 0x0000007f);
|
||
|
-// SPI_write(2,0,0x10,rcv_mask); // Enable Receive
|
||
|
- return ;
|
||
|
- }
|
||
|
-#endif
|
||
|
-
|
||
|
- reg_val = gmac_get_phy_vendor(tp->phy_addr);
|
||
|
- printk("GMAC-%d Addr %d Vendor ID: 0x%08x\n", tp->port_id, tp->phy_addr, reg_val);
|
||
|
-
|
||
|
- switch (tp->phy_mode)
|
||
|
+ switch (tp->phy_mode)
|
||
|
{
|
||
|
case GMAC_PHY_GMII:
|
||
|
mii_write(tp->phy_addr,0x04,0x05e1); /* advertisement 100M full duplex, pause capable on */
|
||
|
@@ -3552,6 +2982,7 @@
|
||
|
status.bits.link = LINK_DOWN;
|
||
|
// clear_bit(__LINK_STATE_START, &dev->state);
|
||
|
printk("Link Down (0x%04x) ", reg_val);
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
if(Giga_switch == 1)
|
||
|
{
|
||
|
wan_port_id = 1;
|
||
|
@@ -3565,6 +2996,7 @@
|
||
|
storlink_ctl.link[ tp->port_id] = 0;
|
||
|
#endif
|
||
|
}
|
||
|
+#endif
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
@@ -3572,6 +3004,7 @@
|
||
|
status.bits.link = LINK_UP;
|
||
|
// set_bit(__LINK_STATE_START, &dev->state);
|
||
|
printk("Link Up (0x%04x) ",reg_val);
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
if(Giga_switch == 1)
|
||
|
{
|
||
|
wan_port_id = 1;
|
||
|
@@ -3585,6 +3018,7 @@
|
||
|
storlink_ctl.link[ tp->port_id] = 1;
|
||
|
#endif
|
||
|
}
|
||
|
+#endif
|
||
|
}
|
||
|
// value = mii_read(PHY_ADDR,0x05);
|
||
|
|
||
|
@@ -3863,6 +3297,7 @@
|
||
|
}
|
||
|
}
|
||
|
status.bits.link = LINK_UP; /* link up */
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
if(Giga_switch==1)
|
||
|
{
|
||
|
wan_port_id = 1;
|
||
|
@@ -3874,6 +3309,7 @@
|
||
|
storlink_ctl.link[ tp->port_id] = 1;
|
||
|
#endif
|
||
|
}
|
||
|
+#endif
|
||
|
if ((ability & 0x20)==0x20)
|
||
|
{
|
||
|
if (tp->flow_control_enable == 0)
|
||
|
@@ -3914,6 +3350,7 @@
|
||
|
else
|
||
|
{
|
||
|
status.bits.link = LINK_DOWN; /* link down */
|
||
|
+#ifdef VITESSE_G5SWITCH
|
||
|
if(Giga_switch == 1)
|
||
|
{
|
||
|
wan_port_id = 1;
|
||
|
@@ -3925,6 +3362,7 @@
|
||
|
storlink_ctl.link[ tp->port_id] = 0;
|
||
|
#endif
|
||
|
}
|
||
|
+#endif
|
||
|
if (tp->pre_phy_status == LINK_UP)
|
||
|
{
|
||
|
printk("GMAC-%d LINK_Down......\n",tp->port_id);
|
||
|
@@ -4298,86 +3736,102 @@
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_SL_NAPI
|
||
|
+
|
||
|
+static int gmax_rx(struct net_device *dev, int *budget)
|
||
|
+{
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+static int gmac_tx(struct net_device *dev, int *budget)
|
||
|
+{
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/*----------------------------------------------------------------------
|
||
|
* gmac_rx_poll
|
||
|
*----------------------------------------------------------------------*/
|
||
|
static int gmac_rx_poll(struct net_device *dev, int *budget)
|
||
|
{
|
||
|
- TOE_INFO_T *toe;
|
||
|
- GMAC_RXDESC_T *curr_desc;
|
||
|
- struct sk_buff *skb;
|
||
|
- DMA_RWPTR_T rwptr;
|
||
|
- unsigned int data32;
|
||
|
- unsigned int pkt_size;
|
||
|
- unsigned int desc_count;
|
||
|
- unsigned int good_frame, chksum_status, rx_status;
|
||
|
- int rx_pkts_num = 0;
|
||
|
- int quota = min(dev->quota, *budget);
|
||
|
- GMAC_INFO_T *tp = (GMAC_INFO_T *)dev->priv;
|
||
|
- unsigned int status4;
|
||
|
- volatile DMA_RWPTR_T fq_rwptr;
|
||
|
- // int max_cnt = TOE_SW_FREEQ_DESC_NUM;//TOE_SW_FREEQ_DESC_NUM = 64
|
||
|
- //unsigned long rx_old_bytes;
|
||
|
+ TOE_INFO_T *toe;
|
||
|
+ GMAC_RXDESC_T *curr_desc;
|
||
|
+ struct sk_buff *skb;
|
||
|
+ DMA_RWPTR_T rwptr;
|
||
|
+ unsigned int data32;
|
||
|
+ unsigned int pkt_size;
|
||
|
+ unsigned int desc_count;
|
||
|
+ unsigned int good_frame, chksum_status, rx_status;
|
||
|
+ int rx_pkts_num = 0;
|
||
|
+ int quota = min(dev->quota, *budget);
|
||
|
+ GMAC_INFO_T *tp = (GMAC_INFO_T *)dev->priv;
|
||
|
+ unsigned int status1;
|
||
|
+ unsigned int status4;
|
||
|
struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
|
||
|
- //unsigned long long rx_time;
|
||
|
-
|
||
|
|
||
|
BUG_ON(rx_poll_enabled == 0);
|
||
|
-#if 1
|
||
|
- if (do_again)
|
||
|
- {
|
||
|
- toe_gmac_fill_free_q();
|
||
|
- status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
- fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- //printk("\n%s:: do_again toe_gmac_fill_free_q =======>status4=0x%x =====fq_rwptr =0x%8x======>JKJKJKJKJKJKJKJKJ \n", __func__,status4,fq_rwptr.bits32);
|
||
|
- if (fq_rwptr.bits.wptr != fq_rwptr.bits.rptr)
|
||
|
- {
|
||
|
- //status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
- do_again =0;
|
||
|
- //netif_rx_complete(dev);
|
||
|
- gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4, 0x1);
|
||
|
- fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
- }
|
||
|
- else
|
||
|
- return 1;
|
||
|
- }
|
||
|
-#endif
|
||
|
- rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
-#if 0
|
||
|
- if (rwptr.bits.rptr != tp->rx_rwptr.bits.rptr)
|
||
|
- {
|
||
|
- mac_stop_txdma((struct net_device *)tp->dev);
|
||
|
- printk("Default Queue HW RD ptr (0x%x) != SW RD Ptr (0x%x)\n",
|
||
|
- rwptr.bits32, tp->rx_rwptr.bits.rptr);
|
||
|
- while(1);
|
||
|
- }
|
||
|
-#endif
|
||
|
+
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
|
||
|
- fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- //printk("%s:---Before-------------->Default Queue HW RW ptr (0x%8x), fq_rwptr =0x%8x \n",__func__,rwptr.bits32,fq_rwptr.bits32 );
|
||
|
- //printk("%s:---Before while rx_pkts_num=%d------rx_finished_idx=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x, rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rx_finished_idx,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
|
||
|
-// while ((--max_cnt) && (rwptr.bits.rptr != rwptr.bits.wptr) && (rx_pkts_num < quota))
|
||
|
+rx_poll_retry:
|
||
|
+ status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
+ if (status1 & 1) {
|
||
|
+ writel(1, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
+ }
|
||
|
|
||
|
+ rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
while ((rwptr.bits.rptr != rwptr.bits.wptr) && (rx_pkts_num < quota))
|
||
|
{
|
||
|
-
|
||
|
- curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
|
||
|
+ curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
|
||
|
tp->default_q_cnt++;
|
||
|
- tp->rx_curr_desc = (unsigned int)curr_desc;
|
||
|
- rx_status = curr_desc->word0.bits.status;
|
||
|
- chksum_status = curr_desc->word0.bits.chksum_status;
|
||
|
- tp->rx_status_cnt[rx_status]++;
|
||
|
- tp->rx_chksum_cnt[chksum_status]++;
|
||
|
- pkt_size = curr_desc->word1.bits.byte_count; /*total byte count in a frame*/
|
||
|
+ tp->rx_curr_desc = (unsigned int)curr_desc;
|
||
|
+ rx_status = curr_desc->word0.bits.status;
|
||
|
+ chksum_status = curr_desc->word0.bits.chksum_status;
|
||
|
+ tp->rx_status_cnt[rx_status]++;
|
||
|
+ tp->rx_chksum_cnt[chksum_status]++;
|
||
|
+ pkt_size = curr_desc->word1.bits.byte_count; /*total byte count in a frame*/
|
||
|
desc_count = curr_desc->word0.bits.desc_count; /* get descriptor count per frame */
|
||
|
good_frame=1;
|
||
|
+
|
||
|
+ if (0) {
|
||
|
+
|
||
|
+ int free, busy;
|
||
|
+ uint32_t rwptr1;
|
||
|
+ uint32_t rwptr2;
|
||
|
+
|
||
|
+ rwptr1 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
+ free = (GET_WPTR(rwptr1) - GET_RPTR(rwptr1)) & 0xFF;
|
||
|
+
|
||
|
+ rwptr2 = readl(&tp->default_qhdr->word1);
|
||
|
+ busy = (GET_RPTR(rwptr2) - GET_WPTR(rwptr2)) & 0xFF;
|
||
|
+
|
||
|
+ if (GET_WPTR(rwptr1) == GET_RPTR(rwptr1)) {
|
||
|
+ printk("frame status: %d\n"
|
||
|
+ "SWFQ: wptr: %hu, rptr: %hu, free: %d\n"
|
||
|
+ "GMAC: wptr: %hu, rptr: %hu, free: %d\n",
|
||
|
+ rx_status,
|
||
|
+ GET_WPTR(rwptr1), GET_RPTR(rwptr1), free,
|
||
|
+ GET_WPTR(rwptr2), GET_RPTR(rwptr2), busy);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ {
|
||
|
+ GMAC_RXDESC_T *fq_desc;
|
||
|
+ void *data;
|
||
|
+ struct sk_buff *skb;
|
||
|
+ unsigned short idx;
|
||
|
+
|
||
|
+ skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
|
||
|
+ idx = (unsigned short)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES + 4));
|
||
|
+
|
||
|
+ BUG_ON(idx > TOE_SW_FREEQ_DESC_NUM);
|
||
|
+ BUG_ON(skb == NULL);
|
||
|
+ fq_desc = (GMAC_RXDESC_T*)toe->swfq_desc_base + idx;
|
||
|
+ fq_desc->word2.buf_adr = 0;
|
||
|
+ }
|
||
|
+
|
||
|
if ((curr_desc->word0.bits32 & (GMAC_RXDESC_0_T_derr | GMAC_RXDESC_0_T_perr))
|
||
|
- || (pkt_size < 60)
|
||
|
+ || (pkt_size < 60)
|
||
|
|| (chksum_status & 0x4)
|
||
|
|| rx_status )
|
||
|
-// || rx_status || (rwptr.bits.rptr > rwptr.bits.wptr ))
|
||
|
{
|
||
|
good_frame = 0;
|
||
|
if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_derr)
|
||
|
@@ -4388,7 +3842,6 @@
|
||
|
{
|
||
|
if (rx_status == 4 || rx_status == 7)
|
||
|
isPtr->rx_crc_errors++;
|
||
|
-// printk("%s::Status=%d (GMAC-%d)!!!\n", __func__, rx_status, tp->port_id);
|
||
|
}
|
||
|
#ifdef SL351x_GMAC_WORKAROUND
|
||
|
else if (pkt_size < 60)
|
||
|
@@ -4407,17 +3860,32 @@
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
-// if (chksum_status)
|
||
|
-// printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
|
||
|
skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
|
||
|
- dev_kfree_skb_irq(skb);
|
||
|
+ dev_kfree_skb(skb);
|
||
|
+
|
||
|
+ if (0) {
|
||
|
+ int free, busy;
|
||
|
+ uint32_t rwptr1;
|
||
|
+ uint32_t rwptr2;
|
||
|
+
|
||
|
+ rwptr1 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
+ free = (GET_WPTR(rwptr1) - GET_RPTR(rwptr1)) & 0xFF;
|
||
|
+
|
||
|
+ rwptr2 = readl(&tp->default_qhdr->word1);
|
||
|
+ busy = (GET_RPTR(rwptr2) - GET_WPTR(rwptr2)) & 0xFF;
|
||
|
+
|
||
|
+ printk("frame status: %d\n"
|
||
|
+ "SWFQ: wptr: %hu, rptr: %hu, free: %d\n"
|
||
|
+ "GMAC: wptr: %hu, rptr: %hu, free: %d\n",
|
||
|
+ rx_status,
|
||
|
+ GET_WPTR(rwptr1), GET_RPTR(rwptr1), free,
|
||
|
+ GET_WPTR(rwptr2), GET_RPTR(rwptr2), busy);
|
||
|
+ }
|
||
|
}
|
||
|
if (good_frame)
|
||
|
{
|
||
|
if (curr_desc->word0.bits.drop)
|
||
|
printk("%s::Drop (GMAC-%d)!!!\n", __func__, tp->port_id);
|
||
|
-// if (chksum_status)
|
||
|
-// printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
|
||
|
|
||
|
#ifdef SL351x_GMAC_WORKAROUND
|
||
|
if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
|
||
|
@@ -4432,225 +3900,118 @@
|
||
|
}
|
||
|
tp->short_frames_cnt = 0;
|
||
|
#endif
|
||
|
- /* get frame information from the first descriptor of the frame */
|
||
|
+ /* get frame information from the first descriptor of the frame */
|
||
|
isPtr->rx_packets++;
|
||
|
- //consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
|
||
|
+ consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
|
||
|
skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
|
||
|
tp->curr_rx_skb = skb;
|
||
|
- // curr_desc->word2.buf_adr = 0;
|
||
|
|
||
|
- //skb_reserve (skb, SKB_RESERVE_BYTES);
|
||
|
skb_reserve (skb, RX_INSERT_BYTES); /* 2 byte align the IP fields. */
|
||
|
- //if ((skb->tail+pkt_size) > skb->end )
|
||
|
- //printk("%s::------------->Here skb->len=%d,pkt_size= %d,skb->head=0x%x,skb->tail= 0x%x, skb->end= 0x%x\n", __func__, skb->len, pkt_size,skb->head,skb->tail,skb->end);
|
||
|
skb_put(skb, pkt_size);
|
||
|
|
||
|
-
|
||
|
skb->dev = dev;
|
||
|
if (chksum_status == RX_CHKSUM_IP_UDP_TCP_OK)
|
||
|
{
|
||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||
|
-#ifdef CONFIG_SL351x_NAT
|
||
|
- if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
|
||
|
- {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
-#endif
|
||
|
skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
-#if 0
|
||
|
-#ifdef CONFIG_SL351x_RXTOE
|
||
|
- if (storlink_ctl.rx_max_pktsize) {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- struct tcphdr *tcp_hdr;
|
||
|
- int ip_hdrlen;
|
||
|
-
|
||
|
- ip_hdr = (struct iphdr*)&(skb->data[0]);
|
||
|
- if ((skb->protocol == __constant_htons(ETH_P_IP)) &&
|
||
|
- ((ip_hdr->protocol & 0x00ff) == IPPROTO_TCP)) {
|
||
|
- ip_hdrlen = ip_hdr->ihl << 2;
|
||
|
- tcp_hdr = (struct tcphdr*)&(skb->data[ip_hdrlen]);
|
||
|
- if (tcp_hdr->syn) {
|
||
|
- struct toe_conn* connection = init_toeq(ip_hdr->version,
|
||
|
- ip_hdr, tcp_hdr, toe, &(skb->data[0]) - 14);
|
||
|
- TCP_SKB_CB(skb)->connection = connection;
|
||
|
- // hash_dump_entry(TCP_SKB_CB(skb)->connection->hash_entry_index);
|
||
|
- // printk("%s::skb data %x, conn %x, mode %x\n",
|
||
|
- // __func__, skb->data, connection, connection->mode);
|
||
|
- }
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
-#endif
|
||
|
}
|
||
|
else if (chksum_status == RX_CHKSUM_IP_OK_ONLY)
|
||
|
{
|
||
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||
|
-#ifdef CONFIG_SL351x_NAT
|
||
|
- if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
|
||
|
- {
|
||
|
- struct iphdr *ip_hdr;
|
||
|
- ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
|
||
|
- if (ip_hdr->protocol == IPPROTO_UDP)
|
||
|
- {
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
- else if (ip_hdr->protocol == IPPROTO_GRE)
|
||
|
- {
|
||
|
- sl351x_nat_input(skb,
|
||
|
- tp->port_id,
|
||
|
- (void *)curr_desc->word3.bits.l3_offset,
|
||
|
- (void *)curr_desc->word3.bits.l4_offset);
|
||
|
- }
|
||
|
- }
|
||
|
-#endif
|
||
|
skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
|
||
|
}
|
||
|
- //netif_rx(skb); /* socket rx */
|
||
|
+
|
||
|
netif_receive_skb(skb); //For NAPI
|
||
|
dev->last_rx = jiffies;
|
||
|
|
||
|
isPtr->rx_bytes += pkt_size;
|
||
|
- //printk("------------------->isPtr->rx_bytes = %d\n",isPtr->rx_bytes);
|
||
|
-
|
||
|
+ }
|
||
|
|
||
|
- }
|
||
|
// advance one for Rx default Q 0/1
|
||
|
rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
|
||
|
SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
|
||
|
- tp->rx_rwptr.bits32 = rwptr.bits32;
|
||
|
+ tp->rx_rwptr.bits32 = rwptr.bits32;
|
||
|
rx_pkts_num++;
|
||
|
- //rwptr.bits32 = readl(&tp->default_qhdr->word1);//try read default_qhdr again
|
||
|
- //fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- //printk("%s:---Loop -------->rx_pkts_num=%d------------>Default Queue HW RW ptr = (0x%8x), fq_rwptr =0x%8x \n",__func__,rx_pkts_num,rwptr.bits32,fq_rwptr.bits32 );
|
||
|
-#if 0
|
||
|
- if ((status4 & 0x1) == 0)
|
||
|
- {
|
||
|
- //if (!((dev->last_rx <= (rx_time + 2)) && (isPtr->rx_bytes > (rx_old_bytes + 1000000 ))))
|
||
|
- if (tp->total_q_cnt_napi < 1024)
|
||
|
- {
|
||
|
- tp->total_q_cnt_napi++;
|
||
|
- toe_gmac_fill_free_q(); //for iperf test disable
|
||
|
- }
|
||
|
- //else
|
||
|
- //printk("%s:---isPtr->rx_bytes =%u , rx_old_bytes =%u\n",__func__,isPtr->rx_bytes,rx_old_bytes );
|
||
|
+ // rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
|
||
|
+ status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+ if (status4 & 1) {
|
||
|
+ writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
}
|
||
|
+
|
||
|
+ toe_gmac_fill_free_q(5);
|
||
|
+ }
|
||
|
+
|
||
|
+#if 0
|
||
|
+ /* avoid races with hard_start_xmit() */
|
||
|
+
|
||
|
+ spin_lock(&gmac_fq_lock);
|
||
|
+ toe_gmac_tx_complete(&toe_private_data.gmac[0], 0, dev, 1);
|
||
|
+ spin_unlock(&gmac_fq_lock);
|
||
|
#endif
|
||
|
- //rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
|
||
|
- //printk("%s:---Loop -------->rx_pkts_num=%d----rwptr.bits.rptr=0x%x-------->Default Queue HW RW ptr = (0x%8x), fq_rwptr =0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits32,fq_rwptr.bits32 );
|
||
|
- //printk("%s:---Loop rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x, rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
|
||
|
+
|
||
|
+ status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+ if (status4 & 1)
|
||
|
+ {
|
||
|
+ writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+ status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
|
||
|
+ toe_gmac_fill_free_q(rx_pkts_num);
|
||
|
}
|
||
|
- // advance one for Rx default Q 0/1
|
||
|
|
||
|
- //rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
|
||
|
- //SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
|
||
|
- //tp->rx_rwptr.bits32 = rwptr.bits32;
|
||
|
- //rwptr.bits.rptr = rwptr.bits.rptr;
|
||
|
+ rwptr.bits32 = readl(&tp->default_qhdr->word1);
|
||
|
+ if (rwptr.bits.rptr != rwptr.bits.wptr &&
|
||
|
+ quota > rx_pkts_num)
|
||
|
+ goto rx_poll_retry;
|
||
|
|
||
|
dev->quota -= rx_pkts_num;
|
||
|
*budget -= rx_pkts_num;
|
||
|
|
||
|
- status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);//try read SWFQ empty again
|
||
|
- //fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
||
|
- rwptr.bits32 = readl(&tp->default_qhdr->word1); //try read default_qhdr again
|
||
|
- //printk("%s:---After rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x, rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
|
||
|
-// if (rwptr.bits.rptr > rwptr.bits.wptr )
|
||
|
-// {
|
||
|
- //toe_gmac_disable_rx(dev);
|
||
|
- //wait_event_interruptible_timeout(freeq_wait,
|
||
|
- //(rx_pkts_num == 100), CMTP_INTEROP_TIMEOUT);
|
||
|
- //printk("\n%s:: return 22222=======> rx_pkts_num =%d, rwptr.bits.rptr=%d, rwptr.bits.wptr = %d ====---------=======>JKJKJKJKJK\n",
|
||
|
- //__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
|
||
|
-// return 1;
|
||
|
-// }
|
||
|
-
|
||
|
- if (rwptr.bits.rptr == rwptr.bits.wptr)
|
||
|
+ /* Receive queue is empty now */
|
||
|
+ if (quota >= rx_pkts_num)
|
||
|
{
|
||
|
- // unsigned int data32;
|
||
|
- //printk("%s:---[rwptr.bits.rptr == rwptr.bits.wptr] rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x, rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
|
||
|
-
|
||
|
- /* Receive descriptor is empty now */
|
||
|
-#if 1
|
||
|
- if (status4 & 0x1)
|
||
|
- {
|
||
|
- do_again =1;
|
||
|
- //writel(0x40400000, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_4_REG); //disable SWFQ empty interrupt
|
||
|
- //toe_gmac_disable_interrupt(tp->irq);
|
||
|
- tp->sw_fq_empty_cnt++;
|
||
|
- //toe_gmac_disable_rx(dev);
|
||
|
- writel(0x07960202, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- writel(0x07960202, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- //printk("\n%s :: freeq int-----tp->sw_fq_empty_cnt =%d---------====================----------------->\n",__func__,tp->sw_fq_empty_cnt);
|
||
|
- //while ((fq_rwptr.bits.wptr >= (fq_rwptr.bits.rptr+256)) || (fq_rwptr.bits.wptr <= (fq_rwptr.bits.rptr+256)))
|
||
|
- //{
|
||
|
- //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
|
||
|
- //0x1);
|
||
|
- //printk("\n%s::fq_rwptr.wrptr = %x =======> ===========>here \n", __func__,fq_rwptr.bits32);
|
||
|
- //if ((status4 & 0x1) == 0)
|
||
|
- //break;
|
||
|
- return 1;
|
||
|
- //}
|
||
|
+ unsigned long flags;
|
||
|
|
||
|
+ netif_rx_complete(dev);
|
||
|
+ rx_poll_enabled = 0;
|
||
|
+#if 0
|
||
|
+ status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
|
||
|
+ if (status1 & 1) {
|
||
|
+ if (netif_rx_reschedule(dev, rx_pkts_num)) {
|
||
|
+ rx_poll_enabled = 1;
|
||
|
+ return 1;
|
||
|
}
|
||
|
+ }
|
||
|
#endif
|
||
|
- //toe_gmac_fill_free_q();
|
||
|
- netif_rx_complete(dev);
|
||
|
-
|
||
|
- rx_poll_enabled = 0;
|
||
|
|
||
|
- data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- if (tp->port_id == 0)
|
||
|
- data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
- else
|
||
|
- data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
- writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
+ spin_lock_irqsave(&gmac_fq_lock, flags);
|
||
|
|
||
|
data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
if (tp->port_id == 0)
|
||
|
- data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
+ data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
else
|
||
|
- data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
+ data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
||
|
|
||
|
- data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
if (tp->port_id == 0)
|
||
|
- data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
+ data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
else
|
||
|
- data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
- writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
||
|
+ data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
|
||
|
- // enable GMAC-0 rx interrupt
|
||
|
- // class-Q & TOE-Q are implemented in future
|
||
|
- //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //if (tp->port_id == 0)
|
||
|
- //data32 |= DEFAULT_Q0_INT_BIT;
|
||
|
- //else
|
||
|
- //data32 |= DEFAULT_Q1_INT_BIT;
|
||
|
- //writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- writel(0x3, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
|
||
|
- //printk("\n%s::netif_rx_complete--> rx_pkts_num =%d, rwptr.bits.rptr=0x%x, rwptr.bits.wptr = 0x%x ====---------=======>JKJKJKJKJK\n",
|
||
|
- //__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
|
||
|
- writel(0x07960200, TOE_GMAC0_BASE+GMAC_CONFIG0);
|
||
|
- writel(0x07960200, TOE_GMAC1_BASE+GMAC_CONFIG0);
|
||
|
- return 0;
|
||
|
- }
|
||
|
- else
|
||
|
- {
|
||
|
- //printk("\n%s:: return 1 -->status4= 0x%x,rx_pkts_num =%d, rwptr.bits.rptr=0x%x, rwptr.bits.wptr = 0x%x ======> \n", __func__,status4,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
|
||
|
- return 1;
|
||
|
- }
|
||
|
+ spin_unlock_irqrestore(&gmac_fq_lock, flags);
|
||
|
+
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ /* not done, will call ->poll() later. */
|
||
|
+ return 1;
|
||
|
+ }
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
@@ -5114,6 +4475,7 @@
|
||
|
{
|
||
|
sl351x_nat_workaround_cnt++;
|
||
|
sl351x_nat_workaround_handler();
|
||
|
+ printk("%():%d - workaround\n", __func__, __LINE__);
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
@@ -5124,6 +4486,7 @@
|
||
|
}
|
||
|
|
||
|
do_workaround:
|
||
|
+ printk("doing workaround ?!\n");
|
||
|
|
||
|
gmac_initialized = 0;
|
||
|
if (hanged_state)
|
||
|
@@ -5290,6 +4653,7 @@
|
||
|
GMAC_SWTXQ_T *swtxq;
|
||
|
DMA_RWPTR_T rwptr;
|
||
|
|
||
|
+ printk("**** %s():%d\n", __func__, __LINE__);
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
tp = (GMAC_INFO_T *)&toe->gmac[0];
|
||
|
for (i=0; i<GMAC_NUM; i++, tp++)
|
||
|
@@ -5341,6 +4705,7 @@
|
||
|
volatile GMAC_RXDESC_T *curr_desc;
|
||
|
struct sk_buff *skb;
|
||
|
|
||
|
+ printk("**** %s():%d\n", __func__, __LINE__);
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
tp = (GMAC_INFO_T *)&toe->gmac[0];
|
||
|
for (i=0; i<GMAC_NUM; i++, tp++)
|
||
|
@@ -5374,6 +4739,7 @@
|
||
|
volatile GMAC_RXDESC_T *curr_desc;
|
||
|
struct sk_buff *skb;
|
||
|
|
||
|
+ printk("**** %s():%d\n", __func__, __LINE__);
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
classq = (CLASSQ_INFO_T *)&toe->classq[0];
|
||
|
for (i=0; i<TOE_CLASS_QUEUE_NUM; i++, classq++)
|
||
|
@@ -5410,6 +4776,7 @@
|
||
|
GMAC_RXDESC_T *toe_curr_desc;
|
||
|
struct sk_buff *skb;
|
||
|
|
||
|
+ printk("**** %s():%d\n", __func__, __LINE__);
|
||
|
toe = (TOE_INFO_T *)&toe_private_data;
|
||
|
toe_qhdr = (TOE_QHDR_T *)TOE_TOE_QUE_HDR_BASE;
|
||
|
for (i=0; i<TOE_TOE_QUEUE_NUM; i++, toe_qhdr++)
|
||
|
--- a/include/asm-arm/arch-sl2312/sl351x_gmac.h
|
||
|
+++ b/include/asm-arm/arch-sl2312/sl351x_gmac.h
|
||
|
@@ -107,7 +107,7 @@
|
||
|
* The base address and descriptor number are configured at
|
||
|
* DMA Queues Descriptor Ring Base Address/Size Register (offset 0x0004)
|
||
|
**********************************************************************/
|
||
|
-#define TOE_SW_FREEQ_DESC_POWER 10
|
||
|
+#define TOE_SW_FREEQ_DESC_POWER 8
|
||
|
#define TOE_SW_FREEQ_DESC_NUM (1<<TOE_SW_FREEQ_DESC_POWER)
|
||
|
#define TOE_HW_FREEQ_DESC_POWER 8
|
||
|
#define TOE_HW_FREEQ_DESC_NUM (1<<TOE_HW_FREEQ_DESC_POWER)
|
||
|
@@ -123,12 +123,12 @@
|
||
|
#define TOE_DEFAULT_Q0_DESC_NUM (1<<TOE_DEFAULT_Q0_DESC_POWER)
|
||
|
#define TOE_DEFAULT_Q1_DESC_POWER 8
|
||
|
#define TOE_DEFAULT_Q1_DESC_NUM (1<<TOE_DEFAULT_Q1_DESC_POWER)
|
||
|
-#define TOE_TOE_DESC_POWER 8
|
||
|
-#define TOE_TOE_DESC_NUM (1<<TOE_TOE_DESC_POWER)
|
||
|
+#define TOE_TOE_DESC_POWER 8
|
||
|
+#define TOE_TOE_DESC_NUM (1<<TOE_TOE_DESC_POWER)
|
||
|
#define TOE_CLASS_DESC_POWER 8
|
||
|
-#define TOE_CLASS_DESC_NUM (1<<TOE_CLASS_DESC_POWER)
|
||
|
-#define TOE_INTR_DESC_POWER 8
|
||
|
-#define TOE_INTR_DESC_NUM (1<<TOE_INTR_DESC_POWER)
|
||
|
+#define TOE_CLASS_DESC_NUM (1<<TOE_CLASS_DESC_POWER)
|
||
|
+#define TOE_INTR_DESC_POWER 8
|
||
|
+#define TOE_INTR_DESC_NUM (1<<TOE_INTR_DESC_POWER)
|
||
|
|
||
|
#define TOE_TOE_QUEUE_MAX 64
|
||
|
#define TOE_TOE_QUEUE_NUM 64
|