source: src/linux/pb42/linux-2.6.23/drivers/net/ag7100/ag7100.c @ 14423

Last change on this file since 14423 was 14423, checked in by BrainSlayer, 3 years ago

solve hangs

File size: 65.8 KB
Line 
1#include <linux/stddef.h>
2#include <linux/autoconf.h>
3#include <linux/module.h>
4#include <linux/types.h>
5#include <asm/byteorder.h>
6#include <linux/init.h>
7#include <linux/errno.h>
8#include <linux/kernel.h>
9#include <linux/netdevice.h>
10#include <linux/etherdevice.h>
11#include <linux/skbuff.h>
12#include <linux/delay.h>
13#include <linux/timer.h>
14#include <linux/interrupt.h>
15#include <linux/dma-mapping.h>
16#include <linux/bitops.h>
17#include <asm/irq.h>
18#include <asm/io.h>
19#include <net/sch_generic.h>
20#include <asm/unaligned.h>
21
22#include "ag7100.h"
23#include "ag7100_phy.h"
24#include "ag7100_trc.h"
25#ifdef CONFIG_BUFFALO
26#include "rtl8366_smi.h"
27RTL8366_FUNCS rtl_funcs =
28{
29        NULL,
30        NULL,
31        NULL,
32        NULL,
33        NULL
34};
35#endif //CONFIG_BUFFALO //
36
37unsigned int rx_hang_detect_pkt_cnt_all[2], rx_hang_detect_pkt_cnt_valid[2],rx_hang_detected[2];
38int set_mac_from_link_flag = 0;
39static ag7100_mac_t *ag7100_macs[2];
40static void ag7100_hw_setup(ag7100_mac_t *mac);
41static void ag7100_hw_stop(ag7100_mac_t *mac);
42static void ag7100_oom_timer(unsigned long data);
43static int  ag7100_check_link(ag7100_mac_t *mac);
44static int  check_for_dma_hang(ag7100_mac_t *mac);
45static int  ag7100_tx_alloc(ag7100_mac_t *mac);
46static int  ag7100_rx_alloc(ag7100_mac_t *mac);
47static void ag7100_rx_free(ag7100_mac_t *mac);
48static void ag7100_tx_free(ag7100_mac_t *mac);
49static int  ag7100_ring_alloc(ag7100_ring_t *r, int count);
50static int  ag7100_rx_replenish(ag7100_mac_t *mac);
51static int  ag7100_tx_reap(ag7100_mac_t *mac);
52static void ag7100_ring_release(ag7100_mac_t *mac, ag7100_ring_t  *r);
53static void ag7100_ring_free(ag7100_ring_t *r);
54static void ag7100_tx_timeout_task(struct work_struct *work);
55static void ag7100_get_default_macaddr(ag7100_mac_t *mac, u8 *mac_addr);
56#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
57static int ag7100_poll(struct napi_struct *napi, int budget);
58#else
59static int ag7100_poll(struct net_device *dev, int *budget);
60#endif
61static void ag7100_buffer_free(struct sk_buff *skb);
62void ag7100_dma_reset(ag7100_mac_t *mac);
63int board_version;
64int  ag7100_recv_packets(struct net_device *dev, ag7100_mac_t *mac,
65    int max_work, int *work_done);
66static irqreturn_t ag7100_intr(int cpl, void *dev_id);
67static struct sk_buff * ag7100_buffer_alloc(void);
68
69char *mii_str[2][4] = {
70    {"GMii", "Mii", "RGMii", "RMii"},
71    {"RGMii", "RMii", "INVL1", "INVL2"}
72};
73char *spd_str[] = {"10Mbps", "100Mbps", "1000Mbps"};
74char *dup_str[] = {"half duplex", "full duplex"};
75
76#define MODULE_NAME "AG7100"
77
78/* if 0 compute in init */
79int tx_len_per_ds = 0;
80#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
81void  ag7100_tx_flush(ag7100_mac_t *mac);
82void howl_10baset_war(ag7100_mac_t *mac);
83#endif
84module_param(tx_len_per_ds, int, 0);
85MODULE_PARM_DESC(tx_len_per_ds, "Size of DMA chunk");
86
87/* if 0 compute in init */
88int tx_max_desc_per_ds_pkt=0;
89
90/* if 0 compute in init */
91#ifdef CONFIG_AR9100
92int fifo_3 = 0x780008;
93#else
94int fifo_3 = 0;
95#endif
96module_param(fifo_3, int, 0);
97MODULE_PARM_DESC(fifo_3, "fifo cfg 3 settings");
98
99int mii0_if = AG7100_MII0_INTERFACE;
100module_param(mii0_if, int, 0);
101MODULE_PARM_DESC(mii0_if, "mii0 connect");
102
103int mii1_if = AG7100_MII1_INTERFACE;
104module_param(mii1_if, int, 0);
105MODULE_PARM_DESC(mii1_if, "mii1 connect");
106#ifndef CONFIG_AR9100
107#ifdef CONFIG_CAMEO_REALTEK_PHY
108int gige_pll = 0x11110000;
109int rtl_chip_type_select(void);
110#else
111int gige_pll = 0x0110000;
112#endif
113unsigned int e1000sr_pll[2]     = { 0x1e000100ul, 0x1e000100ul };
114unsigned int e1000rb_pll[2]     = { 0x1f000000ul, 0x00000100ul };
115unsigned int e100sr_pll[2]      = { 0x13000a44ul, 0x13000a44ul };
116unsigned int e100rb_pll[2]      = { 0x13000a44ul, 0x13000a44ul };
117unsigned int e10sr_pll[2]       = { 0x13000a44ul, 0x00441099ul };
118unsigned int e10rb_pll[2]       = { 0x13000a44ul, 0x00441099ul };
119unsigned int * e1000_pll;
120unsigned int * e100_pll;
121unsigned int * e10_pll;
122#else
123#ifdef  CONFIG_BUFFALO
124unsigned int e1000sr_pll[2]     = { 0x1e000100ul, 0x1e000100ul };
125#ifdef CONFIG_TPLINK
126unsigned int e1000rb_pll[2]     = { 0x1a000000ul, 0x1a000000ul };
127#else
128unsigned int e1000rb_pll[2]     = { 0x1f000000ul, 0x00000100ul };
129#endif
130
131unsigned int e100sr_pll[2]      = { 0x13000a44ul, 0x13000a44ul };
132unsigned int e100rb_pll[2]      = { 0x13000a44ul, 0x13000a44ul };
133unsigned int e10sr_pll[2]       = { 0x13000a44ul, 0x00441099ul };
134unsigned int e10rb_pll[2]       = { 0x13000a44ul, 0x00441099ul };
135unsigned int * e1000_pll;
136unsigned int * e100_pll;
137unsigned int * e10_pll;
138#endif  // CONFIG_BUFFALO //
139#ifdef CONFIG_RTL8366RB_SMI
140#define SW_PLL 0x1a000000ul
141#elif defined(CONFIG_RTL8366RB_SMI_MODULE)
142#define SW_PLL 0x1a000000ul
143#else
144#define SW_PLL 0x1f000000ul
145#endif
146
147int gige_pll = 0x1a000000;
148#endif
149module_param(gige_pll, int, 0);
150MODULE_PARM_DESC(gige_pll, "Pll for (R)GMII if");
151
152/*
153* Cfg 5 settings
154* Weed out junk frames (CRC errored, short collision'ed frames etc.)
155*/
156int fifo_5 = 0x7ffef;
157module_param(fifo_5, int, 0);
158MODULE_PARM_DESC(fifo_5, "fifo cfg 5 settings");
159
160#define addr_to_words(addr, w1, w2)  {                                 \
161    w1 = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]; \
162    w2 = (addr[4] << 24) | (addr[5] << 16) | 0;                        \
163}
164
165/*
166 * Defines specific to this implemention
167 */
168
169#ifndef CONFIG_AG7100_LEN_PER_TX_DS
170#error Please run menuconfig and define CONFIG_AG7100_LEN_PER_TX_DS
171#endif
172
173#ifndef CONFIG_AG7100_NUMBER_TX_PKTS
174#error Please run menuconfig and define CONFIG_AG7100_NUMBER_TX_PKTS
175#endif
176
177#ifndef CONFIG_AG7100_NUMBER_RX_PKTS
178#error Please run menuconfig and define CONFIG_AG7100_NUMBER_RX_PKTS
179#endif
180#define AG7100_TX_FIFO_LEN          2048
181#define AG7100_TX_MIN_DS_LEN        128
182#define AG7100_TX_MAX_DS_LEN        AG7100_TX_FIFO_LEN
183
184#define AG7100_TX_MTU_LEN           1536
185
186#define AG7100_TX_DESC_CNT           CONFIG_AG7100_NUMBER_TX_PKTS*tx_max_desc_per_ds_pkt
187#define AG7100_TX_REAP_THRESH        AG7100_TX_DESC_CNT/2
188#define AG7100_TX_QSTART_THRESH      4*tx_max_desc_per_ds_pkt
189
190#define AG7100_RX_DESC_CNT           CONFIG_AG7100_NUMBER_RX_PKTS
191
192#define AG7100_NAPI_WEIGHT           64
193#define AG7100_PHY_POLL_SECONDS      2
194int dma_flag = 0;
195static inline int ag7100_tx_reap_thresh(ag7100_mac_t *mac)
196{
197    ag7100_ring_t *r = &mac->mac_txring;
198#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
199    if(mac->speed_10t)
200        return (ag7100_ndesc_unused(mac, r) < 2);
201    else
202#endif
203    return (ag7100_ndesc_unused(mac, r) < AG7100_TX_REAP_THRESH);
204}
205
206static inline int ag7100_tx_ring_full(ag7100_mac_t *mac)
207{
208    ag7100_ring_t *r = &mac->mac_txring;
209
210    ag7100_trc_new(ag7100_ndesc_unused(mac, r),"tx ring full");
211    return (ag7100_ndesc_unused(mac, r) < tx_max_desc_per_ds_pkt + 2);
212}
213
214
215static int
216ag7100_open(struct net_device *dev)
217{
218    unsigned int w1 = 0, w2 = 0;
219    ag7100_mac_t *mac = (ag7100_mac_t *)dev->priv;
220    int st;
221#if defined(CONFIG_AR9100) && defined(SWITCH_AHB_FREQ)
222    u32 tmp_pll, pll;
223#endif
224
225    assert(mac);
226
227    st = request_irq(mac->mac_irq, ag7100_intr, 0, dev->name, dev);
228    if (st < 0)
229    {
230        printk(MODULE_NAME ": request irq %d failed %d\n", mac->mac_irq, st);
231        return 1;
232    }
233    if (ag7100_tx_alloc(mac)) goto tx_failed;
234    if (ag7100_rx_alloc(mac)) goto rx_failed;
235
236    ag7100_hw_setup(mac);
237#if defined(CONFIG_AR9100) && defined(SWITCH_AHB_FREQ)
238    /*
239    * Reduce the AHB frequency to 100MHz while setting up the
240    * S26 phy.
241    */
242    pll= ar7100_reg_rd(AR7100_PLL_CONFIG);
243    tmp_pll = pll& ~((PLL_DIV_MASK << PLL_DIV_SHIFT) | (PLL_REF_DIV_MASK << PLL_REF_DIV_SHIFT));
244    tmp_pll = tmp_pll | (0x64 << PLL_DIV_SHIFT) |
245        (0x5 << PLL_REF_DIV_SHIFT) | (1 << AHB_DIV_SHIFT);
246
247    ar7100_reg_wr_nf(AR7100_PLL_CONFIG, tmp_pll);
248    udelay(100*1000);
249#endif
250
251#if defined(CONFIG_ATHRS26_PHY)
252    /* if using header for register configuration, we have to     */
253    /* configure s26 register after frame transmission is enabled */
254    if (mac->mac_unit == 1) /* wan phy */
255        athrs26_reg_init();
256#elif defined(CONFIG_ATHRS16_PHY)
257    if (mac->mac_unit == 1)
258        athrs16_reg_init();
259#endif
260
261    ag7100_phy_setup(mac->mac_unit);
262
263#if defined(CONFIG_AR9100) && defined(SWITCH_AHB_FREQ)
264    ar7100_reg_wr_nf(AR7100_PLL_CONFIG, pll);
265    udelay(100*1000);
266#endif
267    /*
268    * set the mac addr
269    */
270    addr_to_words(dev->dev_addr, w1, w2);
271    ag7100_reg_wr(mac, AG7100_GE_MAC_ADDR1, w1);
272    ag7100_reg_wr(mac, AG7100_GE_MAC_ADDR2, w2);
273
274    /*
275    * phy link mgmt
276    */
277    rx_hang_detect_pkt_cnt_all[mac->mac_unit] = ag7100_get_rx_count(mac);           
278    rx_hang_detect_pkt_cnt_valid[mac->mac_unit] = mac->net_rx_packets;
279    rx_hang_detected[mac->mac_unit] = 0;
280
281    init_timer(&mac->mac_phy_timer);
282    mac->mac_phy_timer.data     = (unsigned long)mac;
283    mac->mac_phy_timer.function = ag7100_check_link;
284    ag7100_check_link(mac);
285
286    dev->trans_start = jiffies;
287
288    napi_enable(&mac->mac_napi);
289    ag7100_int_enable(mac);
290    ag7100_rx_start(mac);
291    netif_start_queue(dev);
292
293    ag7100_start_rx_count(mac);
294
295
296
297    return 0;
298
299rx_failed:
300    ag7100_tx_free(mac);
301tx_failed:
302    free_irq(mac->mac_irq, dev);
303    return 1;
304}
305
306static int
307ag7100_stop(struct net_device *dev)
308{
309    ag7100_mac_t *mac = (ag7100_mac_t *)dev->priv;
310    int flags;
311
312    spin_lock_irqsave(&mac->mac_lock, flags);
313    napi_disable(&mac->mac_napi);
314    netif_stop_queue(dev);
315    netif_carrier_off(dev);
316
317    ag7100_hw_stop(mac);
318    free_irq(mac->mac_irq, dev);
319
320   /*
321    *  WAR for bug:32681 reduces the no of TX buffers to five from the
322    *  actual number  of allocated buffers. Revert the value before freeing
323    *  them to avoid memory leak
324    */
325#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
326    mac->mac_txring.ring_nelem = AG7100_TX_DESC_CNT;
327    mac->speed_10t = 0;
328#endif
329
330    ag7100_tx_free(mac);
331    ag7100_rx_free(mac);
332
333
334    del_timer(&mac->mac_phy_timer);
335    spin_unlock_irqrestore(&mac->mac_lock, flags);
336
337    /*ag7100_trc_dump();*/
338    return 0;
339}
340
341#define FIFO_CFG0_WTM           BIT(0)  /* Watermark Module */
342#define FIFO_CFG0_RXS           BIT(1)  /* Rx System Module */
343#define FIFO_CFG0_RXF           BIT(2)  /* Rx Fabric Module */
344#define FIFO_CFG0_TXS           BIT(3)  /* Tx System Module */
345#define FIFO_CFG0_TXF           BIT(4)  /* Tx Fabric Module */
346#define FIFO_CFG0_ALL   (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
347                        | FIFO_CFG0_TXS | FIFO_CFG0_TXF)
348
349#define FIFO_CFG0_ENABLE_SHIFT  8
350
351#define FIFO_CFG4_DE            BIT(0)  /* Drop Event */
352#define FIFO_CFG4_DV            BIT(1)  /* RX_DV Event */
353#define FIFO_CFG4_FC            BIT(2)  /* False Carrier */
354#define FIFO_CFG4_CE            BIT(3)  /* Code Error */
355#define FIFO_CFG4_CR            BIT(4)  /* CRC error */
356#define FIFO_CFG4_LM            BIT(5)  /* Length Mismatch */
357#define FIFO_CFG4_LO            BIT(6)  /* Length out of range */
358#define FIFO_CFG4_OK            BIT(7)  /* Packet is OK */
359#define FIFO_CFG4_MC            BIT(8)  /* Multicast Packet */
360#define FIFO_CFG4_BC            BIT(9)  /* Broadcast Packet */
361#define FIFO_CFG4_DR            BIT(10) /* Dribble */
362#define FIFO_CFG4_LE            BIT(11) /* Long Event */
363#define FIFO_CFG4_CF            BIT(12) /* Control Frame */
364#define FIFO_CFG4_PF            BIT(13) /* Pause Frame */
365#define FIFO_CFG4_UO            BIT(14) /* Unsupported Opcode */
366#define FIFO_CFG4_VT            BIT(15) /* VLAN tag detected */
367#define FIFO_CFG4_FT            BIT(16) /* Frame Truncated */
368#define FIFO_CFG4_UC            BIT(17) /* Unicast Packet */
369
370#define FIFO_CFG5_DE            BIT(0)  /* Drop Event */
371#define FIFO_CFG5_DV            BIT(1)  /* RX_DV Event */
372#define FIFO_CFG5_FC            BIT(2)  /* False Carrier */
373#define FIFO_CFG5_CE            BIT(3)  /* Code Error */
374#define FIFO_CFG5_LM            BIT(4)  /* Length Mismatch */
375#define FIFO_CFG5_LO            BIT(5)  /* Length Out of Range */
376#define FIFO_CFG5_OK            BIT(6)  /* Packet is OK */
377#define FIFO_CFG5_MC            BIT(7)  /* Multicast Packet */
378#define FIFO_CFG5_BC            BIT(8)  /* Broadcast Packet */
379#define FIFO_CFG5_DR            BIT(9)  /* Dribble */
380#define FIFO_CFG5_CF            BIT(10) /* Control Frame */
381#define FIFO_CFG5_PF            BIT(11) /* Pause Frame */
382#define FIFO_CFG5_UO            BIT(12) /* Unsupported Opcode */
383#define FIFO_CFG5_VT            BIT(13) /* VLAN tag detected */
384#define FIFO_CFG5_LE            BIT(14) /* Long Event */
385#define FIFO_CFG5_FT            BIT(15) /* Frame Truncated */
386#define FIFO_CFG5_16            BIT(16) /* unknown */
387#define FIFO_CFG5_17            BIT(17) /* unknown */
388#define FIFO_CFG5_SF            BIT(18) /* Short Frame */
389#define FIFO_CFG5_BM            BIT(19) /* Byte Mode */
390
391
392#define FIFO_CFG0_INIT  (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
393
394#define FIFO_CFG4_INIT  (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
395                         FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
396                         FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
397                         FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
398                         FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
399                         FIFO_CFG4_VT)
400
401#define FIFO_CFG5_INIT  (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
402                         FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
403                         FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
404                         FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
405                         FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
406                         FIFO_CFG5_17 | FIFO_CFG5_SF)
407
408
409static void
410ag7100_hw_setup(ag7100_mac_t *mac)
411{
412    ag7100_ring_t *tx = &mac->mac_txring, *rx = &mac->mac_rxring;
413    ag7100_desc_t *r0, *t0;
414#ifdef CONFIG_AR9100
415#ifndef CONFIG_PORT0_AS_SWITCH
416    if(mac->mac_unit) {
417#ifdef CONFIG_DUAL_F1E_PHY
418    ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
419        AG7100_MAC_CFG1_TX_EN|AG7100_MAC_CFG1_RX_FCTL));
420#else
421         ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
422        AG7100_MAC_CFG1_TX_EN|AG7100_MAC_CFG1_RX_FCTL|AG7100_MAC_CFG1_TX_FCTL));
423#endif
424    }
425    else {
426         ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
427        AG7100_MAC_CFG1_TX_EN|AG7100_MAC_CFG1_RX_FCTL));
428   }
429#else
430   if(mac->mac_unit) {
431    ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
432        AG7100_MAC_CFG1_TX_EN|AG7100_MAC_CFG1_RX_FCTL));
433    }
434    else {
435         ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
436        AG7100_MAC_CFG1_TX_EN |AG7100_MAC_CFG1_RX_FCTL|AG7100_MAC_CFG1_TX_FCTL));
437   }
438#endif
439#else
440        ag7100_reg_wr(mac, AG7100_MAC_CFG1, (AG7100_MAC_CFG1_RX_EN |
441        AG7100_MAC_CFG1_TX_EN));
442#endif
443    ag7100_reg_rmw_set(mac, AG7100_MAC_CFG2, (AG7100_MAC_CFG2_PAD_CRC_EN |
444        AG7100_MAC_CFG2_LEN_CHECK));
445    ag7100_reg_wr(mac, AG71XX_REG_MAC_MFL, AG71XX_TX_MTU_LEN);
446
447    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_0, FIFO_CFG0_INIT);
448    /*
449    * set the mii if type - NB reg not in the gigE space
450    */
451    ar7100_reg_wr(mii_reg(mac), mii_if(mac));
452    ag7100_reg_wr(mac, AG7100_MAC_MII_MGMT_CFG, AG7100_MGMT_CFG_CLK_DIV_20);
453
454#ifdef CONFIG_AR7100_EMULATION
455    ag7100_reg_rmw_set(mac, AG7100_MAC_FIFO_CFG_4, 0x3ffff);
456    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_1, 0xfff0000);
457    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_2, 0x1fff);
458#else
459    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_1, 0xfff0000);
460    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_2, 0x1fff);
461    /*
462    * Weed out junk frames (CRC errored, short collision'ed frames etc.)
463    */
464    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_4, FIFO_CFG4_INIT);
465    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_5, FIFO_CFG5_INIT);
466#endif
467
468    t0  =  &tx->ring_desc[0];
469    r0  =  &rx->ring_desc[0];
470
471    ag7100_reg_wr(mac, AG7100_DMA_TX_DESC, ag7100_desc_dma_addr(tx, t0));
472    ag7100_reg_wr(mac, AG7100_DMA_RX_DESC, ag7100_desc_dma_addr(rx, r0));
473
474    printk(MODULE_NAME ": cfg1 %#x cfg2 %#x\n", ag7100_reg_rd(mac, AG7100_MAC_CFG1),
475        ag7100_reg_rd(mac, AG7100_MAC_CFG2));
476}
477
478static void
479ag7100_hw_stop(ag7100_mac_t *mac)
480{
481    ag7100_rx_stop(mac);
482    ag7100_tx_stop(mac);
483    ag7100_int_disable(mac);
484    /*
485    * put everything into reset.
486    */
487#ifdef CONFIG_DUAL_F1E_PHY
488        if(mac->mac_unit == 1)
489#endif
490        ag7100_reg_rmw_set(mac, AG7100_MAC_CFG1, AG7100_MAC_CFG1_SOFT_RST);
491}
492
493/*
494 * program the usb pll (misnomer) to genrate appropriate clock
495 * Write 2 into control field
496 * Write pll value
497 * Write 3 into control field
498 * Write 0 into control field
499 */
500#ifdef CONFIG_AR9100
501#define ag7100_pll_shift(_mac)      (((_mac)->mac_unit) ? 22: 20)
502#define ag7100_pll_offset(_mac)     \
503    (((_mac)->mac_unit) ? AR9100_ETH_INT1_CLK : \
504                          AR9100_ETH_INT0_CLK)
505#else
506#define ag7100_pll_shift(_mac)      (((_mac)->mac_unit) ? 19: 17)
507#define ag7100_pll_offset(_mac)     \
508    (((_mac)->mac_unit) ? AR7100_USB_PLL_GE1_OFFSET : \
509                          AR7100_USB_PLL_GE0_OFFSET)
510#endif
511static void
512ag7100_set_pll(ag7100_mac_t *mac, unsigned int pll)
513{
514#ifdef CONFIG_AR9100
515#define ETH_PLL_CONFIG AR9100_ETH_PLL_CONFIG
516#else
517#define ETH_PLL_CONFIG AR7100_USB_PLL_CONFIG
518#endif
519    uint32_t shift, reg, val;
520
521    shift = ag7100_pll_shift(mac);
522    reg   = ag7100_pll_offset(mac);
523
524    val  = ar7100_reg_rd(ETH_PLL_CONFIG);
525    val &= ~(3 << shift);
526    val |=  (2 << shift);
527    ar7100_reg_wr(ETH_PLL_CONFIG, val);
528    udelay(100);
529
530    ar7100_reg_wr(reg, pll);
531
532    val |=  (3 << shift);
533    ar7100_reg_wr(ETH_PLL_CONFIG, val);
534    udelay(100);
535
536    val &= ~(3 << shift);
537    ar7100_reg_wr(ETH_PLL_CONFIG, val);
538    udelay(100);
539
540    printk(MODULE_NAME ": pll reg %#x: %#x  ", reg, ar7100_reg_rd(reg));
541}
542
543#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
544
545
546/*
547 * Flush from tail till the head and free all the socket buffers even if owned by DMA
548 * before we change the size of the ring buffer to avoid memory leaks and reset the ring buffer.
549 *
550 * WAR for Bug: 32681
551 */
552
553void
554ag7100_tx_flush(ag7100_mac_t *mac)
555{
556    ag7100_ring_t   *r     = &mac->mac_txring;
557    int              head  = r->ring_nelem , tail = 0, flushed = 0, i;
558    ag7100_desc_t   *ds;
559    ag7100_buffer_t *bf;
560    uint32_t    flags;
561
562
563    ar7100_flush_ge(mac->mac_unit);
564
565    while(flushed != head)
566    {
567        ds   = &r->ring_desc[tail];
568
569        bf      = &r->ring_buffer[tail];
570        if(bf->buf_pkt) {
571            for(i = 0; i < bf->buf_nds; i++)
572            {
573                ag7100_intr_ack_tx(mac);
574                ag7100_ring_incr(tail);
575            }
576       
577            ag7100_buffer_free(bf->buf_pkt);
578            bf->buf_pkt = NULL;
579        }
580        else
581            ag7100_ring_incr(tail);
582
583        ag7100_tx_own(ds);
584        flushed ++;
585    }
586    r->ring_head = r->ring_tail = 0;
587
588    return;
589}
590
591/*
592 * Work around to recover from Tx failure when connected to 10BASET.
593 * Bug: 32681.
594 *
595 * After AutoNeg to 10Mbps Half Duplex, under some un-identified circumstances
596 * during the init sequence, the MAC is in some illegal state
597 * that stops the TX and hence no TXCTL to the PHY.
598 * On Tx Timeout from the software, the reset sequence is done again which recovers the
599 * MAC and Tx goes through without any problem.
600 * Instead of waiting for the application to transmit and recover, we transmit
601 * 40 dummy Tx pkts on negogiating as 10BASET.
602 * Reduce the number of TX buffers from 40 to 5 so that in case of TX failures we do
603 * a immediate reset and retrasmit again till we successfully transmit all of them.
604 */
605
606void
607howl_10baset_war(ag7100_mac_t *mac)
608{
609
610    struct sk_buff *dummy_pkt;
611    struct net_device *dev = mac->mac_dev;
612    ag7100_desc_t *ds;
613    ag7100_ring_t *r;
614    int i=6;
615   
616    /*
617     * Create dummy packet
618     */
619    dummy_pkt = dev_alloc_skb(64);
620    skb_put(dummy_pkt, 60);
621    atomic_dec(&dummy_pkt->users);
622    while(--i >= 0) {
623        dummy_pkt->data[i] = 0xff;
624    }
625    ag7100_get_default_macaddr(mac,(dummy_pkt->data + 6));
626    dummy_pkt->dev = dev;
627    i = 40;
628
629   /*
630    *  Reduce the no of TX buffers to five from the actual number
631    *  of allocated buffers and link the fifth descriptor to first.
632    *  WAR for Bug:32681 to cause early Tx Timeout in 10BASET.
633    */
634    ag7100_tx_flush(mac);
635    ds = mac->mac_txring.ring_desc;
636    r = &mac->mac_txring;
637    r->ring_nelem = 5;
638    ds[r->ring_nelem - 1].next_desc = ag7100_desc_dma_addr(r, &ds[0]);
639    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_3, 0x300020);
640
641    mac->speed_10t = 1;
642    while(i-- && mac->speed_10t) {
643        netif_carrier_on(dev);
644
645        mdelay(100);
646        ag7100_hard_start(dummy_pkt,dev);
647
648        netif_carrier_off(dev);
649    }
650    return ;
651}
652#endif
653       
654/*
655 * Several fields need to be programmed based on what the PHY negotiated
656 * Ideally we should quiesce everything before touching the pll, but:
657 * 1. If its a linkup/linkdown, we dont care about quiescing the traffic.
658 * 2. If its a single gigE PHY, this can only happen on lup/ldown.
659 * 3. If its a 100Mpbs switch, the link will always remain at 100 (or nothing)
660 * 4. If its a gigE switch then the speed should always be set at 1000Mpbs,
661 *    and the switch should provide buffering for slower devices.
662 *
663 * XXX Only gigE PLL can be changed as a parameter for now. 100/10 is hardcoded.
664 * XXX Need defines for them -
665 * XXX FIFO settings based on the mode
666 */
667#ifdef CONFIG_ATHRS16_PHY
668static int is_setup_done = 0;
669#endif
670static void
671ag7100_set_mac_from_link(ag7100_mac_t *mac, ag7100_phy_speed_t speed, int fdx)
672{
673#ifdef CONFIG_ATHRS26_PHY
674    int change_flag = 0;
675
676    if(mac->mac_speed !=  speed)
677        change_flag = 1;
678
679    if(change_flag)
680    {
681        athrs26_phy_off(mac);
682        athrs26_mac_speed_set(mac, speed);
683    }
684#endif
685#ifdef CONFIG_ATHRS16_PHY
686    if(!is_setup_done &&
687#ifndef CONFIG_PORT0_AS_SWITCH
688        mac->mac_unit == 0 &&
689#else
690        mac->mac_unit == 1 &&
691#endif
692        (mac->mac_speed !=  speed || mac->mac_fdx !=  fdx))
693    {   
694       /* workaround for PHY4 port thru RGMII */
695       phy_mode_setup();
696       is_setup_done = 1;
697    }
698#endif
699   /*
700    *  Flush TX descriptors , reset the MAC and relink all descriptors.
701    *  WAR for Bug:32681
702    */
703
704#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
705    if(mac->speed_10t && (speed != AG7100_PHY_SPEED_10T)) {
706        mac->speed_10t = 0;
707        ag7100_tx_flush(mac);
708        mdelay(500);
709        ag7100_dma_reset(mac);
710    }
711#endif
712
713    mac->mac_speed =  speed;
714    mac->mac_fdx   =  fdx;
715
716    ag7100_set_mii_ctrl_speed(mac, speed);
717    ag7100_set_mac_duplex(mac, fdx);
718    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_3, fifo_3);
719#ifndef CONFIG_AR9100
720    ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_5, fifo_5);
721#endif
722
723    switch (speed)
724    {
725    case AG7100_PHY_SPEED_1000T:
726#ifdef CONFIG_AR9100
727        ag7100_reg_wr(mac, AG7100_MAC_FIFO_CFG_3, 0x780fff);
728#endif
729        ag7100_set_mac_if(mac, 1);
730#ifdef CONFIG_AR9100
731#ifdef  CONFIG_BUFFALO
732        ag7100_set_pll(mac, e1000_pll[mac->mac_unit ? 1 : 0]);
733#else
734        if (mac->mac_unit == 0)
735        { /* eth0 */
736            ag7100_set_pll(mac, gige_pll);
737        }
738        else
739        {
740#ifdef CONFIG_DUAL_F1E_PHY
741            ag7100_set_pll(mac, gige_pll);
742#else
743            ag7100_set_pll(mac, SW_PLL);
744#endif
745        }
746#endif
747#else
748
749#ifdef  CONFIG_BUFFALO
750        ag7100_set_pll(mac, e1000_pll[mac->mac_unit ? 1 : 0]);
751#else
752        ag7100_set_pll(mac, gige_pll);
753#endif
754#endif
755        ag7100_reg_rmw_set(mac, AG7100_MAC_FIFO_CFG_5, (1 << 19));
756        break;
757
758    case AG7100_PHY_SPEED_100TX:
759        ag7100_set_mac_if(mac, 0);
760        ag7100_set_mac_speed(mac, 1);
761#ifndef CONFIG_AR7100_EMULATION
762#ifdef CONFIG_AR9100
763#ifdef  CONFIG_BUFFALO
764        ag7100_set_pll(mac, e100_pll[mac->mac_unit ? 1 : 0]);
765#else
766        if (mac->mac_unit == 0)
767        { /* eth0 */
768            ag7100_set_pll(mac, 0x13000a44);
769        }
770        else
771        {
772#ifdef CONFIG_DUAL_F1E_PHY
773            ag7100_set_pll(mac, 0x13000a44);
774#else
775            ag7100_set_pll(mac, SW_PLL);
776#endif
777        }
778#endif
779#else
780#ifdef  CONFIG_BUFFALO
781        ag7100_set_pll(mac, e100_pll[mac->mac_unit ? 1 : 0]);
782#else
783#ifdef CONFIG_CAMEO_REALTEK_PHY
784        ag7100_set_pll(mac, 0x0001099);
785#else
786        ag7100_set_pll(mac, 0x0001099);
787#endif
788#endif
789#endif
790#endif
791        ag7100_reg_rmw_clear(mac, AG7100_MAC_FIFO_CFG_5, (1 << 19));
792        break;
793
794    case AG7100_PHY_SPEED_10T:
795        ag7100_set_mac_if(mac, 0);
796        ag7100_set_mac_speed(mac, 0);
797#ifdef CONFIG_AR9100
798#ifdef  CONFIG_BUFFALO
799        ag7100_set_pll(mac, e10_pll[mac->mac_unit ? 1 : 0]);
800#else
801        if (mac->mac_unit == 0)
802        { /* eth0 */
803            ag7100_set_pll(mac, 0x00441099);
804        }
805        else
806        {
807#ifdef CONFIG_DUAL_F1E_PHY
808            ag7100_set_pll(mac, 0x00441099);
809#else
810            ag7100_set_pll(mac, SW_PLL);
811#endif
812        }
813#endif
814#else
815#ifdef  CONFIG_BUFFALO
816        ag7100_set_pll(mac, e10_pll[mac->mac_unit ? 1 : 0]);
817#else
818#ifdef CONFIG_CAMEO_REALTEK_PHY
819        ag7100_set_pll(mac, 0x00991099);
820#else
821        ag7100_set_pll(mac, 0x00991099);
822#endif
823#endif
824#endif
825#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
826        if((speed == AG7100_PHY_SPEED_10T) && !mac->speed_10t) {
827           howl_10baset_war(mac);
828        }
829#endif
830        ag7100_reg_rmw_clear(mac, AG7100_MAC_FIFO_CFG_5, (1 << 19));
831        break;
832
833    default:
834        assert(0);
835    }
836
837#ifdef CONFIG_ATHRS26_PHY
838    if(change_flag)
839        athrs26_phy_on(mac);
840#endif
841
842    printk(MODULE_NAME ": CPU PhaseLockLoop      : %#x\n", *(volatile int *) 0xb8050000);  //set CPU PhaseLockLoop configuration
843    printk(MODULE_NAME ": Secondary PhaseLockLoop: %#x\n", *(volatile int *) 0xb8050004);  //set secondary PhaseLockLoop configuration
844    printk(MODULE_NAME ": Ethernet Internal Clock Control: %#x\n", *(volatile int *) 0xb8050010);  //set Ethernet Internal Clock Control
845    printk(MODULE_NAME ": mii: %#x\n", ar7100_reg_rd(mii_reg(mac)));
846    printk(MODULE_NAME ": cfg1: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_CFG1));
847    printk(MODULE_NAME ": cfg2: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_CFG2));       
848    printk(MODULE_NAME ": fcfg_0: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_0));
849    printk(MODULE_NAME ": fcfg_1: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_1));
850    printk(MODULE_NAME ": fcfg_2: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_2));
851    printk(MODULE_NAME ": fcfg_3: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_3));
852    printk(MODULE_NAME ": fcfg_4: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_4));
853    printk(MODULE_NAME ": fcfg_5: %#x\n", ag7100_reg_rd(mac, AG7100_MAC_FIFO_CFG_5));
854}
855
856static void copy_txdescs(ag7100_mac_t *mac, int start, int end)
857{
858    ag7100_ring_t      *r   = &mac->mac_txring;
859    ag7100_ring_t      *tr   = &mac->mac_txring_cache;
860    ag7100_desc_t      *tds, *fds;
861
862    if (end >= r->ring_nelem) end -= r->ring_nelem;
863    while (start != end)
864    {
865        fds = &r->ring_desc[start];
866        tds = &tr->ring_desc[start];
867        memcpy(tds, fds, 8); /* just the first two words of the desc */
868        ag7100_ring_incr(start);
869    }
870}
871
872static int check_for_dma_hang(ag7100_mac_t *mac) {
873
874    ag7100_ring_t   *r     = &mac->mac_txring;
875    int              head  = r->ring_head, tail = r->ring_tail;
876    ag7100_desc_t   *ds;
877#if 1//DMA tx hang
878    ag7100_buffer_t *bf;
879#endif
880    ag7100_buffer_t *bp;
881
882    ar7100_flush_ge(mac->mac_unit);
883
884    while (tail != head)
885    {
886        ds   = &r->ring_desc[tail];
887        bp   =  &r->ring_buffer[tail];
888
889        if(ag7100_tx_owned_by_dma(ds)) {
890                        if ((jiffies - bp->trans_start) > (1 * HZ)) {
891                printk(MODULE_NAME ": Tx Dma status : %s\n",
892                ag7100_tx_stopped(mac) ? "inactive" : "active");
893#if 0
894                printk(MODULE_NAME ": timestamp:%u jiffies:%u diff:%d\n",bp->trans_start,jiffies,
895                             (jiffies - bp->trans_start));
896#endif
897               ag7100_dma_reset(mac);
898                           return 1;
899           }
900        }
901        ag7100_ring_incr(tail);
902    }
903    return 0;
904}
905
906
907/*
908 * phy link state management
909 */
910static int
911ag7100_check_link(ag7100_mac_t *mac)
912{
913    struct net_device  *dev     = mac->mac_dev;
914    int                 carrier = netif_carrier_ok(dev), fdx, phy_up=1;
915    ag7100_phy_speed_t  speed;
916    int                 rc;
917
918    /* workaround for dma hang, seen on DIR-825 */
919    if(check_for_dma_hang(mac))
920        goto done;
921
922    /* The vitesse switch uses an indirect method to communicate phy status
923    * so it is best to limit the number of calls to what is necessary.
924    * However a single call returns all three pieces of status information.
925    *
926    * This is a trivial change to the other PHYs ergo this change.
927    *
928    */
929   
930    /*
931    ** If this is not connected, let's just jump out
932    */
933   
934    if(mii_if(mac) > 3)
935        goto done;
936
937    rc = ag7100_get_link_status(mac->mac_unit, &phy_up, &fdx, &speed);
938    if (rc < 0)
939        goto done;
940
941    if (!phy_up)
942    {
943        if (carrier)
944        {
945            printk(MODULE_NAME ": unit %d: phy not up carrier %d\n", mac->mac_unit, carrier);
946            netif_carrier_off(dev);
947        }
948        goto done;
949    }
950
951    /*
952    * phy is up. Either nothing changed or phy setttings changed while we
953    * were sleeping.
954    */
955
956    if ((fdx < 0) || (speed < 0))
957    {
958        printk(MODULE_NAME ": phy not connected?\n");
959        return 0;
960    }
961
962    if (carrier && (speed == mac->mac_speed) && (fdx == mac->mac_fdx))
963        goto done;
964
965    printk(MODULE_NAME ": unit %d phy is up...", mac->mac_unit);
966    printk("%s %s %s\n", mii_str[mac->mac_unit][mii_if(mac)],
967        spd_str[speed], dup_str[fdx]);
968
969    ag7100_set_mac_from_link(mac, speed, fdx);
970
971    printk(MODULE_NAME ": done cfg2 %#x ifctl %#x miictrl %#x \n",
972        ag7100_reg_rd(mac, AG7100_MAC_CFG2),
973        ag7100_reg_rd(mac, AG7100_MAC_IFCTL),
974        ar7100_reg_rd(mii_reg(mac)));
975    /*
976    * in business
977    */
978    netif_carrier_on(dev);
979
980done:
981#if defined(CONFIG_ATHRS26_PHY) || defined(CONFIG_ATHRS16_PHY)   
982    if(!phy_up)   
983        mod_timer(&mac->mac_phy_timer, jiffies + AG7100_PHY_POLL_SECONDS*HZ/4);
984    else
985#endif       
986    mod_timer(&mac->mac_phy_timer, jiffies + AG7100_PHY_POLL_SECONDS*HZ);
987
988/* "Hydra WAN + RealTek PHY with a specific NetGear Hub" Rx hang workaround */
989#if 1//DMA mac hang
990     {
991        unsigned int perf_cnt = ag7100_get_rx_count(mac);
992        if (perf_cnt == 0xffffffff) {
993            /* we have saturated the counter. let it overflow to 0 */
994            if (mac->mac_unit == 0) {
995                ar7100_reg_wr(AR7100_PERF0_COUNTER, 0);
996            }
997            else {
998                ar7100_reg_wr(AR7100_PERF1_COUNTER, 0);
999            }
1000        }
1001                int status;
1002                status = ag7100_reg_rd(mac, AG7100_DMA_RX_STATUS);
1003        /* perf_cnt increments on every rx pkt including runts.
1004         * so, the rx hang occurred when perf_cnt incremented, but
1005         * valid rx pkts didn't get incremented. this could result
1006         * in a false positive but the likelihood that over a 2sec
1007         * period all pkts received were runts appears to me
1008         * to be very low -JK.
1009         */
1010       
1011                if ((perf_cnt > rx_hang_detect_pkt_cnt_all[mac->mac_unit]) &&
1012            (mac->net_rx_packets == rx_hang_detect_pkt_cnt_valid[mac->mac_unit]) &&
1013            (!(status & AG7100_RX_STATUS_PKT_RCVD)) &&
1014            (!((status & AG7100_RX_STATUS_PKTCNT_MASK )>>16))) {
1015                rx_hang_detected[mac->mac_unit] += 1;
1016                if ( mac->mac_unit == 1 )           
1017                printk(MODULE_NAME ": WAN Rx Hang Detected %d times!\n",rx_hang_detected[mac->mac_unit]);
1018                 else
1019                                printk(MODULE_NAME ": LAN Rx Hang Detected %d times!\n",rx_hang_detected[mac->mac_unit]);
1020            rx_hang_detect_pkt_cnt_all[mac->mac_unit] = perf_cnt;
1021                rx_hang_detect_pkt_cnt_valid[mac->mac_unit] = mac->net_rx_packets;
1022
1023                if (rx_hang_detected[mac->mac_unit] >= 2)
1024                        ag7100_dma_reset(mac);
1025        }
1026        else {
1027            rx_hang_detect_pkt_cnt_all[mac->mac_unit] = perf_cnt;
1028            rx_hang_detect_pkt_cnt_valid[mac->mac_unit] = mac->net_rx_packets;
1029                rx_hang_detected[mac->mac_unit] = 0;
1030        }
1031    }
1032#endif
1033
1034    return 0;
1035}
1036
1037static void
1038ag7100_choose_phy(uint32_t phy_addr)
1039{
1040#ifdef CONFIG_AR7100_EMULATION
1041    if (phy_addr == 0x10)
1042    {
1043        ar7100_reg_rmw_set(AR7100_MII0_CTRL, (1 << 6));
1044    }
1045    else
1046    {
1047        ar7100_reg_rmw_clear(AR7100_MII0_CTRL, (1 << 6));
1048    }
1049#endif
1050}
1051
1052uint16_t
1053ag7100_mii_read(int unit, uint32_t phy_addr, uint8_t reg)
1054{
1055    ag7100_mac_t *mac   = ag7100_unit2mac(0);
1056    uint16_t      addr  = (phy_addr << AG7100_ADDR_SHIFT) | reg, val;
1057    volatile int           rddata;
1058    uint16_t      ii = 0x1000;
1059
1060    ag7100_choose_phy(phy_addr);
1061
1062    ag7100_reg_wr(mac, AG7100_MII_MGMT_CMD, 0x0);
1063    ag7100_reg_wr(mac, AG7100_MII_MGMT_ADDRESS, addr);
1064    ag7100_reg_wr(mac, AG7100_MII_MGMT_CMD, AG7100_MGMT_CMD_READ);
1065
1066    do
1067    {
1068        udelay(5);
1069        rddata = ag7100_reg_rd(mac, AG7100_MII_MGMT_IND) & 0x1;
1070    }while(rddata && --ii);
1071
1072    val = ag7100_reg_rd(mac, AG7100_MII_MGMT_STATUS);
1073    ag7100_reg_wr(mac, AG7100_MII_MGMT_CMD, 0x0);
1074
1075    return val;
1076}
1077
1078void
1079ag7100_mii_write(int unit, uint32_t phy_addr, uint8_t reg, uint16_t data)
1080{
1081    ag7100_mac_t *mac   = ag7100_unit2mac(0);
1082    uint16_t      addr  = (phy_addr << AG7100_ADDR_SHIFT) | reg;
1083    volatile int rddata;
1084    uint16_t      ii = 0x1000;
1085
1086    ag7100_choose_phy(phy_addr);
1087
1088    ag7100_reg_wr(mac, AG7100_MII_MGMT_ADDRESS, addr);
1089    ag7100_reg_wr(mac, AG7100_MII_MGMT_CTRL, data);
1090
1091    do
1092    {
1093        rddata = ag7100_reg_rd(mac, AG7100_MII_MGMT_IND) & 0x1;
1094    }while(rddata && --ii);
1095}
1096
1097/*
1098 * Tx operation:
1099 * We do lazy reaping - only when the ring is "thresh" full. If the ring is
1100 * full and the hardware is not even done with the first pkt we q'd, we turn
1101 * on the tx interrupt, stop all q's and wait for h/w to
1102 * tell us when its done with a "few" pkts, and then turn the Qs on again.
1103 *
1104 * Locking:
1105 * The interrupt only touches the ring when Q's stopped  => Tx is lockless,
1106 * except when handling ring full.
1107 *
1108 * Desc Flushing: Flushing needs to be handled at various levels, broadly:
1109 * - The DDr FIFOs for desc reads.
1110 * - WB's for desc writes.
1111 */
1112static void
1113ag7100_handle_tx_full(ag7100_mac_t *mac)
1114{
1115    u32         flags;
1116#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
1117    if(!mac->speed_10t)
1118#endif
1119    assert(!netif_queue_stopped(mac->mac_dev));
1120
1121    mac->mac_net_stats.tx_fifo_errors ++;
1122
1123    netif_stop_queue(mac->mac_dev);
1124
1125    spin_lock_irqsave(&mac->mac_lock, flags);
1126    ag7100_intr_enable_tx(mac);
1127    spin_unlock_irqrestore(&mac->mac_lock, flags);
1128}
1129
1130/* ******************************
1131 *
1132 * Code under test - do not use
1133 *
1134 * ******************************
1135 */
1136
1137static ag7100_desc_t *
1138ag7100_get_tx_ds(ag7100_mac_t *mac, int *len, unsigned char **start)
1139{
1140    ag7100_desc_t      *ds;
1141    int                len_this_ds;
1142    ag7100_ring_t      *r   = &mac->mac_txring;
1143    ag7100_buffer_t    *bp;
1144
1145    /* force extra pkt if remainder less than 4 bytes */
1146    if (*len > tx_len_per_ds)
1147        if (*len <= (tx_len_per_ds + 4))
1148            len_this_ds = tx_len_per_ds - 4;
1149        else
1150            len_this_ds = tx_len_per_ds;
1151    else
1152        len_this_ds    = *len;
1153
1154    ds = &r->ring_desc[r->ring_head];
1155
1156    ag7100_trc_new(ds,"ds addr");
1157    ag7100_trc_new(ds,"ds len");
1158    if(ag7100_tx_owned_by_dma(ds))
1159        ag7100_dma_reset(mac);
1160
1161    ds->pkt_size       = len_this_ds;
1162    ds->pkt_start_addr = virt_to_phys(*start);
1163    ds->more           = 1;
1164
1165    *len   -= len_this_ds;
1166    *start += len_this_ds;
1167
1168     bp = &r->ring_buffer[r->ring_head];
1169     bp->trans_start = jiffies; /*Time stamp each packet */
1170
1171    ag7100_ring_incr(r->ring_head);
1172
1173    return ds;
1174}
1175
1176#if defined(CONFIG_ATHRS26_PHY)
1177int
1178#else
1179static int
1180#endif
1181ag7100_hard_start(struct sk_buff *skb, struct net_device *dev)
1182{
1183    ag7100_mac_t       *mac = (ag7100_mac_t *)dev->priv;
1184    ag7100_ring_t      *r   = &mac->mac_txring;
1185    ag7100_buffer_t    *bp;
1186    ag7100_desc_t      *ds, *fds;
1187    unsigned char      *start;
1188    int                len;
1189    int                nds_this_pkt;
1190
1191#ifdef VSC73XX_DEBUG
1192    {
1193        static int vsc73xx_dbg;
1194        if (vsc73xx_dbg == 0) {
1195            vsc73xx_get_link_status_dbg();
1196            vsc73xx_dbg = 1;
1197        }
1198        vsc73xx_dbg = (vsc73xx_dbg + 1) % 10;
1199    }
1200#endif
1201
1202#if defined(CONFIG_ATHRS26_PHY) && defined(HEADER_EN)
1203    /* add header to normal frames */
1204    /* check if normal frames */
1205    if ((mac->mac_unit == 0) && (!((skb->cb[0] == 0x7f) && (skb->cb[1] == 0x5d))))
1206    {
1207        skb_push(skb, HEADER_LEN);
1208        skb->data[0] = 0x10; /* broadcast = 0; from_cpu = 0; reserved = 1; port_num = 0 */
1209        skb->data[1] = 0x80; /* reserved = 0b10; priority = 0; type = 0 (normal) */
1210    }
1211
1212#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1213    if(unlikely((skb->len <= 0)
1214        || (skb->len > (dev->mtu + ETH_HLEN + HEADER_LEN + 4))))
1215    { /*vlan tag length = 4*/
1216        printk(MODULE_NAME ": [%d] bad skb, dev->mtu=%d,ETH_HLEN=%d len %d\n", mac->mac_unit, dev->mtu, ETH_HLEN,  skb->len);
1217        goto dropit;
1218    }
1219#else
1220    if(unlikely((skb->len <= 0)
1221        || (skb->len > (dev->mtu + ETH_HLEN + HEADER_LEN))))
1222    {
1223        printk(MODULE_NAME ": [%d] bad skb, dev->mtu=%d,ETH_HLEN=%d len %d\n", mac->mac_unit, dev->mtu, ETH_HLEN,  skb->len);
1224        goto dropit;
1225    }
1226#endif 
1227
1228#else
1229#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1230    if(unlikely((skb->len <= 0) || (skb->len > (dev->mtu + ETH_HLEN + 4))))
1231    {  /*vlan tag length = 4*/
1232        printk(MODULE_NAME ": bad skb, len %d\n", skb->len);
1233        goto dropit;
1234    }
1235#else
1236    if(unlikely((skb->len <= 0) || (skb->len > (dev->mtu + ETH_HLEN))))
1237    {
1238        printk(MODULE_NAME ": bad skb, len %d\n", skb->len);
1239        goto dropit;
1240    }
1241#endif   
1242#endif
1243
1244    if (ag7100_tx_reap_thresh(mac))
1245        ag7100_tx_reap(mac);
1246
1247    ag7100_trc_new(r->ring_head,"hard-stop hd");
1248    ag7100_trc_new(r->ring_tail,"hard-stop tl");
1249
1250    ag7100_trc_new(skb->len,    "len this pkt");
1251    ag7100_trc_new(skb->data,   "ptr 2 pkt");
1252
1253    dma_cache_wback((unsigned long)skb->data, skb->len);
1254
1255    bp          = &r->ring_buffer[r->ring_head];
1256    bp->buf_pkt = skb;
1257    len         = skb->len;
1258    start       = skb->data;
1259
1260    assert(len>4);
1261
1262    nds_this_pkt = 1;
1263    fds = ds = ag7100_get_tx_ds(mac, &len, &start);
1264
1265    while (len>0)
1266    {
1267        ds = ag7100_get_tx_ds(mac, &len, &start);
1268        nds_this_pkt++;
1269        ag7100_tx_give_to_dma(ds);
1270    }
1271
1272    ds->more        = 0;
1273    ag7100_tx_give_to_dma(fds);
1274
1275    bp->buf_lastds  = ds;
1276    bp->buf_nds     = nds_this_pkt;
1277
1278    ag7100_trc_new(ds,"last ds");
1279    ag7100_trc_new(nds_this_pkt,"nmbr ds for this pkt");
1280
1281    wmb();
1282
1283    mac->net_tx_packets ++;
1284    mac->net_tx_bytes += skb->len;
1285
1286    ag7100_trc(ag7100_reg_rd(mac, AG7100_DMA_TX_CTRL),"dma idle");
1287
1288    ag7100_tx_start(mac);
1289
1290    if (unlikely(ag7100_tx_ring_full(mac)))
1291        ag7100_handle_tx_full(mac);
1292
1293    dev->trans_start = jiffies;
1294
1295    return NETDEV_TX_OK;
1296
1297dropit:
1298    printk(MODULE_NAME ": dropping skb %p\n", skb);
1299    kfree_skb(skb);
1300    return NETDEV_TX_OK;
1301}
1302
1303/*
1304 * Interrupt handling:
1305 * - Recv NAPI style (refer to Documentation/networking/NAPI)
1306 *
1307 *   2 Rx interrupts: RX and Overflow (OVF).
1308 *   - If we get RX and/or OVF, schedule a poll. Turn off _both_ interurpts.
1309 *
1310 *   - When our poll's called, we
1311 *     a) Have one or more packets to process and replenish
1312 *     b) The hardware may have stopped because of an OVF.
1313 *
1314 *   - We process and replenish as much as we can. For every rcvd pkt
1315 *     indicated up the stack, the head moves. For every such slot that we
1316 *     replenish with an skb, the tail moves. If head catches up with the tail
1317 *     we're OOM. When all's done, we consider where we're at:
1318 *
1319 *      if no OOM:
1320 *      - if we're out of quota, let the ints be disabled and poll scheduled.
1321 *      - If we've processed everything, enable ints and cancel poll.
1322 *
1323 *      If OOM:
1324 *      - Start a timer. Cancel poll. Ints still disabled.
1325 *        If the hardware's stopped, no point in restarting yet.
1326 *
1327 *      Note that in general, whether we're OOM or not, we still try to
1328 *      indicate everything recvd, up.
1329 *
1330 * Locking:
1331 * The interrupt doesnt touch the ring => Rx is lockless
1332 *
1333 */
1334static irqreturn_t
1335ag7100_intr(int cpl, void *dev_id)
1336{
1337    struct net_device *dev  = (struct net_device *)dev_id;
1338    ag7100_mac_t      *mac  = (ag7100_mac_t *)dev->priv;
1339    int   isr, imr, handled = 0;
1340
1341    isr   = ag7100_get_isr(mac);
1342    imr   = ag7100_reg_rd(mac, AG7100_DMA_INTR_MASK);
1343
1344    ag7100_trc(isr,"isr");
1345    ag7100_trc(imr,"imr");
1346
1347    assert(isr == (isr & imr));
1348
1349    if (likely(isr & (AG7100_INTR_RX | AG7100_INTR_RX_OVF)))
1350    {
1351        handled = 1;
1352#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1353        if (likely(netif_rx_schedule_prep(dev,&mac->mac_napi)))
1354#else
1355        if (likely(netif_rx_schedule_prep(dev)))
1356#endif
1357        {
1358            ag7100_intr_disable_recv(mac);
1359#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1360            __netif_rx_schedule(dev,&mac->mac_napi);
1361#else
1362            __netif_rx_schedule(dev);
1363#endif
1364        }
1365        else
1366        {
1367            printk(MODULE_NAME ": driver bug! interrupt while in poll\n");
1368            assert(0);
1369            ag7100_intr_disable_recv(mac);
1370        }
1371        /*ag7100_recv_packets(dev, mac, 200, &budget);*/
1372    }
1373    if (likely(isr & AG7100_INTR_TX))
1374    {
1375        handled = 1;
1376        ag7100_intr_ack_tx(mac);
1377        ag7100_tx_reap(mac);
1378    }
1379    if (unlikely(isr & AG7100_INTR_RX_BUS_ERROR))
1380    {
1381        assert(0);
1382        handled = 1;
1383        ag7100_intr_ack_rxbe(mac);
1384    }
1385    if (unlikely(isr & AG7100_INTR_TX_BUS_ERROR))
1386    {
1387        assert(0);
1388        handled = 1;
1389        ag7100_intr_ack_txbe(mac);
1390    }
1391
1392    if (!handled)
1393    {
1394        assert(0);
1395        printk(MODULE_NAME ": unhandled intr isr %#x\n", isr);
1396    }
1397
1398    return IRQ_HANDLED;
1399}
1400
1401 /*
1402  * Rx and Tx DMA hangs and goes to an invalid state in HOWL boards
1403  * when the link partner is forced to 10/100 Mode.By resetting the MAC
1404  * we are able to recover from this state.This is a software  WAR and
1405  * will be removed once we have a hardware fix.
1406  */
1407
1408#if 1//def CONFIG_AR9100
1409
1410void ag7100_dma_reset(ag7100_mac_t *mac)
1411{
1412    uint32_t mask;
1413
1414    if(mac->mac_unit)
1415        mask = AR7100_RESET_GE1_MAC;
1416    else
1417        mask = AR7100_RESET_GE0_MAC;
1418
1419    ar7100_reg_rmw_set(AR7100_RESET, mask);
1420    mdelay(100);
1421    ar7100_reg_rmw_clear(AR7100_RESET, mask);
1422    mdelay(100);
1423
1424    ag7100_intr_disable_recv(mac);
1425#if defined(CONFIG_AR9100) && defined(CONFIG_AG7100_GE1_RMII)
1426    mac->speed_10t = 0;
1427#endif
1428    schedule_work(&mac->mac_tx_timeout);
1429}
1430
1431#endif
1432
1433static int
1434#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1435ag7100_poll(struct napi_struct *napi, int budget)
1436#else
1437ag7100_poll(struct net_device *dev, int *budget)
1438#endif
1439{
1440#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1441        ag7100_mac_t *mac = container_of(napi, ag7100_mac_t, mac_napi);
1442        struct net_device *dev = mac->mac_dev;
1443        int work_done,      max_work  = budget, status = 0;
1444#else
1445        ag7100_mac_t       *mac       = (ag7100_mac_t *)dev->priv;
1446        int work_done,      max_work  = min(*budget, dev->quota), status = 0;
1447#endif
1448    ag7100_rx_status_t  ret;
1449    u32                 flags;
1450    spin_lock_irqsave(&mac->mac_lock, flags);
1451
1452    ret = ag7100_recv_packets(dev, mac, max_work, &work_done);
1453
1454
1455#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1456        if (work_done < budget)
1457                {
1458                netif_rx_complete(dev, napi);
1459                ag7100_intr_enable_recv(mac);
1460                }
1461#else
1462    dev->quota  -= work_done;
1463    *budget     -= work_done;
1464    if (likely(ret == AG7100_RX_STATUS_DONE))
1465    {
1466    netif_rx_complete(dev);
1467    }
1468#endif
1469    if(ret == AG7100_RX_DMA_HANG)
1470    {
1471        status = 0;
1472        ag7100_dma_reset(mac);
1473    }
1474
1475    if (likely(ret == AG7100_RX_STATUS_NOT_DONE))
1476    {
1477        /*
1478        * We have work left
1479        */
1480        status = 1;
1481    }
1482    else if (ret == AG7100_RX_STATUS_OOM)
1483    {
1484        printk(MODULE_NAME ": oom..?\n");
1485        /*
1486        * Start timer, stop polling, but do not enable rx interrupts.
1487        */
1488        mod_timer(&mac->mac_oom_timer, jiffies+1);
1489    }
1490    spin_unlock_irqrestore(&mac->mac_lock, flags);
1491
1492#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
1493        return work_done;
1494#else
1495        return status;
1496#endif
1497}
1498
1499int
1500ag7100_recv_packets(struct net_device *dev, ag7100_mac_t *mac,
1501    int quota, int *work_done)
1502{
1503    ag7100_ring_t       *r     = &mac->mac_rxring;
1504    ag7100_desc_t       *ds;
1505    ag7100_buffer_t     *bp;
1506    struct sk_buff      *skb;
1507    ag7100_rx_status_t   ret   = AG7100_RX_STATUS_DONE;
1508    int head = r->ring_head, len, status, iquota = quota, more_pkts, rep;
1509    int i;
1510    ag7100_trc(iquota,"iquota");
1511#if !defined(CONFIG_AR9100)
1512    status = ag7100_reg_rd(mac, AG7100_DMA_RX_STATUS);
1513#endif
1514
1515process_pkts:
1516    ag7100_trc(status,"status");
1517#if !defined(CONFIG_AR9100)
1518    /*
1519    * Under stress, the following assertion fails.
1520    *
1521    * On investigation, the following `appears' to happen.
1522    *   - pkts received
1523    *   - rx intr
1524    *   - poll invoked
1525    *   - process received pkts
1526    *   - replenish buffers
1527    *   - pkts received
1528    *
1529    *   - NO RX INTR & STATUS REG NOT UPDATED <---
1530    *
1531    *   - s/w doesn't process pkts since no intr
1532    *   - eventually, no more buffers for h/w to put
1533    *     future rx pkts
1534    *   - RX overflow intr
1535    *   - poll invoked
1536    *   - since status reg is not getting updated
1537    *     following assertion fails..
1538    *
1539    * Ignore the status register.  Regardless of this
1540    * being a rx or rx overflow, we have packets to process.
1541    * So, we go ahead and receive the packets..
1542    */
1543    assert((status & AG7100_RX_STATUS_PKT_RCVD));
1544    assert((status >> 16));
1545#endif
1546    /*
1547    * Flush the DDR FIFOs for our gmac
1548    */
1549    ar7100_flush_ge(mac->mac_unit);
1550
1551    assert(quota > 0); /* WCL */
1552
1553    while(quota)
1554    {
1555        ds    = &r->ring_desc[head];
1556
1557        ag7100_trc(head,"hd");
1558        ag7100_trc(ds,  "ds");
1559
1560        if (ag7100_rx_owned_by_dma(ds))
1561        {
1562            if(quota == iquota)
1563            {
1564                *work_done = quota = 0;
1565                return AG7100_RX_DMA_HANG;
1566            }
1567            break;
1568        }
1569        ag7100_intr_ack_rx(mac);
1570
1571        bp                  = &r->ring_buffer[head];
1572        len                 = ds->pkt_size;
1573        skb                 = bp->buf_pkt;
1574        assert(skb);
1575        skb_put(skb, len - ETHERNET_FCS_SIZE);
1576
1577#if defined(CONFIG_ATHRS26_PHY) && defined(HEADER_EN)
1578        uint8_t type;
1579        uint16_t def_vid;
1580
1581        if(mac->mac_unit == 0)
1582        {
1583            type = (skb->data[1]) & 0xf;
1584
1585            if (type == NORMAL_PACKET)
1586            {
1587#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)             
1588                /*cpu egress tagged*/
1589                if (is_cpu_egress_tagged())
1590                {
1591                    if ((skb->data[12 + HEADER_LEN] != 0x81) || (skb->data[13 + HEADER_LEN] != 0x00))
1592                    {
1593                        def_vid = athrs26_defvid_get(skb->data[0] & 0xf);
1594                        skb_push(skb, 2); /* vid lenghth - header length */
1595                        memmove(&skb->data[0], &skb->data[4], 12); /*remove header and add vlan tag*/
1596
1597                        skb->data[12] = 0x81;
1598                        skb->data[13] = 0x00;
1599                        skb->data[14] = (def_vid >> 8) & 0xf;
1600                        skb->data[15] = def_vid & 0xff;
1601                    }
1602                }
1603                else
1604#endif               
1605                    skb_pull(skb, 2); /* remove attansic header */
1606
1607                mac->net_rx_packets ++;
1608                mac->net_rx_bytes += skb->len;
1609#if 0//def CONFIG_CAMEO_REALTEK_PHY
1610                /* align the data to the ip header - should be faster than copying the entire packet */
1611                for (i = len - (len % 4); i >= 0; i -= 4) {
1612                        put_unaligned(*((u32 *) (skb->data + i)), (u32 *) (skb->data + i + 2));
1613                }
1614                skb->data += 2;
1615                skb->tail += 2;
1616#endif
1617
1618                /*
1619                * also pulls the ether header
1620                */
1621                skb->protocol       = eth_type_trans(skb, dev);
1622                skb->dev            = dev;
1623                bp->buf_pkt         = NULL;
1624                dev->last_rx        = jiffies;
1625                quota--;
1626
1627                netif_receive_skb(skb);
1628            }
1629            else
1630            {
1631                mac->net_rx_packets ++;
1632                mac->net_rx_bytes += skb->len;
1633                bp->buf_pkt         = NULL;
1634                dev->last_rx        = jiffies;
1635                quota--;
1636
1637                if (type == READ_WRITE_REG_ACK)
1638                {
1639                    header_receive_skb(skb);
1640                }
1641                else
1642                {
1643                    kfree_skb(skb);
1644                }
1645            }
1646        }else
1647        {
1648            mac->net_rx_packets ++;
1649            mac->net_rx_bytes += skb->len;
1650            /*
1651            * also pulls the ether header
1652            */
1653            skb->protocol       = eth_type_trans(skb, dev);
1654            skb->dev            = dev;
1655            bp->buf_pkt         = NULL;
1656            dev->last_rx        = jiffies;
1657            quota--;
1658
1659            netif_receive_skb(skb);
1660        }
1661
1662#else
1663        mac->net_rx_packets ++;
1664        mac->net_rx_bytes += skb->len;
1665        /*
1666        * also pulls the ether header
1667        */
1668        skb->protocol       = eth_type_trans(skb, dev);
1669        skb->dev            = dev;
1670        bp->buf_pkt         = NULL;
1671        dev->last_rx        = jiffies;
1672
1673        quota--;
1674
1675        netif_receive_skb(skb);
1676#endif
1677
1678        ag7100_ring_incr(head);
1679    }
1680
1681    if(quota == iquota)
1682    {
1683        *work_done = quota = 0;
1684        return AG7100_RX_DMA_HANG;
1685    }
1686
1687    r->ring_head   =  head;
1688
1689    rep = ag7100_rx_replenish(mac);
1690    if(rep < 0)
1691    {
1692        *work_done =0 ;
1693        return AG7100_RX_DMA_HANG;
1694    }
1695    /*
1696    * let's see what changed while we were slogging.
1697    * ack Rx in the loop above is no flush version. It will get flushed now.
1698    */
1699    status       =  ag7100_reg_rd(mac, AG7100_DMA_RX_STATUS);
1700    more_pkts    =  (status & AG7100_RX_STATUS_PKT_RCVD);
1701
1702    ag7100_trc(more_pkts,"more_pkts");
1703
1704    if (!more_pkts) goto done;
1705    /*
1706    * more pkts arrived; if we have quota left, get rolling again
1707    */
1708    if (quota)      goto process_pkts;
1709    /*
1710    * out of quota
1711    */
1712    ret = AG7100_RX_STATUS_NOT_DONE;
1713
1714done:
1715    *work_done   = (iquota - quota);
1716
1717    if (unlikely(ag7100_rx_ring_full(mac)))
1718        return AG7100_RX_STATUS_OOM;
1719    /*
1720    * !oom; if stopped, restart h/w
1721    */
1722
1723    if (unlikely(status & AG7100_RX_STATUS_OVF))
1724    {
1725        mac->net_rx_over_errors ++;
1726        ag7100_intr_ack_rxovf(mac);
1727        ag7100_rx_start(mac);
1728    }
1729
1730    return ret;
1731}
1732
1733static struct sk_buff *
1734    ag7100_buffer_alloc(void)
1735{
1736    struct sk_buff *skb;
1737
1738#if 0//def CONFIG_CAMEO_REALTEK_PHY
1739    skb = dev_alloc_skb(AG7100_RX_BUF_SIZE+4);
1740#else
1741    skb = dev_alloc_skb(AG7100_RX_BUF_SIZE + AG7100_RX_RESERVE);
1742#endif
1743    if (unlikely(!skb))
1744        return NULL;
1745    skb_reserve(skb, AG7100_RX_RESERVE);
1746
1747    return skb;
1748}
1749
1750static void
1751ag7100_buffer_free(struct sk_buff *skb)
1752{
1753    if (in_irq())
1754        dev_kfree_skb_irq(skb);
1755    else
1756        dev_kfree_skb(skb);
1757}
1758
1759/*
1760 * Head is the first slot with a valid buffer. Tail is the last slot
1761 * replenished. Tries to refill buffers from tail to head.
1762 */
1763static int
1764ag7100_rx_replenish(ag7100_mac_t *mac)
1765{
1766    ag7100_ring_t   *r     = &mac->mac_rxring;
1767    int              head  = r->ring_head, tail = r->ring_tail, refilled = 0;
1768    ag7100_desc_t   *ds;
1769    ag7100_buffer_t *bf;
1770
1771    ag7100_trc(head,"hd");
1772    ag7100_trc(tail,"tl");
1773
1774    do
1775    {
1776        bf                  = &r->ring_buffer[tail];
1777        ds                  = &r->ring_desc[tail];
1778
1779        ag7100_trc(ds,"ds");
1780
1781        if(ag7100_rx_owned_by_dma(ds))
1782        {
1783            return -1;
1784        }
1785        assert(!bf->buf_pkt);
1786
1787        bf->buf_pkt         = ag7100_buffer_alloc();
1788        if (!bf->buf_pkt)
1789        {
1790            printk(MODULE_NAME ": outta skbs!\n");
1791            break;
1792        }
1793        dma_cache_inv((unsigned long)bf->buf_pkt->data, AG7100_RX_BUF_SIZE);
1794        ds->pkt_start_addr  = virt_to_phys(bf->buf_pkt->data);
1795
1796        ag7100_rx_give_to_dma(ds);
1797        refilled ++;
1798
1799        ag7100_ring_incr(tail);
1800
1801    } while(tail != head);
1802    /*
1803    * Flush descriptors
1804    */
1805    wmb();
1806
1807    r->ring_tail = tail;
1808    ag7100_trc(refilled,"refilled");
1809
1810    return refilled;
1811}
1812
1813/*
1814 * Reap from tail till the head or whenever we encounter an unxmited packet.
1815 */
1816static int
1817ag7100_tx_reap(ag7100_mac_t *mac)
1818{
1819    ag7100_ring_t   *r     = &mac->mac_txring;
1820    int              head  = r->ring_head, tail = r->ring_tail, reaped = 0, i;
1821    ag7100_desc_t   *ds;
1822    ag7100_buffer_t *bf;
1823    uint32_t    flags;
1824
1825    ag7100_trc_new(head,"hd");
1826    ag7100_trc_new(tail,"tl");
1827
1828    ar7100_flush_ge(mac->mac_unit);
1829    spin_lock_irqsave(&mac->mac_lock, flags);
1830    while(tail != head)
1831    {
1832        ds   = &r->ring_desc[tail];
1833
1834        ag7100_trc_new(ds,"ds");
1835
1836        if(ag7100_tx_owned_by_dma(ds))
1837            break;
1838
1839        bf      = &r->ring_buffer[tail];
1840        assert(bf->buf_pkt);
1841
1842        ag7100_trc_new(bf->buf_lastds,"lastds");
1843
1844        if(ag7100_tx_owned_by_dma(bf->buf_lastds))
1845            break;
1846
1847        for(i = 0; i < bf->buf_nds; i++)
1848        {
1849            ag7100_intr_ack_tx(mac);
1850            ag7100_ring_incr(tail);
1851        }
1852
1853        ag7100_buffer_free(bf->buf_pkt);
1854        bf->buf_pkt = NULL;
1855
1856        reaped ++;
1857    }
1858    spin_unlock_irqrestore(&mac->mac_lock, flags);
1859
1860    r->ring_tail = tail;
1861
1862    if (netif_queue_stopped(mac->mac_dev) &&
1863        (ag7100_ndesc_unused(mac, r) >= AG7100_TX_QSTART_THRESH) &&
1864        netif_carrier_ok(mac->mac_dev))
1865    {
1866        if (ag7100_reg_rd(mac, AG7100_DMA_INTR_MASK) & AG7100_INTR_TX)
1867        {
1868            spin_lock_irqsave(&mac->mac_lock, flags);
1869            ag7100_intr_disable_tx(mac);
1870            spin_unlock_irqrestore(&mac->mac_lock, flags);
1871        }
1872        netif_wake_queue(mac->mac_dev);
1873    }
1874
1875    return reaped;
1876}
1877
1878/*
1879 * allocate and init rings, descriptors etc.
1880 */
1881static int
1882ag7100_tx_alloc(ag7100_mac_t *mac)
1883{
1884    ag7100_ring_t *r = &mac->mac_txring;
1885    ag7100_desc_t *ds;
1886    int i, next;
1887
1888    if (ag7100_ring_alloc(r, AG7100_TX_DESC_CNT))
1889        return 1;
1890
1891    ag7100_trc(r->ring_desc,"ring_desc");
1892
1893    ds = r->ring_desc;
1894    for(i = 0; i < r->ring_nelem; i++ )
1895    {
1896        ag7100_trc_new(ds,"tx alloc ds");
1897        next                =   (i == (r->ring_nelem - 1)) ? 0 : (i + 1);
1898        ds[i].next_desc     =   ag7100_desc_dma_addr(r, &ds[next]);
1899        ag7100_tx_own(&ds[i]);
1900    }
1901
1902    return 0;
1903}
1904
1905static int
1906ag7100_rx_alloc(ag7100_mac_t *mac)
1907{
1908    ag7100_ring_t *r  = &mac->mac_rxring;
1909    ag7100_desc_t *ds;
1910    int i, next, tail = r->ring_tail;
1911    ag7100_buffer_t *bf;
1912
1913    if (ag7100_ring_alloc(r, AG7100_RX_DESC_CNT))
1914        return 1;
1915
1916    ag7100_trc(r->ring_desc,"ring_desc");
1917
1918    ds = r->ring_desc;
1919    for(i = 0; i < r->ring_nelem; i++ )
1920    {
1921        next                =   (i == (r->ring_nelem - 1)) ? 0 : (i + 1);
1922        ds[i].next_desc     =   ag7100_desc_dma_addr(r, &ds[next]);
1923    }
1924
1925    for (i = 0; i < AG7100_RX_DESC_CNT; i++)
1926    {
1927        bf                  = &r->ring_buffer[tail];
1928        ds                  = &r->ring_desc[tail];
1929
1930        bf->buf_pkt         = ag7100_buffer_alloc();
1931        if (!bf->buf_pkt)
1932            goto error;
1933
1934        dma_cache_inv((unsigned long)bf->buf_pkt->data, AG7100_RX_BUF_SIZE);
1935        ds->pkt_start_addr  = virt_to_phys(bf->buf_pkt->data);
1936
1937        ag7100_rx_give_to_dma(ds);
1938        ag7100_ring_incr(tail);
1939    }
1940
1941    return 0;
1942error:
1943    printk(MODULE_NAME ": unable to allocate rx\n");
1944    ag7100_rx_free(mac);
1945    return 1;
1946}
1947
1948static void
1949ag7100_tx_free(ag7100_mac_t *mac)
1950{
1951    ag7100_ring_release(mac, &mac->mac_txring);
1952    ag7100_ring_free(&mac->mac_txring);
1953}
1954
1955static void
1956ag7100_rx_free(ag7100_mac_t *mac)
1957{
1958    ag7100_ring_release(mac, &mac->mac_rxring);
1959    ag7100_ring_free(&mac->mac_rxring);
1960}
1961
1962static int
1963ag7100_ring_alloc(ag7100_ring_t *r, int count)
1964{
1965    int desc_alloc_size, buf_alloc_size;
1966
1967    desc_alloc_size = sizeof(ag7100_desc_t)   * count;
1968    buf_alloc_size  = sizeof(ag7100_buffer_t) * count;
1969
1970    memset(r, 0, sizeof(ag7100_ring_t));
1971
1972    r->ring_buffer = (ag7100_buffer_t *)kmalloc(buf_alloc_size, GFP_KERNEL);
1973    printk("%s Allocated %d at 0x%lx\n",__func__,buf_alloc_size,(unsigned long) r->ring_buffer);
1974    if (!r->ring_buffer)
1975    {
1976        printk(MODULE_NAME ": unable to allocate buffers\n");
1977        return 1;
1978    }
1979
1980    r->ring_desc  =  (ag7100_desc_t *)dma_alloc_coherent(NULL,
1981        desc_alloc_size,
1982        &r->ring_desc_dma,
1983        GFP_DMA);
1984    if (! r->ring_desc)
1985    {
1986        printk(MODULE_NAME ": unable to allocate coherent descs\n");
1987        kfree(r->ring_buffer);
1988        printk("%s Freeing at 0x%lx\n",__func__,(unsigned long) r->ring_buffer);
1989        return 1;
1990    }
1991
1992    memset(r->ring_buffer, 0, buf_alloc_size);
1993    memset(r->ring_desc,   0, desc_alloc_size);
1994    r->ring_nelem   = count;
1995
1996    return 0;
1997}
1998
1999static void
2000ag7100_ring_release(ag7100_mac_t *mac, ag7100_ring_t  *r)
2001{
2002    int i;
2003
2004    for(i = 0; i < r->ring_nelem; i++)
2005        if (r->ring_buffer[i].buf_pkt)
2006            ag7100_buffer_free(r->ring_buffer[i].buf_pkt);
2007}
2008
2009static void
2010ag7100_ring_free(ag7100_ring_t *r)
2011{
2012    dma_free_coherent(NULL, sizeof(ag7100_desc_t)*r->ring_nelem, r->ring_desc,
2013        r->ring_desc_dma);
2014    kfree(r->ring_buffer);
2015    printk("%s Freeing at 0x%lx\n",__func__,(unsigned long) r->ring_buffer);
2016}
2017
2018/*
2019 * Error timers
2020 */
2021static void
2022ag7100_oom_timer(unsigned long data)
2023{
2024    ag7100_mac_t *mac = (ag7100_mac_t *)data;
2025    int val;
2026
2027    ag7100_trc(data,"data");
2028    ag7100_rx_replenish(mac);
2029    if (ag7100_rx_ring_full(mac))
2030    {
2031        val = mod_timer(&mac->mac_oom_timer, jiffies+1);
2032        assert(!val);
2033    }
2034    else
2035#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
2036        netif_rx_schedule(mac->mac_dev, &mac->mac_napi);
2037#else
2038        netif_rx_schedule(mac->mac_dev);
2039#endif
2040}
2041
2042static void
2043ag7100_tx_timeout(struct net_device *dev)
2044{
2045    ag7100_mac_t *mac = (ag7100_mac_t *)dev->priv;
2046    ag7100_trc(dev,"dev");
2047    printk("%s\n",__func__);
2048    /*
2049    * Do the reset outside of interrupt context
2050    */
2051    schedule_work(&mac->mac_tx_timeout);
2052}
2053
2054
2055static void
2056ag7100_tx_timeout_task(struct work_struct *work)
2057{
2058    ag7100_mac_t *mac = container_of(work, ag7100_mac_t, mac_tx_timeout);
2059    ag7100_trc(mac,"mac");
2060    ag7100_stop(mac->mac_dev);
2061    ag7100_open(mac->mac_dev);
2062}
2063
2064static void
2065ag7100_get_default_macaddr(ag7100_mac_t *mac, u8 *mac_addr)
2066{
2067    /*
2068    ** Use MAC address stored in Flash.  If CONFIG_AG7100_MAC_LOCATION is defined,
2069    ** it provides the physical address of where the MAC addresses are located.
2070    ** This can be a board specific location, so it's best to be part of the
2071    ** defconfig for that board.
2072    **
2073    ** The default locations assume the last sector in flash.
2074    */
2075   
2076#ifdef CONFIG_AG7100_MAC_LOCATION
2077    u8 *eep_mac_addr = (u8 *)( CONFIG_AG7100_MAC_LOCATION + (mac->mac_unit)*6);
2078#else
2079    u8 *eep_mac_addr = (mac->mac_unit) ? AR7100_EEPROM_GE1_MAC_ADDR:
2080        AR7100_EEPROM_GE0_MAC_ADDR;
2081#endif
2082
2083    printk(MODULE_NAME "CHH: Mac address for unit %d\n",mac->mac_unit);
2084    printk(MODULE_NAME "CHH: %02x:%02x:%02x:%02x:%02x:%02x \n",
2085        eep_mac_addr[0],eep_mac_addr[1],eep_mac_addr[2],
2086        eep_mac_addr[3],eep_mac_addr[4],eep_mac_addr[5]);   
2087    memcpy(mac_addr,eep_mac_addr,6);   
2088}
2089
2090static int
2091ag7100_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2092{
2093#if !defined(CONFIG_ATHRS26_PHY) && !defined(CONFIG_ATHRS16_PHY)
2094    printk(MODULE_NAME ": unsupported ioctl\n");
2095    return -EOPNOTSUPP;
2096#else
2097    return athr_ioctl(ifr->ifr_data, cmd);
2098#endif
2099}
2100
2101static struct net_device_stats
2102    *ag7100_get_stats(struct net_device *dev)
2103{
2104    ag7100_mac_t *mac = dev->priv;
2105    struct Qdisc *sch;
2106    int i;
2107
2108    sch = rcu_dereference(dev->qdisc);
2109    mac->mac_net_stats.tx_dropped = sch->qstats.drops;
2110
2111    i = ag7100_get_rx_count(mac) - mac->net_rx_packets;
2112    if (i<0)
2113        i=0;
2114
2115    mac->mac_net_stats.rx_missed_errors = i;
2116
2117    return &mac->mac_net_stats;
2118}
2119
2120static void
2121ag7100_vet_tx_len_per_pkt(unsigned int *len)
2122{
2123    unsigned int l;
2124
2125    /* make it into words */
2126    l = *len & ~3;
2127
2128    /*
2129    * Not too small
2130    */
2131    if (l < AG7100_TX_MIN_DS_LEN)
2132        l = AG7100_TX_MIN_DS_LEN;
2133    else
2134    /* Avoid len where we know we will deadlock, that
2135    * is the range between fif_len/2 and the MTU size
2136    */
2137    if (l > (AG7100_TX_FIFO_LEN/2))
2138    {
2139        if (l < AG7100_TX_MTU_LEN)
2140            {
2141            l = AG7100_TX_MTU_LEN;
2142            }
2143        else if (l > AG7100_TX_MAX_DS_LEN)
2144            {
2145            l = AG7100_TX_MAX_DS_LEN;
2146            }
2147        *len = l;
2148    }
2149}
2150
2151/*
2152 * All allocations (except irq and rings).
2153 */
2154static int __init
2155ag7100_init(void)
2156{
2157    int i;
2158    struct net_device *dev;
2159    ag7100_mac_t      *mac;
2160    uint32_t mask;
2161
2162    /*
2163    * tx_len_per_ds is the number of bytes per data transfer in word increments.
2164    *
2165    * If the value is 0 than we default the value to a known good value based
2166    * on benchmarks. Otherwise we use the value specified - within some
2167    * cosntraints of course.
2168    *
2169    * Tested working values are 256, 512, 768, 1024 & 1536.
2170    *
2171    * A value of 256 worked best in all benchmarks. That is the default.
2172    *
2173    */
2174
2175    /* Tested 256, 512, 768, 1024, 1536 OK, 1152 and 1280 failed*/
2176    if (0 == tx_len_per_ds)
2177        tx_len_per_ds = CONFIG_AG7100_LEN_PER_TX_DS;
2178
2179    ag7100_vet_tx_len_per_pkt( &tx_len_per_ds);
2180
2181    printk(MODULE_NAME ": Length per segment %d\n", tx_len_per_ds);
2182
2183    /*
2184    * Compute the number of descriptors for an MTU
2185    */
2186#ifndef CONFIG_AR9100
2187    tx_max_desc_per_ds_pkt = AG7100_TX_MAX_DS_LEN / tx_len_per_ds;
2188    if (AG7100_TX_MAX_DS_LEN % tx_len_per_ds) tx_max_desc_per_ds_pkt++;
2189#else
2190    tx_max_desc_per_ds_pkt =1;
2191#endif
2192
2193    printk(MODULE_NAME ": Max segments per packet %d\n", tx_max_desc_per_ds_pkt);
2194    printk(MODULE_NAME ": Max tx descriptor count    %d\n", AG7100_TX_DESC_CNT);
2195    printk(MODULE_NAME ": Max rx descriptor count    %d\n", AG7100_RX_DESC_CNT);
2196
2197    /*
2198    * Let hydra know how much to put into the fifo in words (for tx)
2199    */
2200    if (0 == fifo_3)
2201        fifo_3 = 0x000001ff | ((AG7100_TX_FIFO_LEN-tx_len_per_ds)/4)<<16;
2202
2203    printk(MODULE_NAME ": fifo cfg 3 %08x\n", fifo_3);
2204
2205    /*
2206    ** Do the rest of the initializations
2207    */
2208
2209    for(i = 0; i < AG7100_NMACS; i++)
2210    {
2211        mac = kmalloc(sizeof(ag7100_mac_t), GFP_KERNEL);
2212        if (!mac)
2213        {
2214            printk(MODULE_NAME ": unable to allocate mac\n");
2215            return 1;
2216        }
2217        memset(mac, 0, sizeof(ag7100_mac_t));
2218
2219        mac->mac_unit               =  i;
2220        mac->mac_base               =  ag7100_mac_base(i);
2221        mac->mac_irq                =  ag7100_mac_irq(i);
2222        ag7100_macs[i]              =  mac;
2223        spin_lock_init(&mac->mac_lock);
2224        /*
2225        * out of memory timer
2226        */
2227        init_timer(&mac->mac_oom_timer);
2228        mac->mac_oom_timer.data     = (unsigned long)mac;
2229        mac->mac_oom_timer.function = ag7100_oom_timer;
2230        /*
2231        * watchdog task
2232        */
2233        INIT_WORK(&mac->mac_tx_timeout, ag7100_tx_timeout_task);
2234
2235        dev = alloc_etherdev(0);
2236        if (!dev)
2237        {
2238            kfree(mac);
2239            printk("%s Freeing at 0x%lx\n",__func__,(unsigned long) mac);
2240            printk(MODULE_NAME ": unable to allocate etherdev\n");
2241            return 1;
2242        }
2243
2244        mac->mac_dev         =  dev;
2245        dev->get_stats       =  ag7100_get_stats;
2246        dev->open            =  ag7100_open;
2247        dev->stop            =  ag7100_stop;
2248        dev->hard_start_xmit =  ag7100_hard_start;
2249#if defined(CONFIG_ATHRS26_PHY) || defined(CONFIG_ATHRS16_PHY)
2250        dev->do_ioctl        =  ag7100_do_ioctl;
2251#else
2252        dev->do_ioctl        =  NULL;
2253#endif
2254#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
2255        netif_napi_add(dev, &mac->mac_napi, ag7100_poll, AG7100_NAPI_WEIGHT);
2256#else
2257        dev->poll            =  ag7100_poll;
2258        dev->weight          =  AG7100_NAPI_WEIGHT;
2259#endif
2260        dev->tx_timeout      =  ag7100_tx_timeout;
2261        dev->priv            =  mac;
2262       
2263#ifdef CONFIG_BUFFALO   // { append by BUFFALO 2008.09.19
2264
2265#ifdef CONFIG_TPLINK
2266        switch(rtl_chip_type_select())
2267        {
2268                case CHIP_TYPE_RTL8366SR:
2269                        rtl_funcs.phy_setup = rtl8366sr_phy_setup;
2270                        rtl_funcs.phy_is_up = rtl8366sr_phy_is_up;
2271                        rtl_funcs.phy_speed = rtl8366sr_phy_speed;
2272                        rtl_funcs.phy_is_fdx = rtl8366sr_phy_is_fdx;
2273                        rtl_funcs.get_link_status = rtl8366sr_get_link_status;
2274                        e1000_pll = e1000sr_pll;
2275                        e100_pll = e100sr_pll;
2276                        e10_pll = e10sr_pll;
2277                        break;
2278                case CHIP_TYPE_RTL8366RB:
2279                default:
2280                        rtl_funcs.phy_setup = rtl8366rb_phy_setup;
2281                        rtl_funcs.phy_is_up = rtl8366rb_phy_is_up;
2282                        rtl_funcs.phy_speed = rtl8366rb_phy_speed;
2283                        rtl_funcs.phy_is_fdx = rtl8366rb_phy_is_fdx;
2284                        rtl_funcs.get_link_status = rtl8366rb_get_link_status;
2285                        e1000_pll = e1000rb_pll;
2286                        e100_pll = e100rb_pll;
2287                        e10_pll = e10rb_pll;
2288                        break;
2289        }
2290#else
2291        switch(rtl_chip_type_select())
2292        {
2293                case CHIP_TYPE_RTL8366RB:
2294                        rtl_funcs.phy_setup = rtl8366rb_phy_setup;
2295                        rtl_funcs.phy_is_up = rtl8366rb_phy_is_up;
2296                        rtl_funcs.phy_speed = rtl8366rb_phy_speed;
2297                        rtl_funcs.phy_is_fdx = rtl8366rb_phy_is_fdx;
2298                        rtl_funcs.get_link_status = rtl8366rb_get_link_status;
2299                        e1000_pll = e1000rb_pll;
2300                        e100_pll = e100rb_pll;
2301                        e10_pll = e10rb_pll;
2302                        break;
2303                case CHIP_TYPE_RTL8366SR:
2304                default:
2305                        rtl_funcs.phy_setup = rtl8366sr_phy_setup;
2306                        rtl_funcs.phy_is_up = rtl8366sr_phy_is_up;
2307                        rtl_funcs.phy_speed = rtl8366sr_phy_speed;
2308                        rtl_funcs.phy_is_fdx = rtl8366sr_phy_is_fdx;
2309                        rtl_funcs.get_link_status = rtl8366sr_get_link_status;
2310                        e1000_pll = e1000sr_pll;
2311                        e100_pll = e100sr_pll;
2312                        e10_pll = e10sr_pll;
2313                        break;
2314        }
2315
2316
2317#endif
2318#else //CONFIG_BUFFALO //
2319#ifdef CONFIG_CAMEO_REALTEK_PHY
2320    rtl_chip_type_select();
2321#endif
2322#endif
2323        ag7100_get_default_macaddr(mac, dev->dev_addr);
2324
2325        if (register_netdev(dev))
2326        {
2327            printk(MODULE_NAME ": register netdev failed\n");
2328            goto failed;
2329        }
2330#ifdef CONFIG_PHY_LAYER
2331        ag7100_mdiobus_setup(i,dev);
2332#endif
2333
2334        netif_carrier_off(dev);
2335
2336#ifdef CONFIG_AR9100
2337        ag7100_reg_rmw_set(mac, AG7100_MAC_CFG1, AG7100_MAC_CFG1_SOFT_RST
2338                                | AG7100_MAC_CFG1_RX_RST | AG7100_MAC_CFG1_TX_RST);
2339#else
2340        ag7100_reg_rmw_set(mac, AG7100_MAC_CFG1, AG7100_MAC_CFG1_SOFT_RST);
2341#endif
2342        udelay(20);
2343        mask = ag7100_reset_mask(mac->mac_unit);
2344
2345        /*
2346        * put into reset, hold, pull out.
2347        */
2348        ar7100_reg_rmw_set(AR7100_RESET, mask);
2349        mdelay(100);
2350        ar7100_reg_rmw_clear(AR7100_RESET, mask);
2351        mdelay(100);
2352
2353    }
2354
2355    ag7100_trc_init();
2356
2357#ifdef CONFIG_AR9100
2358#define AP83_BOARD_NUM_ADDR ((char *)0xbf7f1244)
2359
2360        board_version = (AP83_BOARD_NUM_ADDR[0] - '0') +
2361                        ((AP83_BOARD_NUM_ADDR[1] - '0') * 10);
2362#endif
2363
2364#if defined(CONFIG_ATHRS26_PHY)
2365    athrs26_reg_dev(ag7100_macs);
2366#endif
2367
2368    return 0;
2369
2370failed:
2371    for(i = 0; i < AG7100_NMACS; i++)
2372    {
2373        if (!ag7100_macs[i])
2374            continue;
2375        if (ag7100_macs[i]->mac_dev)
2376            free_netdev(ag7100_macs[i]->mac_dev);
2377        kfree(ag7100_macs[i]);
2378        printk("%s Freeing at 0x%lx\n",__func__,(unsigned long) ag7100_macs[i]);
2379    }
2380    return 1;
2381}
2382
2383static void __exit
2384ag7100_cleanup(void)
2385{
2386    int i;
2387
2388    for(i = 0; i < AG7100_NMACS; i++)
2389    {
2390        unregister_netdev(ag7100_macs[i]->mac_dev);
2391        free_netdev(ag7100_macs[i]->mac_dev);
2392        kfree(ag7100_macs[i]);
2393        printk("%s Freeing at 0x%lx\n",__func__,(unsigned long) ag7100_macs[i]);
2394    }
2395    printk(MODULE_NAME ": cleanup done\n");
2396}
2397
2398module_init(ag7100_init);
2399module_exit(ag7100_cleanup);
Note: See TracBrowser for help on using the repository browser.