ltq-ptm: fix build with kernel 4.9
[librecmc/librecmc.git] / package / kernel / lantiq / ltq-ptm / src / ifxmips_ptm_vdsl.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : ifxmips_ptm_vdsl.c
4 ** PROJECT      : UEIP
5 ** MODULES      : PTM
6 **
7 ** DATE         : 7 Jul 2009
8 ** AUTHOR       : Xu Liang
9 ** DESCRIPTION  : PTM driver common source file (core functions for VR9)
10 ** COPYRIGHT    :       Copyright (c) 2006
11 **                      Infineon Technologies AG
12 **                      Am Campeon 1-12, 85579 Neubiberg, Germany
13 **
14 **    This program is free software; you can redistribute it and/or modify
15 **    it under the terms of the GNU General Public License as published by
16 **    the Free Software Foundation; either version 2 of the License, or
17 **    (at your option) any later version.
18 **
19 ** HISTORY
20 ** $Date        $Author         $Comment
21 ** 07 JUL 2009  Xu Liang        Init Version
22 *******************************************************************************/
23
24 #include <linux/version.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/types.h>
28 #include <linux/ctype.h>
29 #include <linux/errno.h>
30 #include <linux/proc_fs.h>
31 #include <linux/init.h>
32 #include <linux/ioctl.h>
33 #include <linux/etherdevice.h>
34 #include <linux/interrupt.h>
35 #include <linux/netdevice.h>
36
37 #include "ifxmips_ptm_vdsl.h"
38 #include <lantiq_soc.h>
39
40 #define MODULE_PARM_ARRAY(a, b)   module_param_array(a, int, NULL, 0)
41 #define MODULE_PARM(a, b)         module_param(a, int, 0)
42
43 static int wanqos_en = 0;
44 static int queue_gamma_map[4] = {0xFE, 0x01, 0x00, 0x00};
45
46 MODULE_PARM(wanqos_en, "i");
47 MODULE_PARM_DESC(wanqos_en, "WAN QoS support, 1 - enabled, 0 - disabled.");
48
49 MODULE_PARM_ARRAY(queue_gamma_map, "4-4i");
50 MODULE_PARM_DESC(queue_gamma_map, "TX QoS queues mapping to 4 TX Gamma interfaces.");
51
52 extern int (*ifx_mei_atm_showtime_enter)(struct port_cell_info *, void *);
53 extern int (*ifx_mei_atm_showtime_exit)(void);
54 extern int ifx_mei_atm_showtime_check(int *is_showtime, struct port_cell_info *port_cell, void **xdata_addr);
55
56 static int g_showtime = 0;
57 static void *g_xdata_addr = NULL;
58
59
60 #define ENABLE_TMP_DBG                          0
61
62 unsigned long cgu_get_pp32_clock(void)
63 {
64         struct clk *c = clk_get_ppe();
65         unsigned long rate = clk_get_rate(c);
66         clk_put(c);
67         return rate;
68 }
69
70 static void ptm_setup(struct net_device *, int);
71 static struct net_device_stats *ptm_get_stats(struct net_device *);
72 static int ptm_open(struct net_device *);
73 static int ptm_stop(struct net_device *);
74   static unsigned int ptm_poll(int, unsigned int);
75   static int ptm_napi_poll(struct napi_struct *, int);
76 static int ptm_hard_start_xmit(struct sk_buff *, struct net_device *);
77 static int ptm_change_mtu(struct net_device *, int);
78 static int ptm_ioctl(struct net_device *, struct ifreq *, int);
79 static void ptm_tx_timeout(struct net_device *);
80
81 static inline struct sk_buff* alloc_skb_rx(void);
82 static inline struct sk_buff* alloc_skb_tx(unsigned int);
83 static inline struct sk_buff *get_skb_pointer(unsigned int);
84 static inline int get_tx_desc(unsigned int, unsigned int *);
85
86 /*
87  *  Mailbox handler and signal function
88  */
89 static irqreturn_t mailbox_irq_handler(int, void *);
90
91 /*
92  *  Tasklet to Handle Swap Descriptors
93  */
94 static void do_swap_desc_tasklet(unsigned long);
95
96
97 /*
98  *  Init & clean-up functions
99  */
100 static inline int init_priv_data(void);
101 static inline void clear_priv_data(void);
102 static inline int init_tables(void);
103 static inline void clear_tables(void);
104
105 static int g_wanqos_en = 0;
106
107 static int g_queue_gamma_map[4];
108
109 static struct ptm_priv_data g_ptm_priv_data;
110
111 static struct net_device_ops g_ptm_netdev_ops = {
112     .ndo_get_stats       = ptm_get_stats,
113     .ndo_open            = ptm_open,
114     .ndo_stop            = ptm_stop,
115     .ndo_start_xmit      = ptm_hard_start_xmit,
116     .ndo_validate_addr   = eth_validate_addr,
117     .ndo_set_mac_address = eth_mac_addr,
118     .ndo_change_mtu      = ptm_change_mtu,
119     .ndo_do_ioctl        = ptm_ioctl,
120     .ndo_tx_timeout      = ptm_tx_timeout,
121 };
122
123 static struct net_device *g_net_dev[1] = {0};
124 static char *g_net_dev_name[1] = {"ptm0"};
125
126 static int g_ptm_prio_queue_map[8];
127
128 static DECLARE_TASKLET(g_swap_desc_tasklet, do_swap_desc_tasklet, 0);
129
130
131 unsigned int ifx_ptm_dbg_enable = DBG_ENABLE_MASK_ERR;
132
133 /*
134  * ####################################
135  *            Local Function
136  * ####################################
137  */
138
139 static void ptm_setup(struct net_device *dev, int ndev)
140 {
141     netif_carrier_off(dev);
142
143     dev->netdev_ops      = &g_ptm_netdev_ops;
144     netif_napi_add(dev, &g_ptm_priv_data.itf[ndev].napi, ptm_napi_poll, 16);
145     dev->watchdog_timeo  = ETH_WATCHDOG_TIMEOUT;
146
147     dev->dev_addr[0] = 0x00;
148     dev->dev_addr[1] = 0x20;
149         dev->dev_addr[2] = 0xda;
150         dev->dev_addr[3] = 0x86;
151         dev->dev_addr[4] = 0x23;
152         dev->dev_addr[5] = 0x75 + ndev;
153 }
154
155 static struct net_device_stats *ptm_get_stats(struct net_device *dev)
156 {
157    struct net_device_stats *s;
158   
159     if ( dev != g_net_dev[0] )
160         return NULL;
161 s = &g_ptm_priv_data.itf[0].stats;
162
163     return s;
164 }
165
166 static int ptm_open(struct net_device *dev)
167 {
168     ASSERT(dev == g_net_dev[0], "incorrect device");
169
170     napi_enable(&g_ptm_priv_data.itf[0].napi);
171
172     IFX_REG_W32_MASK(0, 1, MBOX_IGU1_IER);
173
174     netif_start_queue(dev);
175
176     return 0;
177 }
178
179 static int ptm_stop(struct net_device *dev)
180 {
181     ASSERT(dev == g_net_dev[0], "incorrect device");
182
183     IFX_REG_W32_MASK(1 | (1 << 17), 0, MBOX_IGU1_IER);
184
185     napi_disable(&g_ptm_priv_data.itf[0].napi);
186
187     netif_stop_queue(dev);
188
189     return 0;
190 }
191
192 static unsigned int ptm_poll(int ndev, unsigned int work_to_do)
193 {
194     unsigned int work_done = 0;
195     volatile struct rx_descriptor *desc;
196     struct rx_descriptor reg_desc;
197     struct sk_buff *skb, *new_skb;
198
199     ASSERT(ndev >= 0 && ndev < ARRAY_SIZE(g_net_dev), "ndev = %d (wrong value)", ndev);
200
201     while ( work_done < work_to_do ) {
202         desc = &WAN_RX_DESC_BASE[g_ptm_priv_data.itf[0].rx_desc_pos];
203         if ( desc->own /* || !desc->c */ )  //  if PP32 hold descriptor or descriptor not completed
204             break;
205         if ( ++g_ptm_priv_data.itf[0].rx_desc_pos == WAN_RX_DESC_NUM )
206             g_ptm_priv_data.itf[0].rx_desc_pos = 0;
207
208         reg_desc = *desc;
209         skb = get_skb_pointer(reg_desc.dataptr);
210         ASSERT(skb != NULL, "invalid pointer skb == NULL");
211
212         new_skb = alloc_skb_rx();
213         if ( new_skb != NULL ) {
214             skb_reserve(skb, reg_desc.byteoff);
215             skb_put(skb, reg_desc.datalen);
216
217             //  parse protocol header
218             skb->dev = g_net_dev[0];
219             skb->protocol = eth_type_trans(skb, skb->dev);
220
221             g_net_dev[0]->last_rx = jiffies;
222
223             netif_receive_skb(skb);
224
225             g_ptm_priv_data.itf[0].stats.rx_packets++;
226             g_ptm_priv_data.itf[0].stats.rx_bytes += reg_desc.datalen;
227
228             reg_desc.dataptr = (unsigned int)new_skb->data & 0x0FFFFFFF;
229             reg_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
230         }
231
232         reg_desc.datalen = RX_MAX_BUFFER_SIZE - RX_HEAD_MAC_ADDR_ALIGNMENT;
233         reg_desc.own     = 1;
234         reg_desc.c       = 0;
235
236         /*  write discriptor to memory  */
237         *((volatile unsigned int *)desc + 1) = *((unsigned int *)&reg_desc + 1);
238         wmb();
239         *(volatile unsigned int *)desc = *(unsigned int *)&reg_desc;
240
241         work_done++;
242     }
243
244     return work_done;
245 }
246
247 static int ptm_napi_poll(struct napi_struct *napi, int budget)
248 {
249     int ndev = 0;
250     unsigned int work_done;
251
252     work_done = ptm_poll(ndev, budget);
253
254     //  interface down
255     if ( !netif_running(napi->dev) ) {
256         napi_complete(napi);
257         return work_done;
258     }
259
260     //  clear interrupt
261     IFX_REG_W32_MASK(0, 1, MBOX_IGU1_ISRC);
262     //  no more traffic
263     if (work_done < budget) {
264         napi_complete(napi);
265         IFX_REG_W32_MASK(0, 1, MBOX_IGU1_IER);
266         return work_done;
267     }
268
269     //  next round
270     return work_done;
271 }
272
273 static int ptm_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
274 {
275     unsigned int f_full;
276     int desc_base;
277     volatile struct tx_descriptor *desc;
278     struct tx_descriptor reg_desc = {0};
279     struct sk_buff *skb_to_free;
280     unsigned int byteoff;
281
282     ASSERT(dev == g_net_dev[0], "incorrect device");
283
284     if ( !g_showtime ) {
285         err("not in showtime");
286         goto PTM_HARD_START_XMIT_FAIL;
287     }
288
289     /*  allocate descriptor */
290     desc_base = get_tx_desc(0, &f_full);
291     if ( f_full ) {
292 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
293         netif_trans_update(dev);
294 #else
295         dev->trans_start = jiffies;
296 #endif
297         netif_stop_queue(dev);
298
299         IFX_REG_W32_MASK(0, 1 << 17, MBOX_IGU1_ISRC);
300         IFX_REG_W32_MASK(0, 1 << 17, MBOX_IGU1_IER);
301     }
302     if ( desc_base < 0 )
303         goto PTM_HARD_START_XMIT_FAIL;
304     desc = &CPU_TO_WAN_TX_DESC_BASE[desc_base];
305
306     byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
307     if ( skb_headroom(skb) < sizeof(struct sk_buff *) + byteoff || skb_cloned(skb) ) {
308         struct sk_buff *new_skb;
309
310         ASSERT(skb_headroom(skb) >= sizeof(struct sk_buff *) + byteoff, "skb_headroom(skb) < sizeof(struct sk_buff *) + byteoff");
311         ASSERT(!skb_cloned(skb), "skb is cloned");
312
313         new_skb = alloc_skb_tx(skb->len);
314         if ( new_skb == NULL ) {
315             dbg("no memory");
316             goto ALLOC_SKB_TX_FAIL;
317         }
318         skb_put(new_skb, skb->len);
319         memcpy(new_skb->data, skb->data, skb->len);
320         dev_kfree_skb_any(skb);
321         skb = new_skb;
322         byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
323         /*  write back to physical memory   */
324         dma_cache_wback((unsigned long)skb->data, skb->len);
325     }
326
327     *(struct sk_buff **)((unsigned int)skb->data - byteoff - sizeof(struct sk_buff *)) = skb;
328     /*  write back to physical memory   */
329     dma_cache_wback((unsigned long)skb->data - byteoff - sizeof(struct sk_buff *), skb->len + byteoff + sizeof(struct sk_buff *));
330
331     /*  free previous skb   */
332     skb_to_free = get_skb_pointer(desc->dataptr);
333     if ( skb_to_free != NULL )
334         dev_kfree_skb_any(skb_to_free);
335
336     /*  update descriptor   */
337     reg_desc.small   = 0;
338     reg_desc.dataptr = (unsigned int)skb->data & (0x0FFFFFFF ^ (DATA_BUFFER_ALIGNMENT - 1));
339     reg_desc.datalen = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
340     reg_desc.qid     = g_ptm_prio_queue_map[skb->priority > 7 ? 7 : skb->priority];
341     reg_desc.byteoff = byteoff;
342     reg_desc.own     = 1;
343     reg_desc.c       = 1;
344     reg_desc.sop = reg_desc.eop = 1;
345
346     /*  update MIB  */
347     g_ptm_priv_data.itf[0].stats.tx_packets++;
348     g_ptm_priv_data.itf[0].stats.tx_bytes += reg_desc.datalen;
349
350     /*  write discriptor to memory  */
351     *((volatile unsigned int *)desc + 1) = *((unsigned int *)&reg_desc + 1);
352     wmb();
353     *(volatile unsigned int *)desc = *(unsigned int *)&reg_desc;
354
355 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
356     netif_trans_update(dev);
357 #else
358     dev->trans_start = jiffies;
359 #endif
360
361     return 0;
362
363 ALLOC_SKB_TX_FAIL:
364 PTM_HARD_START_XMIT_FAIL:
365     dev_kfree_skb_any(skb);
366     g_ptm_priv_data.itf[0].stats.tx_dropped++;
367     return 0;
368 }
369
370 static int ptm_change_mtu(struct net_device *dev, int mtu)
371 {
372         /* Allow up to 1508 bytes, for RFC4638 */
373         if (mtu < 68 || mtu > ETH_DATA_LEN + 8)
374                 return -EINVAL;
375         dev->mtu = mtu;
376         return 0;
377 }
378
379 static int ptm_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
380 {
381     ASSERT(dev == g_net_dev[0], "incorrect device");
382
383     switch ( cmd )
384     {
385     case IFX_PTM_MIB_CW_GET:
386         ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxNoIdleCodewords   = IFX_REG_R32(DREG_AR_CELL0) + IFX_REG_R32(DREG_AR_CELL1);
387         ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxIdleCodewords     = IFX_REG_R32(DREG_AR_IDLE_CNT0) + IFX_REG_R32(DREG_AR_IDLE_CNT1);
388         ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifRxCodingViolation   = IFX_REG_R32(DREG_AR_CVN_CNT0) + IFX_REG_R32(DREG_AR_CVN_CNT1) + IFX_REG_R32(DREG_AR_CVNP_CNT0) + IFX_REG_R32(DREG_AR_CVNP_CNT1);
389         ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxNoIdleCodewords   = IFX_REG_R32(DREG_AT_CELL0) + IFX_REG_R32(DREG_AT_CELL1);
390         ((PTM_CW_IF_ENTRY_T *)ifr->ifr_data)->ifTxIdleCodewords     = IFX_REG_R32(DREG_AT_IDLE_CNT0) + IFX_REG_R32(DREG_AT_IDLE_CNT1);
391         break;
392     case IFX_PTM_MIB_FRAME_GET:
393         {
394             PTM_FRAME_MIB_T data = {0};
395             int i;
396
397             data.RxCorrect = IFX_REG_R32(DREG_AR_HEC_CNT0) + IFX_REG_R32(DREG_AR_HEC_CNT1) + IFX_REG_R32(DREG_AR_AIIDLE_CNT0) + IFX_REG_R32(DREG_AR_AIIDLE_CNT1);
398             for ( i = 0; i < 4; i++ )
399                 data.RxDropped += WAN_RX_MIB_TABLE(i)->wrx_dropdes_pdu;
400             for ( i = 0; i < 8; i++ )
401                 data.TxSend    += WAN_TX_MIB_TABLE(i)->wtx_total_pdu;
402
403             *((PTM_FRAME_MIB_T *)ifr->ifr_data) = data;
404         }
405         break;
406     case IFX_PTM_CFG_GET:
407         //  use bear channel 0 preemption gamma interface settings
408         ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcPresent = 1;
409         ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck   = RX_GAMMA_ITF_CFG(0)->rx_eth_fcs_ver_dis == 0 ? 1 : 0;
410         ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck    = RX_GAMMA_ITF_CFG(0)->rx_tc_crc_ver_dis == 0 ? 1 : 0;;
411         ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen      = RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size == 0 ? 0 : (RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size * 16);
412         ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen     = TX_GAMMA_ITF_CFG(0)->tx_eth_fcs_gen_dis == 0 ? 1 : 0;
413         ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen      = TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size == 0 ? 0 : 1;
414         ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen      = TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size == 0 ? 0 : (TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size * 16);
415         break;
416     case IFX_PTM_CFG_SET:
417         {
418             int i;
419
420             for ( i = 0; i < 4; i++ ) {
421                 RX_GAMMA_ITF_CFG(i)->rx_eth_fcs_ver_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxEthCrcCheck ? 0 : 1;
422
423                 RX_GAMMA_ITF_CFG(0)->rx_tc_crc_ver_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcCheck ? 0 : 1;
424
425                 switch ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->RxTcCrcLen ) {
426                     case 16: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 1; break;
427                     case 32: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 2; break;
428                     default: RX_GAMMA_ITF_CFG(0)->rx_tc_crc_size = 0;
429                 }
430
431                 TX_GAMMA_ITF_CFG(0)->tx_eth_fcs_gen_dis = ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxEthCrcGen ? 0 : 1;
432
433                 if ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcGen ) {
434                     switch ( ((IFX_PTM_CFG_T *)ifr->ifr_data)->TxTcCrcLen ) {
435                         case 16: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 1; break;
436                         case 32: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 2; break;
437                         default: TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 0;
438                     }
439                 }
440                 else
441                     TX_GAMMA_ITF_CFG(0)->tx_tc_crc_size = 0;
442             }
443         }
444         break;
445     case IFX_PTM_MAP_PKT_PRIO_TO_Q:
446         {
447             struct ppe_prio_q_map cmd;
448
449             if ( copy_from_user(&cmd, ifr->ifr_data, sizeof(cmd)) )
450                 return -EFAULT;
451
452             if ( cmd.pkt_prio < 0 || cmd.pkt_prio >= ARRAY_SIZE(g_ptm_prio_queue_map) )
453                 return -EINVAL;
454
455             if ( cmd.qid < 0 || cmd.qid >= g_wanqos_en )
456                 return -EINVAL;
457
458             g_ptm_prio_queue_map[cmd.pkt_prio] = cmd.qid;
459         }
460         break;
461     default:
462         return -EOPNOTSUPP;
463     }
464
465     return 0;
466 }
467
468 static void ptm_tx_timeout(struct net_device *dev)
469 {
470     ASSERT(dev == g_net_dev[0], "incorrect device");
471
472     /*  disable TX irq, release skb when sending new packet */
473     IFX_REG_W32_MASK(1 << 17, 0, MBOX_IGU1_IER);
474
475     /*  wake up TX queue    */
476     netif_wake_queue(dev);
477
478     return;
479 }
480
481 static inline struct sk_buff* alloc_skb_rx(void)
482 {
483     struct sk_buff *skb;
484
485     /*  allocate memroy including trailer and padding   */
486     skb = dev_alloc_skb(RX_MAX_BUFFER_SIZE + DATA_BUFFER_ALIGNMENT);
487     if ( skb != NULL ) {
488         /*  must be burst length alignment and reserve two more bytes for MAC address alignment  */
489         if ( ((unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1)) != 0 )
490             skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
491         /*  pub skb in reserved area "skb->data - 4"    */
492         *((struct sk_buff **)skb->data - 1) = skb;
493         wmb();
494         /*  write back and invalidate cache    */
495         dma_cache_wback_inv((unsigned long)skb->data - sizeof(skb), sizeof(skb));
496         /*  invalidate cache    */
497         dma_cache_inv((unsigned long)skb->data, (unsigned int)skb->end - (unsigned int)skb->data);
498     }
499
500     return skb;
501 }
502
503 static inline struct sk_buff* alloc_skb_tx(unsigned int size)
504 {
505     struct sk_buff *skb;
506
507     /*  allocate memory including padding   */
508     size = RX_MAX_BUFFER_SIZE;
509     size = (size + DATA_BUFFER_ALIGNMENT - 1) & ~(DATA_BUFFER_ALIGNMENT - 1);
510     skb = dev_alloc_skb(size + DATA_BUFFER_ALIGNMENT);
511     /*  must be burst length alignment  */
512     if ( skb != NULL )
513         skb_reserve(skb, ~((unsigned int)skb->data + (DATA_BUFFER_ALIGNMENT - 1)) & (DATA_BUFFER_ALIGNMENT - 1));
514     return skb;
515 }
516
517 static inline struct sk_buff *get_skb_pointer(unsigned int dataptr)
518 {
519     unsigned int skb_dataptr;
520     struct sk_buff *skb;
521
522     //  usually, CPE memory is less than 256M bytes
523     //  so NULL means invalid pointer
524     if ( dataptr == 0 ) {
525         dbg("dataptr is 0, it's supposed to be invalid pointer");
526         return NULL;
527     }
528
529     skb_dataptr = (dataptr - 4) | KSEG1;
530     skb = *(struct sk_buff **)skb_dataptr;
531
532     ASSERT((unsigned int)skb >= KSEG0, "invalid skb - skb = %#08x, dataptr = %#08x", (unsigned int)skb, dataptr);
533     ASSERT((((unsigned int)skb->data & (0x0FFFFFFF ^ (DATA_BUFFER_ALIGNMENT - 1))) | KSEG1) == (dataptr | KSEG1), "invalid skb - skb = %#08x, skb->data = %#08x, dataptr = %#08x", (unsigned int)skb, (unsigned int)skb->data, dataptr);
534
535     return skb;
536 }
537
538 static inline int get_tx_desc(unsigned int itf, unsigned int *f_full)
539 {
540     int desc_base = -1;
541     struct ptm_itf *p_itf = &g_ptm_priv_data.itf[0];
542
543     //  assume TX is serial operation
544     //  no protection provided
545
546     *f_full = 1;
547
548     if ( CPU_TO_WAN_TX_DESC_BASE[p_itf->tx_desc_pos].own == 0 ) {
549         desc_base = p_itf->tx_desc_pos;
550         if ( ++(p_itf->tx_desc_pos) == CPU_TO_WAN_TX_DESC_NUM )
551             p_itf->tx_desc_pos = 0;
552         if ( CPU_TO_WAN_TX_DESC_BASE[p_itf->tx_desc_pos].own == 0 )
553             *f_full = 0;
554     }
555
556     return desc_base;
557 }
558
559 static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
560 {
561     unsigned int isr;
562     int i;
563
564     isr = IFX_REG_R32(MBOX_IGU1_ISR);
565     IFX_REG_W32(isr, MBOX_IGU1_ISRC);
566     isr &= IFX_REG_R32(MBOX_IGU1_IER);
567
568             if (isr & BIT(0)) {
569                 IFX_REG_W32_MASK(1, 0, MBOX_IGU1_IER);
570                 napi_schedule(&g_ptm_priv_data.itf[0].napi);
571 #if defined(ENABLE_TMP_DBG) && ENABLE_TMP_DBG
572                 {
573                     volatile struct rx_descriptor *desc = &WAN_RX_DESC_BASE[g_ptm_priv_data.itf[0].rx_desc_pos];
574
575                     if ( desc->own ) {  //  PP32 hold
576                         err("invalid interrupt");
577                     }
578                 }
579 #endif
580             }
581            if (isr & BIT(16)) {
582                 IFX_REG_W32_MASK(1 << 16, 0, MBOX_IGU1_IER);
583                 tasklet_hi_schedule(&g_swap_desc_tasklet);
584             }
585             if (isr & BIT(17)) {
586                 IFX_REG_W32_MASK(1 << 17, 0, MBOX_IGU1_IER);
587                 netif_wake_queue(g_net_dev[0]);
588                 }
589
590     return IRQ_HANDLED;
591 }
592
593 static void do_swap_desc_tasklet(unsigned long arg)
594 {
595     int budget = 32;
596     volatile struct tx_descriptor *desc;
597     struct sk_buff *skb;
598     unsigned int byteoff;
599
600     while ( budget-- > 0 ) {
601         if ( WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos].own )  //  if PP32 hold descriptor
602             break;
603
604         desc = &WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos];
605         if ( ++g_ptm_priv_data.itf[0].tx_swap_desc_pos == WAN_SWAP_DESC_NUM )
606             g_ptm_priv_data.itf[0].tx_swap_desc_pos = 0;
607
608         skb = get_skb_pointer(desc->dataptr);
609         if ( skb != NULL )
610             dev_kfree_skb_any(skb);
611
612         skb = alloc_skb_tx(RX_MAX_BUFFER_SIZE);
613         if ( skb == NULL )
614             panic("can't allocate swap buffer for PPE firmware use\n");
615         byteoff = (unsigned int)skb->data & (DATA_BUFFER_ALIGNMENT - 1);
616         *(struct sk_buff **)((unsigned int)skb->data - byteoff - sizeof(struct sk_buff *)) = skb;
617
618         desc->dataptr = (unsigned int)skb->data & 0x0FFFFFFF;
619         desc->own = 1;
620     }
621
622     //  clear interrupt
623     IFX_REG_W32_MASK(0, 16, MBOX_IGU1_ISRC);
624     //  no more skb to be replaced
625     if ( WAN_SWAP_DESC_BASE[g_ptm_priv_data.itf[0].tx_swap_desc_pos].own ) {    //  if PP32 hold descriptor
626         IFX_REG_W32_MASK(0, 1 << 16, MBOX_IGU1_IER);
627         return;
628     }
629
630     tasklet_hi_schedule(&g_swap_desc_tasklet);
631     return;
632 }
633
634
635 static inline int ifx_ptm_version(char *buf)
636 {
637     int len = 0;
638     unsigned int major, minor;
639
640     ifx_ptm_get_fw_ver(&major, &minor);
641
642     len += sprintf(buf + len, "PTM %d.%d.%d", IFX_PTM_VER_MAJOR, IFX_PTM_VER_MID, IFX_PTM_VER_MINOR);
643     len += sprintf(buf + len, "    PTM (E1) firmware version %d.%d\n", major, minor);
644
645     return len;
646 }
647
648 static inline int init_priv_data(void)
649 {
650     int i, j;
651
652     g_wanqos_en = wanqos_en ? wanqos_en : 8;
653     if ( g_wanqos_en > 8 )
654         g_wanqos_en = 8;
655
656     for ( i = 0; i < ARRAY_SIZE(g_queue_gamma_map); i++ )
657     {
658         g_queue_gamma_map[i] = queue_gamma_map[i] & ((1 << g_wanqos_en) - 1);
659         for ( j = 0; j < i; j++ )
660             g_queue_gamma_map[i] &= ~g_queue_gamma_map[j];
661     }
662
663     memset(&g_ptm_priv_data, 0, sizeof(g_ptm_priv_data));
664
665     {
666         int max_packet_priority = ARRAY_SIZE(g_ptm_prio_queue_map);
667         int tx_num_q;
668         int q_step, q_accum, p_step;
669
670         tx_num_q = __ETH_WAN_TX_QUEUE_NUM;
671         q_step = tx_num_q - 1;
672         p_step = max_packet_priority - 1;
673         for ( j = 0, q_accum = 0; j < max_packet_priority; j++, q_accum += q_step )
674             g_ptm_prio_queue_map[j] = q_step - (q_accum + (p_step >> 1)) / p_step;
675     }
676
677     return 0;
678 }
679
680 static inline void clear_priv_data(void)
681 {
682 }
683
684 static inline int init_tables(void)
685 {
686     struct sk_buff *skb_pool[WAN_RX_DESC_NUM] = {0};
687     struct cfg_std_data_len cfg_std_data_len = {0};
688     struct tx_qos_cfg tx_qos_cfg = {0};
689     struct psave_cfg psave_cfg = {0};
690     struct eg_bwctrl_cfg eg_bwctrl_cfg = {0};
691     struct test_mode test_mode = {0};
692     struct rx_bc_cfg rx_bc_cfg = {0};
693     struct tx_bc_cfg tx_bc_cfg = {0};
694     struct gpio_mode gpio_mode = {0};
695     struct gpio_wm_cfg gpio_wm_cfg = {0};
696     struct rx_gamma_itf_cfg rx_gamma_itf_cfg = {0};
697     struct tx_gamma_itf_cfg tx_gamma_itf_cfg = {0};
698     struct wtx_qos_q_desc_cfg wtx_qos_q_desc_cfg = {0};
699     struct rx_descriptor rx_desc = {0};
700     struct tx_descriptor tx_desc = {0};
701     int i;
702
703     for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
704         skb_pool[i] = alloc_skb_rx();
705         if ( skb_pool[i] == NULL )
706             goto ALLOC_SKB_RX_FAIL;
707     }
708
709     cfg_std_data_len.byte_off = RX_HEAD_MAC_ADDR_ALIGNMENT; //  this field replaces byte_off in rx descriptor of VDSL ingress
710     cfg_std_data_len.data_len = 1600;
711     *CFG_STD_DATA_LEN = cfg_std_data_len;
712
713     tx_qos_cfg.time_tick    = cgu_get_pp32_clock() / 62500; //  16 * (cgu_get_pp32_clock() / 1000000)
714     tx_qos_cfg.overhd_bytes = 0;
715     tx_qos_cfg.eth1_eg_qnum = __ETH_WAN_TX_QUEUE_NUM;
716     tx_qos_cfg.eth1_burst_chk = 1;
717     tx_qos_cfg.eth1_qss     = 0;
718     tx_qos_cfg.shape_en     = 0;    //  disable
719     tx_qos_cfg.wfq_en       = 0;    //  strict priority
720     *TX_QOS_CFG = tx_qos_cfg;
721
722     psave_cfg.start_state   = 0;
723     psave_cfg.sleep_en      = 1;    //  enable sleep mode
724     *PSAVE_CFG = psave_cfg;
725
726     eg_bwctrl_cfg.fdesc_wm  = 16;
727     eg_bwctrl_cfg.class_len = 128;
728     *EG_BWCTRL_CFG = eg_bwctrl_cfg;
729
730     //*GPIO_ADDR = (unsigned int)IFX_GPIO_P0_OUT;
731     *GPIO_ADDR = (unsigned int)0x00000000;  //  disabled by default
732
733     gpio_mode.gpio_bit_bc1 = 2;
734     gpio_mode.gpio_bit_bc0 = 1;
735     gpio_mode.gpio_bc1_en  = 0;
736     gpio_mode.gpio_bc0_en  = 0;
737     *GPIO_MODE = gpio_mode;
738
739     gpio_wm_cfg.stop_wm_bc1  = 2;
740     gpio_wm_cfg.start_wm_bc1 = 4;
741     gpio_wm_cfg.stop_wm_bc0  = 2;
742     gpio_wm_cfg.start_wm_bc0 = 4;
743     *GPIO_WM_CFG = gpio_wm_cfg;
744
745     test_mode.mib_clear_mode    = 0;
746     test_mode.test_mode         = 0;
747     *TEST_MODE = test_mode;
748
749     rx_bc_cfg.local_state   = 0;
750     rx_bc_cfg.remote_state  = 0;
751     rx_bc_cfg.to_false_th   = 7;
752     rx_bc_cfg.to_looking_th = 3;
753     *RX_BC_CFG(0) = rx_bc_cfg;
754     *RX_BC_CFG(1) = rx_bc_cfg;
755
756     tx_bc_cfg.fill_wm   = 2;
757     tx_bc_cfg.uflw_wm   = 2;
758     *TX_BC_CFG(0) = tx_bc_cfg;
759     *TX_BC_CFG(1) = tx_bc_cfg;
760
761     rx_gamma_itf_cfg.receive_state      = 0;
762     rx_gamma_itf_cfg.rx_min_len         = 60;
763     rx_gamma_itf_cfg.rx_pad_en          = 1;
764     rx_gamma_itf_cfg.rx_eth_fcs_ver_dis = 0;
765     rx_gamma_itf_cfg.rx_rm_eth_fcs      = 1;
766     rx_gamma_itf_cfg.rx_tc_crc_ver_dis  = 0;
767     rx_gamma_itf_cfg.rx_tc_crc_size     = 1;
768     rx_gamma_itf_cfg.rx_eth_fcs_result  = 0xC704DD7B;
769     rx_gamma_itf_cfg.rx_tc_crc_result   = 0x1D0F1D0F;
770     rx_gamma_itf_cfg.rx_crc_cfg         = 0x2500;
771     rx_gamma_itf_cfg.rx_eth_fcs_init_value  = 0xFFFFFFFF;
772     rx_gamma_itf_cfg.rx_tc_crc_init_value   = 0x0000FFFF;
773     rx_gamma_itf_cfg.rx_max_len_sel     = 0;
774     rx_gamma_itf_cfg.rx_edit_num2       = 0;
775     rx_gamma_itf_cfg.rx_edit_pos2       = 0;
776     rx_gamma_itf_cfg.rx_edit_type2      = 0;
777     rx_gamma_itf_cfg.rx_edit_en2        = 0;
778     rx_gamma_itf_cfg.rx_edit_num1       = 0;
779     rx_gamma_itf_cfg.rx_edit_pos1       = 0;
780     rx_gamma_itf_cfg.rx_edit_type1      = 0;
781     rx_gamma_itf_cfg.rx_edit_en1        = 0;
782     rx_gamma_itf_cfg.rx_inserted_bytes_1l   = 0;
783     rx_gamma_itf_cfg.rx_inserted_bytes_1h   = 0;
784     rx_gamma_itf_cfg.rx_inserted_bytes_2l   = 0;
785     rx_gamma_itf_cfg.rx_inserted_bytes_2h   = 0;
786     rx_gamma_itf_cfg.rx_len_adj         = -6;
787     for ( i = 0; i < 4; i++ )
788         *RX_GAMMA_ITF_CFG(i) = rx_gamma_itf_cfg;
789
790     tx_gamma_itf_cfg.tx_len_adj         = 6;
791     tx_gamma_itf_cfg.tx_crc_off_adj     = 6;
792     tx_gamma_itf_cfg.tx_min_len         = 0;
793     tx_gamma_itf_cfg.tx_eth_fcs_gen_dis = 0;
794     tx_gamma_itf_cfg.tx_tc_crc_size     = 1;
795     tx_gamma_itf_cfg.tx_crc_cfg         = 0x2F00;
796     tx_gamma_itf_cfg.tx_eth_fcs_init_value  = 0xFFFFFFFF;
797     tx_gamma_itf_cfg.tx_tc_crc_init_value   = 0x0000FFFF;
798     for ( i = 0; i < ARRAY_SIZE(g_queue_gamma_map); i++ ) {
799         tx_gamma_itf_cfg.queue_mapping = g_queue_gamma_map[i];
800         *TX_GAMMA_ITF_CFG(i) = tx_gamma_itf_cfg;
801     }
802
803     for ( i = 0; i < __ETH_WAN_TX_QUEUE_NUM; i++ ) {
804         wtx_qos_q_desc_cfg.length = WAN_TX_DESC_NUM;
805         wtx_qos_q_desc_cfg.addr   = __ETH_WAN_TX_DESC_BASE(i);
806         *WTX_QOS_Q_DESC_CFG(i) = wtx_qos_q_desc_cfg;
807     }
808
809     //  default TX queue QoS config is all ZERO
810
811     //  TX Ctrl K Table
812     IFX_REG_W32(0x90111293, TX_CTRL_K_TABLE(0));
813     IFX_REG_W32(0x14959617, TX_CTRL_K_TABLE(1));
814     IFX_REG_W32(0x18999A1B, TX_CTRL_K_TABLE(2));
815     IFX_REG_W32(0x9C1D1E9F, TX_CTRL_K_TABLE(3));
816     IFX_REG_W32(0xA02122A3, TX_CTRL_K_TABLE(4));
817     IFX_REG_W32(0x24A5A627, TX_CTRL_K_TABLE(5));
818     IFX_REG_W32(0x28A9AA2B, TX_CTRL_K_TABLE(6));
819     IFX_REG_W32(0xAC2D2EAF, TX_CTRL_K_TABLE(7));
820     IFX_REG_W32(0x30B1B233, TX_CTRL_K_TABLE(8));
821     IFX_REG_W32(0xB43536B7, TX_CTRL_K_TABLE(9));
822     IFX_REG_W32(0xB8393ABB, TX_CTRL_K_TABLE(10));
823     IFX_REG_W32(0x3CBDBE3F, TX_CTRL_K_TABLE(11));
824     IFX_REG_W32(0xC04142C3, TX_CTRL_K_TABLE(12));
825     IFX_REG_W32(0x44C5C647, TX_CTRL_K_TABLE(13));
826     IFX_REG_W32(0x48C9CA4B, TX_CTRL_K_TABLE(14));
827     IFX_REG_W32(0xCC4D4ECF, TX_CTRL_K_TABLE(15));
828
829     //  init RX descriptor
830     rx_desc.own     = 1;
831     rx_desc.c       = 0;
832     rx_desc.sop     = 1;
833     rx_desc.eop     = 1;
834     rx_desc.byteoff = RX_HEAD_MAC_ADDR_ALIGNMENT;
835     rx_desc.datalen = RX_MAX_BUFFER_SIZE - RX_HEAD_MAC_ADDR_ALIGNMENT;
836     for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
837         rx_desc.dataptr = (unsigned int)skb_pool[i]->data & 0x0FFFFFFF;
838         WAN_RX_DESC_BASE[i] = rx_desc;
839     }
840
841     //  init TX descriptor
842     tx_desc.own     = 0;
843     tx_desc.c       = 0;
844     tx_desc.sop     = 1;
845     tx_desc.eop     = 1;
846     tx_desc.byteoff = 0;
847     tx_desc.qid     = 0;
848     tx_desc.datalen = 0;
849     tx_desc.small   = 0;
850     tx_desc.dataptr = 0;
851     for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ )
852         CPU_TO_WAN_TX_DESC_BASE[i] = tx_desc;
853     for ( i = 0; i < WAN_TX_DESC_NUM_TOTAL; i++ )
854         WAN_TX_DESC_BASE(0)[i] = tx_desc;
855
856     //  init Swap descriptor
857     for ( i = 0; i < WAN_SWAP_DESC_NUM; i++ )
858         WAN_SWAP_DESC_BASE[i] = tx_desc;
859
860     //  init fastpath TX descriptor
861     tx_desc.own     = 1;
862     for ( i = 0; i < FASTPATH_TO_WAN_TX_DESC_NUM; i++ )
863         FASTPATH_TO_WAN_TX_DESC_BASE[i] = tx_desc;
864
865     return 0;
866
867 ALLOC_SKB_RX_FAIL:
868     while ( i-- > 0 )
869         dev_kfree_skb_any(skb_pool[i]);
870     return -1;
871 }
872
873 static inline void clear_tables(void)
874 {
875     struct sk_buff *skb;
876     int i, j;
877
878     for ( i = 0; i < WAN_RX_DESC_NUM; i++ ) {
879         skb = get_skb_pointer(WAN_RX_DESC_BASE[i].dataptr);
880         if ( skb != NULL )
881             dev_kfree_skb_any(skb);
882     }
883
884     for ( i = 0; i < CPU_TO_WAN_TX_DESC_NUM; i++ ) {
885         skb = get_skb_pointer(CPU_TO_WAN_TX_DESC_BASE[i].dataptr);
886         if ( skb != NULL )
887             dev_kfree_skb_any(skb);
888     }
889
890     for ( j = 0; j < 8; j++ )
891         for ( i = 0; i < WAN_TX_DESC_NUM; i++ ) {
892             skb = get_skb_pointer(WAN_TX_DESC_BASE(j)[i].dataptr);
893             if ( skb != NULL )
894                 dev_kfree_skb_any(skb);
895         }
896
897     for ( i = 0; i < WAN_SWAP_DESC_NUM; i++ ) {
898         skb = get_skb_pointer(WAN_SWAP_DESC_BASE[i].dataptr);
899         if ( skb != NULL )
900             dev_kfree_skb_any(skb);
901     }
902
903     for ( i = 0; i < FASTPATH_TO_WAN_TX_DESC_NUM; i++ ) {
904         skb = get_skb_pointer(FASTPATH_TO_WAN_TX_DESC_BASE[i].dataptr);
905         if ( skb != NULL )
906             dev_kfree_skb_any(skb);
907     }
908 }
909
910 static int ptm_showtime_enter(struct port_cell_info *port_cell, void *xdata_addr)
911 {
912         int i;
913
914         ASSERT(port_cell != NULL, "port_cell is NULL");
915         ASSERT(xdata_addr != NULL, "xdata_addr is NULL");
916
917         //  TODO: ReTX set xdata_addr
918         g_xdata_addr = xdata_addr;
919
920         g_showtime = 1;
921
922         for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
923                 netif_carrier_on(g_net_dev[i]);
924
925         IFX_REG_W32(0x0F, UTP_CFG);
926
927         //#ifdef CONFIG_VR9
928         //    IFX_REG_W32_MASK(1 << 17, 0, FFSM_CFG0);
929         //#endif
930
931         printk("enter showtime\n");
932
933         return 0;
934 }
935
936 static int ptm_showtime_exit(void)
937 {
938         int i;
939
940         if ( !g_showtime )
941                 return -1;
942
943         //#ifdef CONFIG_VR9
944         //    IFX_REG_W32_MASK(0, 1 << 17, FFSM_CFG0);
945         //#endif
946
947         IFX_REG_W32(0x00, UTP_CFG);
948
949         for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
950                 netif_carrier_off(g_net_dev[i]);
951
952         g_showtime = 0;
953
954         //  TODO: ReTX clean state
955         g_xdata_addr = NULL;
956
957         printk("leave showtime\n");
958
959         return 0;
960 }
961
962
963
964 static int ifx_ptm_init(void)
965 {
966     int ret;
967     int i;
968     char ver_str[128];
969     struct port_cell_info port_cell = {0};
970
971     ret = init_priv_data();
972     if ( ret != 0 ) {
973         err("INIT_PRIV_DATA_FAIL");
974         goto INIT_PRIV_DATA_FAIL;
975     }
976
977     ifx_ptm_init_chip();
978     ret = init_tables();
979     if ( ret != 0 ) {
980         err("INIT_TABLES_FAIL");
981         goto INIT_TABLES_FAIL;
982     }
983
984     for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
985         g_net_dev[i] = alloc_netdev(0, g_net_dev_name[i], NET_NAME_UNKNOWN, ether_setup);
986         if ( g_net_dev[i] == NULL )
987             goto ALLOC_NETDEV_FAIL;
988         ptm_setup(g_net_dev[i], i);
989     }
990
991     for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
992         ret = register_netdev(g_net_dev[i]);
993         if ( ret != 0 )
994             goto REGISTER_NETDEV_FAIL;
995     }
996
997     /*  register interrupt handler  */
998 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0)
999     ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, 0, "ptm_mailbox_isr", &g_ptm_priv_data);
1000 #else
1001     ret = request_irq(PPE_MAILBOX_IGU1_INT, mailbox_irq_handler, IRQF_DISABLED, "ptm_mailbox_isr", &g_ptm_priv_data);
1002 #endif
1003     if ( ret ) {
1004         if ( ret == -EBUSY ) {
1005             err("IRQ may be occupied by other driver, please reconfig to disable it.");
1006         }
1007         else {
1008             err("request_irq fail");
1009         }
1010         goto REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL;
1011     }
1012     disable_irq(PPE_MAILBOX_IGU1_INT);
1013
1014     ret = ifx_pp32_start(0);
1015     if ( ret ) {
1016         err("ifx_pp32_start fail!");
1017         goto PP32_START_FAIL;
1018     }
1019     IFX_REG_W32(1 << 16, MBOX_IGU1_IER);    //  enable SWAP interrupt
1020     IFX_REG_W32(~0, MBOX_IGU1_ISRC);
1021
1022     enable_irq(PPE_MAILBOX_IGU1_INT);
1023
1024     ifx_mei_atm_showtime_check(&g_showtime, &port_cell, &g_xdata_addr);
1025     
1026     ifx_mei_atm_showtime_enter = ptm_showtime_enter;
1027     ifx_mei_atm_showtime_exit  = ptm_showtime_exit;
1028
1029     ifx_ptm_version(ver_str);
1030     printk(KERN_INFO "%s", ver_str);
1031
1032     printk("ifxmips_ptm: PTM init succeed\n");
1033
1034     return 0;
1035
1036 PP32_START_FAIL:
1037     free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
1038 REQUEST_IRQ_PPE_MAILBOX_IGU1_INT_FAIL:
1039     i = ARRAY_SIZE(g_net_dev);
1040 REGISTER_NETDEV_FAIL:
1041     while ( i-- )
1042         unregister_netdev(g_net_dev[i]);
1043     i = ARRAY_SIZE(g_net_dev);
1044 ALLOC_NETDEV_FAIL:
1045     while ( i-- ) {
1046         free_netdev(g_net_dev[i]);
1047         g_net_dev[i] = NULL;
1048     }
1049 INIT_TABLES_FAIL:
1050 INIT_PRIV_DATA_FAIL:
1051     clear_priv_data();
1052     printk("ifxmips_ptm: PTM init failed\n");
1053     return ret;
1054 }
1055
1056 static void __exit ifx_ptm_exit(void)
1057 {
1058     int i;
1059         ifx_mei_atm_showtime_enter = NULL;
1060         ifx_mei_atm_showtime_exit  = NULL;
1061
1062
1063     ifx_pp32_stop(0);
1064
1065     free_irq(PPE_MAILBOX_IGU1_INT, &g_ptm_priv_data);
1066
1067     for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ )
1068         unregister_netdev(g_net_dev[i]);
1069
1070     for ( i = 0; i < ARRAY_SIZE(g_net_dev); i++ ) {
1071         free_netdev(g_net_dev[i]);
1072         g_net_dev[i] = NULL;
1073     }
1074
1075     clear_tables();
1076
1077     ifx_ptm_uninit_chip();
1078
1079     clear_priv_data();
1080 }
1081
1082 #ifndef MODULE
1083 static int __init wanqos_en_setup(char *line)
1084 {
1085     wanqos_en = simple_strtoul(line, NULL, 0);
1086
1087     if ( wanqos_en < 1 || wanqos_en > 8 )
1088         wanqos_en = 0;
1089
1090     return 0;
1091 }
1092
1093 static int __init queue_gamma_map_setup(char *line)
1094 {
1095     char *p;
1096     int i;
1097
1098     for ( i = 0, p = line; i < ARRAY_SIZE(queue_gamma_map) && isxdigit(*p); i++ )
1099     {
1100         queue_gamma_map[i] = simple_strtoul(p, &p, 0);
1101         if ( *p == ',' || *p == ';' || *p == ':' )
1102             p++;
1103     }
1104
1105     return 0;
1106 }
1107 #endif
1108 module_init(ifx_ptm_init);
1109 module_exit(ifx_ptm_exit);
1110 #ifndef MODULE
1111   __setup("wanqos_en=", wanqos_en_setup);
1112   __setup("queue_gamma_map=", queue_gamma_map_setup);
1113 #endif
1114
1115 MODULE_LICENSE("GPL");