mirror of https://github.com/hak5/openwrt.git
249 lines
9.1 KiB
Diff
249 lines
9.1 KiB
Diff
--- a/drivers/net/sl351x_gmac.c
|
|
+++ b/drivers/net/sl351x_gmac.c
|
|
@@ -127,6 +127,7 @@ static char _debug_prefetch_buf[_DEBUG_P
|
|
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;
|
|
|
|
@@ -1065,7 +1066,8 @@ static void toe_init_gmac(struct net_dev
|
|
tp->intr3_enabled = 0xffffffff;
|
|
tp->intr4_selected = GMAC0_INT_BITS | CLASS_RX_FULL_INT_BITS |
|
|
HWFQ_EMPTY_INT_BIT | SWFQ_EMPTY_INT_BIT;
|
|
- tp->intr4_enabled = GMAC0_INT_BITS | SWFQ_EMPTY_INT_BIT;
|
|
+ tp->intr4_enabled = GMAC0_INT_BITS | SWFQ_EMPTY_INT_BIT| GMAC0_RX_OVERRUN_INT_BIT;
|
|
+ // GMAC0_TX_PAUSE_OFF_INT_BIT| GMAC0_MIB_INT_BIT;
|
|
|
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) & ~tp->intr0_selected;
|
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
|
|
@@ -1115,7 +1117,7 @@ static void toe_init_gmac(struct net_dev
|
|
tp->intr3_enabled |= 0xffffffff;
|
|
tp->intr4_selected |= CLASS_RX_FULL_INT_BITS |
|
|
HWFQ_EMPTY_INT_BIT | SWFQ_EMPTY_INT_BIT;
|
|
- tp->intr4_enabled |= SWFQ_EMPTY_INT_BIT;
|
|
+ tp->intr4_enabled |= SWFQ_EMPTY_INT_BIT | GMAC1_RX_OVERRUN_INT_BIT;
|
|
}
|
|
data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) | tp->intr0_selected;
|
|
writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
|
|
@@ -2408,7 +2410,7 @@ static inline void toe_gmac_fill_free_q(
|
|
// unsigned short max_cnt=TOE_SW_FREEQ_DESC_NUM>>1;
|
|
|
|
fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
|
|
- spin_lock_irqsave(&gmac_fq_lock, flags);
|
|
+ // 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,
|
|
@@ -2428,10 +2430,47 @@ static inline void toe_gmac_fill_free_q(
|
|
SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, fq_rwptr.bits.wptr);
|
|
toe_private_data.fq_rx_rwptr.bits32 = fq_rwptr.bits32;
|
|
}
|
|
- spin_unlock_irqrestore(&gmac_fq_lock, flags);
|
|
+ // spin_unlock_irqrestore(&gmac_fq_lock, flags);
|
|
}
|
|
// EXPORT_SYMBOL(toe_gmac_fill_free_q);
|
|
|
|
+static void gmac_registers(const char *message)
|
|
+{
|
|
+ unsigned int status0;
|
|
+ unsigned int status1;
|
|
+ unsigned int status2;
|
|
+ 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("status: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
|
|
+ status0, status1, status2, status3, status4);
|
|
+
|
|
+ status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_0_REG);
|
|
+ status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|
|
+ status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_2_REG);
|
|
+ status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_3_REG);
|
|
+ status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
|
|
+
|
|
+ printk("mask : s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
|
|
+ status0, status1, status2, status3, status4);
|
|
+
|
|
+ status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
|
|
+ status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG);
|
|
+ status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG);
|
|
+ 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);
|
|
+}
|
|
/*----------------------------------------------------------------------
|
|
* toe_gmac_interrupt
|
|
*----------------------------------------------------------------------*/
|
|
@@ -2492,6 +2531,7 @@ if (1)
|
|
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) {
|
|
@@ -2536,10 +2576,31 @@ if (1)
|
|
}
|
|
if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
|
|
{
|
|
- if (likely(netif_rx_schedule_prep(dev)))
|
|
+ if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
|
|
{
|
|
- // unsigned int data32;
|
|
- // disable GMAC-0 rx interrupt
|
|
+ unsigned int data32;
|
|
+
|
|
+ if (rx_poll_enabled)
|
|
+ gmac_registers("check #1");
|
|
+
|
|
+ BUG_ON(rx_poll_enabled == 1);
|
|
+
|
|
+#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;
|
|
@@ -2549,7 +2610,8 @@ if (1)
|
|
//tp->total_q_cnt_napi=0;
|
|
//rx_time = jiffies;
|
|
//rx_old_bytes = isPtr->rx_bytes;
|
|
- __netif_rx_schedule(dev);
|
|
+ __netif_rx_schedule(dev);
|
|
+ rx_poll_enabled = 1;
|
|
}
|
|
}
|
|
}
|
|
@@ -2569,9 +2631,31 @@ if (1)
|
|
|
|
if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
|
|
{
|
|
- if (likely(netif_rx_schedule_prep(dev)))
|
|
+ if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
|
|
{
|
|
- // unsigned int data32;
|
|
+ unsigned int data32;
|
|
+
|
|
+ if (rx_poll_enabled)
|
|
+ gmac_registers("check #2");
|
|
+
|
|
+ BUG_ON(rx_poll_enabled == 1);
|
|
+
|
|
+#if 0
|
|
+ /* Masks GMAC-1 rx interrupt */
|
|
+ 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);
|
|
+
|
|
+ /* 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);
|
|
+
|
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
|
+ data32 &= ~DEFAULT_Q1_INT_BIT;
|
|
+ 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);
|
|
@@ -2583,9 +2667,13 @@ if (1)
|
|
//rx_time = jiffies;
|
|
//rx_old_bytes = isPtr->rx_bytes;
|
|
__netif_rx_schedule(dev);
|
|
+ rx_poll_enabled = 1;
|
|
}
|
|
}
|
|
}
|
|
+ } else {
|
|
+
|
|
+ gmac_registers("check #3");
|
|
}
|
|
|
|
// Interrupt Status 0
|
|
@@ -3306,8 +3394,10 @@ next_rx:
|
|
SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
|
|
tp->rx_rwptr.bits32 = rwptr.bits32;
|
|
|
|
- toe_gmac_fill_free_q();
|
|
}
|
|
+
|
|
+ /* Handles first available packets only then refill the queue. */
|
|
+ toe_gmac_fill_free_q();
|
|
}
|
|
|
|
/*----------------------------------------------------------------------
|
|
@@ -4217,6 +4307,7 @@ static int gmac_rx_poll(struct net_devic
|
|
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;
|
|
@@ -4231,7 +4322,7 @@ static int gmac_rx_poll(struct net_devic
|
|
//unsigned long long rx_time;
|
|
|
|
|
|
-
|
|
+ BUG_ON(rx_poll_enabled == 0);
|
|
#if 1
|
|
if (do_again)
|
|
{
|
|
@@ -4516,6 +4607,30 @@ static int gmac_rx_poll(struct net_devic
|
|
#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);
|
|
+
|
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_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_4_REG);
|
|
+
|
|
+ data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
|
+ if (tp->port_id == 0)
|
|
+ data32 |= DEFAULT_Q0_INT_BIT;
|
|
+ else
|
|
+ data32 |= DEFAULT_Q1_INT_BIT;
|
|
+ writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
|
|
+
|
|
// enable GMAC-0 rx interrupt
|
|
// class-Q & TOE-Q are implemented in future
|
|
//data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
|