945edec6beac5a7976bd53d0d37d63257d36e061
[librecmc/librecmc.git] / target / linux / cns3xxx / patches-2.6.31 / 205-cns3xxx_net_device_support.patch
1 --- /dev/null
2 +++ b/drivers/net/cns3xxx/cns3xxx_config.h
3 @@ -0,0 +1,136 @@
4 +/*******************************************************************************
5 + *
6 + *   Copyright (c) 2009 Cavium Networks 
7 + *
8 + *   This program is free software; you can redistribute it and/or modify it
9 + *   under the terms of the GNU General Public License as published by the Free
10 + *   Software Foundation; either version 2 of the License, or (at your option)
11 + *   any later version.
12 + *
13 + *   This program is distributed in the hope that it will be useful, but WITHOUT
14 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16 + *   more details.
17 + *
18 + *   You should have received a copy of the GNU General Public License along with
19 + *   this program; if not, write to the Free Software Foundation, Inc., 59
20 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 + *
22 + *   The full GNU General Public License is included in this distribution in the
23 + *   file called LICENSE.
24 + *
25 + ********************************************************************************/
26 +
27 +#include <linux/version.h>
28 +
29 +#ifndef CNS3XXX_CONFIG_H
30 +#define CNS3XXX_CONFIG_H
31 +
32 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
33 +#define LINUX2627 1
34 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
35 +#define LINUX2631 1
36 +#endif
37 +
38 +
39 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
40 +#define CNS3XXX_VLAN_8021Q
41 +#endif
42 +
43 +#ifdef CNS3XXX_VLAN_8021Q
44 +//#define CNS3XXX_NIC_MODE_8021Q // use NIC mode to support 8021Q
45 +
46 +#endif
47 +
48 +#define CONFIG_CNS3XXX_JUMBO_FRAME
49 +
50 +#ifdef CONFIG_CNS3XXX_JUMBO_FRAME
51 +#define MAX_PACKET_LEN 9600
52 +#else
53 +#define MAX_PACKET_LEN 1536
54 +#endif
55 +
56 +//#define CONFIG_SWITCH_BIG_ENDIAN
57 +
58 +//#define CONFIG_FPGA_FORCE
59 +
60 +//#define CNS3XXX_GIGA_MODE
61 +
62 +#define CNS3XXX_SET_ARL_TABLE
63 +#define CNS3XXX_AGE_ENABLE
64 +#define CNS3XXX_LEARN_ENABLE
65 +#define CNS3XXX_CPU_PORT_FC
66 +#define CNS3XXX_CPU_MIB_COUNTER
67 +#define CNS3XXX_MAC0_MIB_COUNTER
68 +#define CNS3XXX_MAC1_MIB_COUNTER
69 +//#define CNS3XXX_MAC2_MIB_COUNTER
70 +//#define QOS_TEST
71 +//#define ACCEPT_CRC_BAD_PKT
72 +//#define CONFIG_FAST_BRIDGE
73 +//#define CONFIG_HOLP_TEST
74 +
75 +
76 +#define CONFIG_CNS3XXX_NAPI
77 +#ifdef CONFIG_CNS3XXX_NAPI
78 +#define CNS3XXX_NAPI_WEIGHT 64
79 +#endif
80 +//#define CONFIG_NIC_MODE
81 +//#define CNS3XXX_TX_HW_CHECKSUM
82 +//#define CNS3XXX_RX_HW_CHECKSUM
83 +//#define CNS3XXX_STATUS_ISR
84 +//#define CNS3XXX_TEST_ONE_LEG_VLAN
85 +//#define CNS3XXX_TX_DSCP_PROC
86 +
87 +
88 +#define CNS3XXX_FSQF_RING0_ISR
89 +//#define CNS3XXX_TSTC_RING0_ISR
90 +//#define CNS3XXX_TSTC_RING1_ISR
91 +
92 +//#define CNS3XXX_COMPARE_PACKET
93 +//#define CONFIG_FPGA_10
94 +//#define CNS3XXX_CONFIG_SIM_MODE
95 +
96 +#define CNS3XXX_8021Q_HW_TX
97 +
98 +
99 +#ifndef CONFIG_CNS3XXX_SPPE
100 +#define IVL // if no define, use SVL
101 +#endif
102 +//#define CNS3XXX_4N // if don't define it, use 4N+2
103 +
104 +//#define NCNB_TEST
105 +//#define CNS3XXX_TEST_D_CACHE
106 +#define CNS3XXX_FREE_TX_IN_RX_PATH
107 +
108 +
109 +//#define DEBUG_RX
110 +//#define DEBUG_TX
111 +//#define DEBUG_PRIO_IPDSCR
112 +#define DEBUG_RX_PROC
113 +#define DEBUG_TX_PROC
114 +//#define DEBUG_PHY_PROC
115 +#define CNS3XXX_PVID_PROC
116 +#define CNS3XXX_SARL_PROC
117 +
118 +
119 +//#define DOUBLE_RING_TEST
120 +
121 +//#define CNS3XXX_DOUBLE_RX_RING
122 +//#define CNS3XXX_DOUBLE_TX_RING
123 +#define CNS3XXX_USE_MASK
124 +
125 +#define CNS3XXX_CONFIG_CHANGE_TX_RING
126 +
127 +#ifdef CNS3XXX_DOUBLE_RX_RING
128 +#define CNS3XXX_FSQF_RING1_ISR
129 +#endif
130 +
131 +//#define CNS3XXX_DELAYED_INTERRUPT
132 +
133 +#ifdef CNS3XXX_DELAYED_INTERRUPT
134 +#define MAX_PEND_INT_CNT 0x06
135 +#define MAX_PEND_TIME 0x20
136 +#endif
137 +
138 +//#define CNS3XXX_ENABLE_RINT1
139 +#endif
140 --- /dev/null
141 +++ b/drivers/net/cns3xxx/cns3xxx_ethtool.c
142 @@ -0,0 +1,436 @@
143 +/*******************************************************************************
144 + *
145 + *
146 + *   Copyright (c) 2009 Cavium Networks 
147 + *
148 + *   This program is free software; you can redistribute it and/or modify it
149 + *   under the terms of the GNU General Public License as published by the Free
150 + *   Software Foundation; either version 2 of the License, or (at your option)
151 + *   any later version.
152 + *
153 + *   This program is distributed in the hope that it will be useful, but WITHOUT
154 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
155 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
156 + *   more details.
157 + *
158 + *   You should have received a copy of the GNU General Public License along with
159 + *   this program; if not, write to the Free Software Foundation, Inc., 59
160 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
161 + *
162 + *   The full GNU General Public License is included in this distribution in the
163 + *   file called LICENSE.
164 + *
165 + ********************************************************************************/
166 +
167 +//#include <linux/module.h>
168 +#include <linux/types.h>
169 +#include <linux/ethtool.h>
170 +#include <linux/netdevice.h>
171 +#include "cns3xxx_symbol.h"
172 +#include "cns3xxx.h"
173 +#include "cns3xxx_tool.h"
174 +
175 +// ethtool support reference e100.c and e1000_ethtool.c .
176 +static void cns3xxx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
177 +{
178 +       strcpy(info->driver, "cns3xxx");
179 +        strcpy(info->version, DRV_VERSION);
180 +        strcpy(info->fw_version, "N/A");
181 +        strcpy(info->bus_info, "N/A");
182 +}
183 +
184 +static void cns3xxx_get_ringparam(struct net_device *netdev,
185 +        struct ethtool_ringparam *ring)
186 +{
187 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
188 +
189 +        ring->rx_max_pending = priv->rx_ring->max_ring_size;
190 +        ring->tx_max_pending = priv->tx_ring->max_ring_size;
191 +        ring->rx_pending = priv->rx_ring->ring_size;
192 +        ring->tx_pending = priv->tx_ring->ring_size;
193 +#if 0
194 +        struct nic *nic = netdev_priv(netdev);
195 +        struct param_range *rfds = &nic->params.rfds;
196 +        struct param_range *cbs = &nic->params.cbs;
197 +
198 +        ring->rx_max_pending = rfds->max;
199 +        ring->tx_max_pending = cbs->max;
200 +        ring->rx_mini_max_pending = 0;
201 +        ring->rx_jumbo_max_pending = 0;
202 +        ring->rx_pending = rfds->count;
203 +        ring->tx_pending = cbs->count;
204 +        ring->rx_mini_pending = 0;
205 +        ring->rx_jumbo_pending = 0;
206 +#endif
207 +}
208 +
209 +
210 +
211 +static int cns3xxx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
212 +{
213 +       int cns3xxx_up(void);
214 +       int cns3xxx_down(void);
215 +       int cns3xxx_close(struct net_device *dev);
216 +       int cns3xxx_open(struct net_device *dev);
217 +       extern struct net_device *net_dev_array[];
218 +
219 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
220 +
221 +       int i=0;
222 +
223 +#if 0
224 +        struct nic *nic = netdev_priv(netdev);
225 +        struct param_range *rfds = &nic->params.rfds;
226 +        struct param_range *cbs = &nic->params.cbs;
227 +
228 +        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
229 +                return -EINVAL;
230 +
231 +        if(netif_running(netdev))
232 +                e100_down(nic);
233 +        rfds->count = max(ring->rx_pending, rfds->min);
234 +        rfds->count = min(rfds->count, rfds->max);
235 +        cbs->count = max(ring->tx_pending, cbs->min);
236 +        cbs->count = min(cbs->count, cbs->max);
237 +        DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n",
238 +                rfds->count, cbs->count);
239 +        if(netif_running(netdev))
240 +                e100_up(nic);
241 +
242 +#endif
243 +        //ring->rx_max_pending = RX_DESC_SIZE;
244 +        //ring->tx_max_pending = TX_DESC_SIZE;
245 +
246 +#if 0
247 +       printk("ring->rx_max_pending: %d\n", ring->rx_max_pending);
248 +       printk("ring->tx_max_pending: %d\n", ring->tx_max_pending);
249 +       printk("ring->rx_pending: %d\n", ring->rx_pending);
250 +       printk("ring->tx_pending: %d\n", ring->tx_pending);
251 +#endif
252 +
253 +       for (i=0 ; i < NETDEV_SIZE ; ++i) {
254 +               if(net_dev_array[i] && netif_running(net_dev_array[i])) {
255 +                       //printk("close net_dev_array[%d]: %s\n", i, net_dev_array[i]);
256 +                       cns3xxx_close(net_dev_array[i]);
257 +               }
258 +       }
259 +
260 +                //cns3xxx_down();
261 +
262 +        priv->rx_ring->ring_size = min(ring->rx_pending, priv->rx_ring->max_ring_size);
263 +        priv->tx_ring->ring_size = min(ring->rx_pending, priv->tx_ring->max_ring_size);
264 +
265 +       for (i=0 ; i < NETDEV_SIZE ; ++i) {
266 +               if(net_dev_array[i] && netif_running(net_dev_array[i])) {
267 +                       //printk("open net_dev_array[%d]: %s\n", i, net_dev_array[i]);
268 +                       cns3xxx_open(net_dev_array[i]);
269 +               }
270 +       }
271 +                //cns3xxx_up();
272 +
273 +        return 0;
274 +}
275 +
276 +static uint32_t cns3xxx_get_tx_csum(struct net_device *netdev)
277 +{
278 +        //return (netdev->features & NETIF_F_HW_CSUM) != 0;
279 +        return (netdev->features & NETIF_F_IP_CSUM) != 0;
280 +}
281 +
282 +static int cns3xxx_set_tx_csum(struct net_device *netdev, uint32_t data)
283 +{
284 +       if (data)
285 +                netdev->features |= NETIF_F_IP_CSUM;
286 +        else
287 +                netdev->features &= ~NETIF_F_IP_CSUM;
288 +       return 0;
289 +}
290 +
291 +static uint32_t cns3xxx_get_rx_csum(struct net_device *netdev)
292 +{
293 +        //struct e1000_adapter *adapter = netdev_priv(netdev);
294 +        //return adapter->rx_csum;
295 +       return 1;
296 +}
297 +
298 +static int cns3xxx_set_rx_csum(struct net_device *netdev, uint32_t data)
299 +{
300 +       return 0;
301 +}
302 +
303 +u32 cns3xxx_get_sg(struct net_device *dev)
304 +{
305 +#ifdef NETIF_F_SG
306 +        return (dev->features & NETIF_F_SG) != 0;
307 +#else
308 +        return 0;
309 +#endif
310 +}
311 +
312 +int cns3xxx_set_sg(struct net_device *dev, u32 data)
313 +{
314 +#ifdef NETIF_F_SG 
315 +        if (data)
316 +                dev->features |= NETIF_F_SG;
317 +        else
318 +                dev->features &= ~NETIF_F_SG;
319 +#endif
320 +
321 +        return 0;
322 +}
323 +
324 +static void cns3xxx_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
325 +{
326 +        u32 mac_port_config = 0;
327 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
328 +
329 +       switch (priv->net_device_priv->which_port)
330 +       {
331 +               case MAC_PORT0:
332 +               {
333 +                       mac_port_config = MAC0_CFG_REG;
334 +                       break;
335 +               }
336 +               case MAC_PORT1:
337 +               {
338 +                       mac_port_config = MAC1_CFG_REG;
339 +                       break;
340 +               }
341 +               case MAC_PORT2:
342 +               {
343 +                       mac_port_config = MAC2_CFG_REG;
344 +                       break;
345 +               }
346 +       }
347 +
348 +
349 +        pause->autoneg = ( ((mac_port_config >> 7) & 1) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
350 +       pause->tx_pause = (mac_port_config >> 6) & 1;
351 +       pause->rx_pause = (mac_port_config >> 5) & 1;
352 +}
353 +
354 +static int cns3xxx_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
355 +{
356 +        u32 mac_port_config = 0;
357 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
358 +
359 +       switch (priv->net_device_priv->which_port)
360 +       {
361 +               case MAC_PORT0:
362 +               {
363 +                       mac_port_config = MAC0_CFG_REG;
364 +                       break;
365 +               }
366 +               case MAC_PORT1:
367 +               {
368 +                       mac_port_config = MAC1_CFG_REG;
369 +                       break;
370 +               }
371 +               case MAC_PORT2:
372 +               {
373 +                       mac_port_config = MAC2_CFG_REG;
374 +                       break;
375 +               }
376 +       }
377 +
378 +
379 +       mac_port_config &= ~(0x1 << 7); // clean AN
380 +       mac_port_config &= ~(0x1 << 11); // clean rx flow control
381 +       mac_port_config &= ~(0x1 << 12); // clean tx flow control
382 +
383 +       mac_port_config |= ( (pause->autoneg << 7) | (pause->rx_pause << 11) | (pause->tx_pause << 12) );
384 +
385 +
386 +       switch (priv->net_device_priv->which_port)
387 +       {
388 +               case MAC_PORT0:
389 +               {
390 +                       MAC0_CFG_REG  = mac_port_config;
391 +                       break;
392 +               }
393 +               case MAC_PORT1:
394 +               {
395 +                       MAC1_CFG_REG  = mac_port_config;
396 +                       break;
397 +               }
398 +               case MAC_PORT2:
399 +               {
400 +                       MAC2_CFG_REG  = mac_port_config;
401 +                       break;
402 +               }
403 +       }
404 +       return 0;
405 +}
406 +
407 +u32 cns3xxx_get_link(struct net_device *netdev)
408 +{
409 +        u32 mac_port_config = 0;
410 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
411 +
412 +       switch (priv->net_device_priv->which_port)
413 +       {
414 +               case MAC_PORT0:
415 +               {
416 +                       mac_port_config = MAC0_CFG_REG;
417 +                       break;
418 +               }
419 +               case MAC_PORT1:
420 +               {
421 +                       mac_port_config = MAC1_CFG_REG;
422 +                       break;
423 +               }
424 +               case MAC_PORT2:
425 +               {
426 +                       mac_port_config = MAC2_CFG_REG;
427 +                       break;
428 +               }
429 +       }
430 +
431 +        return (mac_port_config & 1 ) ? 1 : 0;
432 +        //return netif_carrier_ok(dev) ? 1 : 0;
433 +}
434 +
435 +
436 +static int cns3xxx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
437 +{
438 +       u8 value;
439 +        u32 mac_port_config = 0;
440 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
441 +
442 +
443 +       if (priv->net_device_priv->nic_setting == 0) { // connect to switch chip
444 +
445 +               GET_MAC_PORT_CFG(priv->net_device_priv->which_port, mac_port_config)
446 +
447 +               ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full| SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_Pause);
448 +       
449 +               ecmd->duplex = ((mac_port_config >> 4) & 0x1) ? DUPLEX_FULL : DUPLEX_HALF ;
450 +       
451 +               value = ((mac_port_config >> 2) & 0x3);
452 +               switch (value)
453 +               {
454 +                       case 0:
455 +                               ecmd->speed = SPEED_10;
456 +                               break;
457 +                       case 1:
458 +                               ecmd->speed = SPEED_100;
459 +                               break;
460 +                       case 2:
461 +                               ecmd->speed = SPEED_1000;
462 +                               break;
463 +               }
464 +       
465 +               ecmd->autoneg = ((mac_port_config >> 7) & 1) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
466 +
467 +
468 +
469 +       } else { // connect to PHY chip
470 +
471 +       }
472 +
473 +       return 0;
474 +}
475 +
476 +// set speed and duplex
477 +int cns3xxx_set_spd_dplx(struct net_device *netdev, u16 spddplx)
478 +{
479 +        u32 mac_port_config = 0;
480 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
481 +
482 +       GET_MAC_PORT_CFG(priv->net_device_priv->which_port, mac_port_config)
483 +
484 +       //printk("mac_port_config: %x\n", mac_port_config);
485 +
486 +       mac_port_config &= ~(0x3 << 8); // clear speed
487 +       mac_port_config &= ~(0x1 << 10); // clear duplex
488 +       mac_port_config &= ~(0x1 << 7); // disable AN
489 +
490 +        switch (spddplx) {
491 +        case AUTONEG_ENABLE:
492 +               mac_port_config |= (0x1 << 7); // enable AN
493 +                break;
494 +        case SPEED_10 + DUPLEX_HALF:
495 +               printk("10, halt\n");
496 +                mac_port_config |= (0 << 8);    // set speed
497 +                mac_port_config |= (0 << 10);    // set duplex
498 +               //printk("xxx mac_port_config: %x\n", mac_port_config);
499 +                break;
500 +        case SPEED_10 + DUPLEX_FULL:
501 +                mac_port_config |= (0 << 8);    // set speed
502 +                mac_port_config |= (1 << 10);    // set duplex
503 +                break;
504 +        case SPEED_100 + DUPLEX_HALF:
505 +                mac_port_config |= (1 << 8);    // set speed
506 +                mac_port_config |= (0 << 10);    // set duplex
507 +                break;
508 +        case SPEED_100 + DUPLEX_FULL:
509 +                mac_port_config |= (1 << 8);    // set speed
510 +                mac_port_config |= (1 << 10);    // set duplex
511 +                break;
512 +        case SPEED_1000 + DUPLEX_HALF: 
513 +                mac_port_config |= (2 << 8);    // set speed
514 +                mac_port_config |= (0 << 10);    // set duplex
515 +                break;
516 +        case SPEED_1000 + DUPLEX_FULL:
517 +                mac_port_config |= (2 << 8);    // set speed
518 +                mac_port_config |= (1 << 10);    // set duplex
519 +                break;
520 +        default:
521 +                //printk("Unsupported Speed/Duplex configuration\n");
522 +                return -EINVAL;
523 +       }
524 +
525 +       SET_MAC_PORT_CFG(priv->net_device_priv->which_port, mac_port_config)
526 +
527 +       return 0;
528 +}
529 +
530 +static int cns3xxx_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
531 +{
532 +       u8 value = 0;
533 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
534 +
535 +       if (priv->net_device_priv->nic_setting == 0) { // connect to switch chip
536 +               if (ecmd->autoneg == AUTONEG_ENABLE) {
537 +                       printk("autoneg\n");
538 +                       if ((value=cns3xxx_set_spd_dplx(netdev, AUTONEG_ENABLE)) != 0) {
539 +                               return -EINVAL;
540 +                       } 
541 +               } else {
542 +                       printk("no autoneg\n");
543 +                       if ((value=cns3xxx_set_spd_dplx(netdev, ecmd->speed + ecmd->duplex)) != 0) {
544 +                               return -EINVAL;
545 +                       } 
546 +
547 +
548 +               }
549 +
550 +       } else { // connect to PHY chip 
551 +
552 +       }
553 +
554 +       // down then up
555 +       return 0;
556 +}
557 +
558 +static const struct ethtool_ops cns3xxx_ethtool_ops = {
559 +       .get_drvinfo            = cns3xxx_get_drvinfo,
560 +        .get_ringparam          = cns3xxx_get_ringparam,
561 +        .set_ringparam          = cns3xxx_set_ringparam,
562 +        .get_rx_csum            = cns3xxx_get_rx_csum,
563 +        .set_rx_csum            = cns3xxx_set_rx_csum,
564 +        .get_tx_csum            = cns3xxx_get_tx_csum,
565 +        .set_tx_csum            = cns3xxx_set_tx_csum,
566 +        .get_sg                = cns3xxx_get_sg,
567 +        .set_sg                 = cns3xxx_set_sg,
568 +        .get_pauseparam         = cns3xxx_get_pauseparam,
569 +        .set_pauseparam         = cns3xxx_set_pauseparam,
570 +        .get_link               = cns3xxx_get_link,
571 +        .get_settings           = cns3xxx_get_settings,
572 +        .set_settings           = cns3xxx_set_settings,
573 +};
574 +
575 +void cns3xxx_set_ethtool_ops(struct net_device *netdev)
576 +{
577 +       SET_ETHTOOL_OPS(netdev, &cns3xxx_ethtool_ops);
578 +}
579 --- /dev/null
580 +++ b/drivers/net/cns3xxx/cns3xxx.h
581 @@ -0,0 +1,452 @@
582 +/*******************************************************************************
583 + *
584 + *   Copyright (c) 2009 Cavium Networks 
585 + *
586 + *   This program is free software; you can redistribute it and/or modify it
587 + *   under the terms of the GNU General Public License as published by the Free
588 + *   Software Foundation; either version 2 of the License, or (at your option)
589 + *   any later version.
590 + *
591 + *   This program is distributed in the hope that it will be useful, but WITHOUT
592 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
593 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
594 + *   more details.
595 + *
596 + *   You should have received a copy of the GNU General Public License along with
597 + *   this program; if not, write to the Free Software Foundation, Inc., 59
598 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
599 + *
600 + *   The full GNU General Public License is included in this distribution in the
601 + *   file called LICENSE.
602 + *
603 + ********************************************************************************/
604 +
605 +#ifndef CNS3XXX_H
606 +#define CNS3XXX_H
607 +
608 +#include "cns3xxx_symbol.h"
609 +#include "cns3xxx_config.h"
610 +#include <linux/cns3xxx/switch_api.h>
611 +
612 +#include <linux/module.h>
613 +#include <linux/init.h>
614 +#include <linux/kernel.h>
615 +#include <linux/bootmem.h>
616 +#include <linux/sched.h>
617 +#include <linux/types.h>
618 +#include <linux/fcntl.h>
619 +#include <linux/interrupt.h>
620 +#include <linux/ptrace.h>
621 +#include <linux/ioport.h>
622 +#include <linux/in.h>
623 +#include <linux/slab.h>
624 +#include <linux/init.h>
625 +#include <linux/proc_fs.h>
626 +#include <linux/reboot.h>
627 +#include <asm/bitops.h>
628 +#include <asm/irq.h>
629 +#include <asm/io.h>
630 +//#include <asm/hardware.h>
631 +#include <linux/pci.h>
632 +#include <linux/errno.h>
633 +#include <linux/delay.h>
634 +#include <linux/netdevice.h>
635 +#include <linux/etherdevice.h>
636 +#include <linux/skbuff.h>
637 +#include <linux/ip.h>
638 +#include <linux/if_ether.h>
639 +#include <linux/icmp.h>
640 +#include <linux/udp.h>
641 +#include <linux/tcp.h>
642 +#include <linux/if_arp.h>
643 +#include <net/arp.h>
644 +
645 +
646 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
647 +#include <linux/if_vlan.h>
648 +#endif
649 +
650 +//#define VERSION "1.0"
651 +
652 +
653 +typedef struct
654 +{
655 +       int32_t sdp; // segment data pointer
656 +
657 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
658 +       u32 cown:1;
659 +       u32 eor:1;
660 +       u32 fsd:1;
661 +       u32 lsd:1;
662 +       u32 interrupt:1;
663 +       u32 fr:1;
664 +       u32 fp:1; // force priority
665 +       u32 pri:3;
666 +       u32 rsv_1:3; // reserve
667 +       u32 ico:1;
668 +       u32 uco:1;
669 +       u32 tco:1;
670 +       u32 sdl:16; // segment data length
671 +
672 +#else
673 +       u32 sdl:16; // segment data length
674 +       u32 tco:1;
675 +       u32 uco:1;
676 +       u32 ico:1;
677 +       u32 rsv_1:3; // reserve
678 +       u32 pri:3;
679 +       u32 fp:1; // force priority
680 +       u32 fr:1;
681 +       u32 interrupt:1;
682 +       u32 lsd:1;
683 +       u32 fsd:1;
684 +       u32 eor:1;
685 +       u32 cown:1;
686 +#endif
687 +
688 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
689 +       u32 rsv_3:5;
690 +       u32 fewan:1;
691 +       u32 ewan:1;
692 +       u32 mark:3;
693 +       u32 pmap:5;
694 +       u32 rsv_2:9;
695 +       u32 dels:1;
696 +       u32 inss:1;
697 +       u32 sid:4;
698 +       u32 stv:1;
699 +       u32 ctv:1;
700 +#else
701 +       u32 ctv:1;
702 +       u32 stv:1;
703 +       u32 sid:4;
704 +       u32 inss:1;
705 +       u32 dels:1;
706 +       u32 rsv_2:9;
707 +       u32 pmap:5;
708 +       u32 mark:3;
709 +       u32 ewan:1;
710 +       u32 fewan:1;
711 +       u32 rsv_3:5;
712 +#endif
713 +
714 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
715 +       u32 s_pri:3;
716 +       u32 s_dei:1;
717 +       u32 s_vid:12;
718 +       u32 c_pri:3;
719 +       u32 c_cfs:1;
720 +       u32 c_vid:12;
721 +#else
722 +       u32 c_vid:12;
723 +       u32 c_cfs:1;
724 +       u32 c_pri:3;
725 +       u32 s_vid:12;
726 +       u32 s_dei:1;
727 +       u32 s_pri:3;
728 +#endif
729 +
730 +       u8 alignment[16]; // for alignment 32 byte
731 +
732 +} __attribute__((packed)) TXDesc;
733 +
734 +typedef struct
735 +{
736 +       u32 sdp;
737 +
738 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
739 +       u32 cown:1;
740 +       u32 eor:1;
741 +       u32 fsd:1;
742 +       u32 lsd:1;
743 +       u32 hr :6;
744 +       u32 prot:4;
745 +       u32 ipf:1;
746 +       u32 l4f:1;
747 +       u32 sdl:16;
748 +#else
749 +       u32 sdl:16;
750 +       u32 l4f:1;
751 +       u32 ipf:1;
752 +       u32 prot:4;
753 +       u32 hr :6;
754 +       u32 lsd:1;
755 +       u32 fsd:1;
756 +       u32 eor:1;
757 +       u32 cown:1;
758 +#endif
759 +
760 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
761 +       u32 rsv_3:11;
762 +       u32 ip_offset:5;
763 +       u32 rsv_2:1;
764 +       u32 tc:2;
765 +       u32 un_eth:1;
766 +       u32 crc_err:1;
767 +       u32 sp:3;
768 +       u32 rsv_1:2;
769 +       u32 e_wan:1;
770 +       u32 exdv:1;
771 +       u32 iwan:1;
772 +       u32 unv:1;
773 +       u32 stv:1;
774 +       u32 ctv:1;
775 +#else
776 +       u32 ctv:1;
777 +       u32 stv:1;
778 +       u32 unv:1;
779 +       u32 iwan:1;
780 +       u32 exdv:1;
781 +       u32 e_wan:1;
782 +       u32 rsv_1:2;
783 +       u32 sp:3;
784 +       u32 crc_err:1;
785 +       u32 un_eth:1;
786 +       u32 tc:2;
787 +       u32 rsv_2:1;
788 +       u32 ip_offset:5;
789 +       u32 rsv_3:11;
790 +#endif
791 +
792 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
793 +       u32 s_pri:3;
794 +       u32 s_dei:1;
795 +       u32 s_vid:12;
796 +       u32 c_pri:3;
797 +       u32 c_cfs:1;
798 +       u32 c_vid:12;
799 +#else
800 +       u32 c_vid:12;
801 +       u32 c_cfs:1;
802 +       u32 c_pri:3;
803 +       u32 s_vid:12;
804 +       u32 s_dei:1;
805 +       u32 s_pri:3;
806 +#endif
807 +
808 +       u8 alignment[16]; // for alignment 32 byte
809 +
810 +} __attribute__((packed)) RXDesc;
811 +
812 +typedef struct {
813 +       TXDesc *tx_desc;
814 +       struct sk_buff *skb; // for free skb
815 +       u32 pri;
816 +       unsigned long j;
817 +       unsigned long tx_index;
818 +}TXBuffer;
819 +
820 +typedef struct {
821 +       RXDesc *rx_desc;
822 +       struct sk_buff *skb; // rx path need to fill some skb field, ex: length ...
823 +#ifdef NCNB_TEST
824 +       u32 ncnb_index;
825 +#endif
826 +}RXBuffer;
827 +
828 +
829 +typedef struct {
830 +       TXBuffer *head; 
831 +       TXDesc *tx_desc_head_vir_addr;
832 +       dma_addr_t tx_desc_head_phy_addr;
833 +       u32 cur_index; // for put send packet
834 +       spinlock_t tx_lock;
835 +       u32 non_free_tx_skb;
836 +       u32 free_tx_skb_index;
837 +       u32 ring_size;
838 +       u32 max_ring_size;
839 +}TXRing;
840 +
841 +
842 +typedef struct {
843 +       RXBuffer *head;
844 +       RXDesc *rx_desc_head_vir_addr;
845 +       dma_addr_t rx_desc_head_phy_addr;
846 +       u32 cur_index;
847 +       u32 ring_size;
848 +       u32 max_ring_size;
849 +}RXRing;
850 +
851 +#if 0
852 +typedef struct 
853 +{
854 +        CNS3XXXIoctlCmd cmd;
855 +        TXRing *tx_ring;
856 +        RXRing *rx_ring;
857 +}CNS3XXXRingStatus;
858 +#endif
859 +
860 +
861 +#define RX_RING0(priv) (priv->rx_ring[0])
862 +#define TX_RING0(priv) (priv->tx_ring[0])
863 +
864 +
865 +static inline u32 get_rx_ring_size(const RXRing *ring)
866 +{
867 +       //printk("rx ring->ring_size: %d\n", ring->ring_size);
868 +       return ring->ring_size;
869 +}
870 +
871 +static inline u32 get_tx_ring_size(TXRing *ring)
872 +{
873 +       //printk("tx ring->ring_size: %d\n", ring->ring_size);
874 +       return ring->ring_size;
875 +}
876 +
877 +static inline RXBuffer *get_rx_ring_head(const RXRing *rx_ring)
878 +{
879 +       return rx_ring->head;
880 +}
881 +
882 +static inline TXBuffer *get_tx_ring_head(TXRing *tx_ring)
883 +{
884 +       return tx_ring->head;
885 +}
886 +
887 +static inline RXBuffer *get_cur_rx_buffer(RXRing *rx_ring)
888 +{
889 +       return rx_ring->head + rx_ring->cur_index;
890 +}
891 +
892 +static inline TXBuffer *get_cur_tx_buffer(TXRing *tx_ring)
893 +{
894 +       return tx_ring->head + tx_ring->cur_index;
895 +}
896 +
897 +static inline u32 get_rx_head_phy_addr(RXRing *rx_ring)
898 +{
899 +       return rx_ring->rx_desc_head_phy_addr;
900 +}
901 +
902 +static inline u32 get_tx_ring_head_phy_addr(TXRing *tx_ring)
903 +{
904 +       return tx_ring->tx_desc_head_phy_addr;
905 +}
906 +
907 +
908 +static inline u32 get_rx_cur_index(RXRing *rx_ring)
909 +{
910 +       return rx_ring->cur_index;
911 +}
912 +
913 +static inline u32 get_tx_cur_index(TXRing *tx_ring)
914 +{
915 +       return tx_ring->cur_index;
916 +}
917 +
918 +static inline u32 get_tx_cur_phy_addr(u8 ring_num)
919 +{
920 +       if (ring_num == 0)
921 +               return TS_DESC_PTR0_REG;        
922 +       if (ring_num == 1)
923 +               return TS_DESC_PTR1_REG;        
924 +       return 0; // fail
925 +}
926 +
927 +static inline void rx_index_next(RXRing *ring)
928 +{ 
929 +        ring->cur_index = ((ring->cur_index + 1) % ring->ring_size);
930 +}  
931 +static inline void tx_index_next(TXRing *ring)
932 +{ 
933 +        ring->cur_index = ((ring->cur_index + 1) % ring->ring_size);
934 +}
935 +
936 +
937 +
938 +struct CNS3XXXPrivate_;
939 +
940 +typedef int (*RXFuncPtr)(struct sk_buff *skb, RXDesc*tx_desc_ptr, const struct CNS3XXXPrivate_* );
941 +typedef int (*TXFuncPtr)(TXDesc*tx_desc_ptr, const struct CNS3XXXPrivate_*, struct sk_buff *);
942 +typedef void (*OpenPtr)(void);
943 +typedef void (*ClosePtr)(void);
944 +
945 +
946 +// for ethtool set operate
947 +typedef struct{
948 +
949 +}NICSetting;
950 +
951 +typedef struct{
952 +       int pmap; // for port base, force route
953 +       int is_wan; // mean the net device is WAN side.
954 +       //u16 gid;
955 +       u16 s_tag;
956 +       //u8 mac_type; // VLAN base, or port base;
957 +       u16 vlan_tag;
958 +
959 +       // do port base mode and vlan base mode work
960 +       RXFuncPtr rx_func;
961 +       TXFuncPtr tx_func;
962 +       OpenPtr open;
963 +       ClosePtr close;
964 +       u8 which_port;
965 +       //NICSetting *nic_setting;
966 +       u8 *mac; // point to a mac address array
967 +       VLANTableEntry *vlan_table_entry;
968 +       ARLTableEntry *arl_table_entry;
969 +        NICSetting *nic_setting;
970 +       const char *name; // 16 bytes, reference include/linux/netdevice.h IFNAMSIZ
971 +}NetDevicePriv;
972 +
973 +typedef struct
974 +{
975 +        u8 num_rx_queues;
976 +        u8 num_tx_queues;
977 +        TXRing *tx_ring;
978 +        RXRing *rx_ring;
979 +}RingInfo;
980 +
981 +
982 +/* store this information for the driver.. */
983 +typedef struct CNS3XXXPrivate_
984 +{
985 +       u8 num_rx_queues;
986 +       u8 num_tx_queues;
987 +       TXRing *tx_ring;
988 +       RXRing *rx_ring;
989 +       struct net_device_stats stats;
990 +       spinlock_t lock;
991 +       int pmap;
992 +       int is_wan; // mean the net device is WAN side.
993 +       u16 gid;
994 +       u8 mac_type; // VLAN base, or port base;
995 +       u16 vlan_tag;
996 +       struct napi_struct napi;
997 +        struct work_struct reset_task;
998 +
999 +       u8 which_port;
1000 +       //NICSetting *nic_setting;
1001 +       char name[IFNAMSIZ]; // 16 bytes, reference include/linux/netdevice.h IFNAMSIZ
1002 +       
1003 +
1004 +       NetDevicePriv *net_device_priv;
1005 +       u8 ring_index;
1006 +
1007 +       u32 rx_s_vid[4096]; // record receive s vid (0x9100 ...)
1008 +       u32 rx_c_vid[4096]; // record receive c vid (0x8100 ...)
1009 +#ifdef CONFIG_CNS3XXX_NAPI
1010 +       volatile unsigned long is_qf; // determine rx ring queue full state
1011 +#endif
1012 +       
1013 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1014 +        struct vlan_group               *vlgrp;
1015 +#endif
1016 +}CNS3XXXPrivate;
1017 +
1018 +
1019 +
1020 +
1021 +int rx_port_base(struct sk_buff *skb, RXDesc *rx_desc_ptr, const struct CNS3XXXPrivate_ *priv);
1022 +
1023 +int rx_vlan_base(struct sk_buff *skb, RXDesc *rx_desc_ptr, const struct CNS3XXXPrivate_ *priv);
1024 +
1025 +int tx_port_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb);
1026 +
1027 +
1028 +int tx_vlan_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb);
1029 +#if defined (CONFIG_CNS3XXX_SPPE)
1030 +int fp_port_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb);
1031 +#endif
1032 +#endif
1033 +
1034 --- /dev/null
1035 +++ b/drivers/net/cns3xxx/cns3xxx_main.c
1036 @@ -0,0 +1,3949 @@
1037 +/*******************************************************************************
1038 + *
1039 + *   Copyright (c) 2009 Cavium Networks 
1040 + *
1041 + *   This program is free software; you can redistribute it and/or modify it
1042 + *   under the terms of the GNU General Public License as published by the Free
1043 + *   Software Foundation; either version 2 of the License, or (at your option)
1044 + *   any later version.
1045 + *
1046 + *   This program is distributed in the hope that it will be useful, but WITHOUT
1047 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1048 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1049 + *   more details.
1050 + *
1051 + *   You should have received a copy of the GNU General Public License along with
1052 + *   this program; if not, write to the Free Software Foundation, Inc., 59
1053 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
1054 + *
1055 + *   The full GNU General Public License is included in this distribution in the
1056 + *   file called LICENSE.
1057 + *
1058 + ********************************************************************************/
1059 +
1060 +#include <linux/module.h>
1061 +#include <mach/board.h>
1062 +#include <linux/platform_device.h>
1063 +#include "cns3xxx.h"
1064 +#include "cns3xxx_tool.h"
1065 +#include "cns3xxx_config.h"
1066 +
1067 +#if defined (CONFIG_CNS3XXX_SPPE)
1068 +#include <linux/cns3xxx/sppe.h>
1069 +#define PACKET_REASON_TO_CPU (0x2C)
1070 +#endif
1071 +
1072 +#define RX_SDP_ALIGN 64
1073 +
1074 +#ifdef CONFIG_FPGA
1075 +#include "fpga.h"
1076 +#endif
1077 +
1078 +#ifdef CONFIG_VB
1079 +#include "vb.h"
1080 +#endif
1081 +
1082 +#define CPU_CACHE_BYTES         64
1083 +#define CPU_CACHE_ALIGN(X)      (((X) + (CPU_CACHE_BYTES-1)) & ~(CPU_CACHE_BYTES-1))
1084 +
1085 +
1086 +#define QUEUE_WEIGHT_SET(port, ctl) \
1087 +{ \
1088 +       MAC##port##_PRI_CTRL_REG &= ~(0x3ffff); \
1089 +       MAC##port##_PRI_CTRL_REG |= (ctl.sch_mode << 16); \
1090 +       MAC##port##_PRI_CTRL_REG |= (ctl.q0_w); \
1091 +       MAC##port##_PRI_CTRL_REG |= (ctl.q1_w << 4); \
1092 +       MAC##port##_PRI_CTRL_REG |= (ctl.q2_w << 8); \
1093 +       MAC##port##_PRI_CTRL_REG |= (ctl.q3_w << 12); \
1094 +}
1095 +
1096 +#define QUEUE_WEIGHT_GET(port, ctl) \
1097 +{ \
1098 +       ctl.sch_mode = ((MAC##port##_PRI_CTRL_REG >> 16 ) & 0x3); \
1099 +       ctl.q0_w = ((MAC##port##_PRI_CTRL_REG >> 0 ) & 0x7); \
1100 +       ctl.q1_w = ((MAC##port##_PRI_CTRL_REG >> 4 ) & 0x7); \
1101 +       ctl.q2_w = ((MAC##port##_PRI_CTRL_REG >> 8 ) & 0x7); \
1102 +       ctl.q3_w = ((MAC##port##_PRI_CTRL_REG >> 12 ) & 0x7); \
1103 +}
1104 +
1105 +int cns3xxx_send_packet(struct sk_buff *skb, struct net_device *netdev);
1106 +static int install_isr_rc = 0;
1107 +static int rc_setup_rx_tx = 0; // rc means reference counting.
1108 +static struct net_device *intr_netdev;
1109 +struct net_device *net_dev_array[NETDEV_SIZE]; 
1110 +spinlock_t tx_lock;
1111 +spinlock_t rx_lock;
1112 +u8 fast_bridge_en=1;
1113 +u8 show_rx_proc=0;
1114 +u8 show_tx_proc=0;
1115 +
1116 +int init_port=7; // bit map 7 means port 0, 1 and 2, default is 7.
1117 +//module_param(init_port, u8, S_IRUGO);
1118 +module_param(init_port, int, 0);
1119 +
1120 +u8 ring_index=0; // 0 or 1
1121 +
1122 +#ifdef CNS3XXX_DELAYED_INTERRUPT
1123 +static u32 max_pend_int_cnt=MAX_PEND_INT_CNT, max_pend_time=MAX_PEND_TIME;
1124 +#endif
1125 +
1126 +#ifdef CONFIG_CNS3XXX_NAPI
1127 +struct net_device *napi_dev;
1128 +       #ifdef CNS3XXX_DOUBLE_RX_RING
1129 +       struct net_device *r1_napi_dev; // ring1 napi dev
1130 +       #endif
1131 +#endif
1132 +
1133 +const u32 MAX_RX_DESC_SIZE = 512;
1134 +const u32 MAX_TX_DESC_SIZE = 512;
1135 +const u32 RX_DESC_SIZE = 128;
1136 +//const u32 RX_DESC_SIZE = 5;
1137 +const u32 TX_DESC_SIZE = 120;
1138 +
1139 +//RXRing *rx_ring;
1140 +//TXRing *tx_ring;
1141 +
1142 +// only for debug (proc)
1143 +RingInfo g_ring_info; 
1144 +
1145 +int MSG_LEVEL = NORMAL_MSG;
1146 +
1147 +#ifdef CNS3XXX_STATUS_ISR
1148 +const char *cns3xxx_gsw_status_tbl[] = {
1149 +       "\nMAC0_Q_FULL\n",
1150 +       "\nMAC1_Q_FULL\n",
1151 +       "\nCPU_Q_FULL\n",
1152 +       "\nHNAT_Q_FULL\n",
1153 +       "\nMAC2_Q_FULL\n",
1154 +       "\nMAC0_Q_EXT_FULL\n",
1155 +       "\nGLOBAL_Q_FULL\n",
1156 +       "\nBUFFER_FULL\n",
1157 +       "\nMIB_COUNTER_TH\n",
1158 +       "\n", // 9
1159 +       "\nMAC0_INTRUDER\n",
1160 +       "\nMAC1_INTRUDER\n",
1161 +       "\nCPU_INTRUDER\n",
1162 +       "\nMAC2_INTRUDER\n",
1163 +       "\nMAC0_STATUS_CHG\n",
1164 +       "\nMAC1_STATUS_CHG\n",
1165 +       "\nMAC2_STATUS_CHG\n",
1166 +       "\nMAC0_NO_LINK_DROP\n",
1167 +       "\nMAC1_NO_LINK_DROP\n",
1168 +       "\nMAC2_NO_LINK_DROP\n",
1169 +       "\nMAC0_RX_ERROR_DROP\n",
1170 +       "\nMAC1_RX_ERROR_DROP\n",
1171 +       "\nMAC2_RX_ERROR_DROP\n",
1172 +       "\nMAC0_NO_DESTINATION_DROP\n",
1173 +       "\nMAC1_NO_DESTINATION_DROP\n",
1174 +       "\nMAC2_NO_DESTINATION_DROP\n",
1175 +       "\nMAC0_RMC_PAUSE_DROP\n",
1176 +       "\nMAC1_RMC_PAUSE_DROP\n",
1177 +       "\nMAC2_RMC_PAUSE_DROP\n",
1178 +       "\nMAC0_LOCAL_DROP\n",
1179 +       "\nMAC1_LOCAL_DROP\n",
1180 +       "\nMAC2_LOCAL_DROP\n",
1181 +};
1182 +#endif
1183 +
1184 +#define MIN_PACKET_LEN 14
1185 +
1186 +void cns3xxx_write_pri_mask(u8 pri_mask);
1187 +
1188 +static int cns3xxx_notify_reboot(struct notifier_block *nb, unsigned long event, void *ptr);
1189 +
1190 +static struct notifier_block cns3xxx_notifier_reboot = {
1191 +       .notifier_call  = cns3xxx_notify_reboot,
1192 +       .next           = NULL,
1193 +       .priority       = 0
1194 +};
1195 +
1196 +#if defined(CNS3XXX_VLAN_8021Q)
1197 +void cns3xxx_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
1198 +void cns3xxx_vlan_rx_register(struct net_device *dev, struct vlan_group *grp);
1199 +#endif
1200 +
1201 +void take_off_vlan_header(struct sk_buff *skb)
1202 +{
1203 +       // take off VLAN header
1204 +       memmove(skb->data + 4, skb->data, 12);
1205 +#if 0
1206 +       //skb_ptr->data += 4; 
1207 +       skb_reserve(skb, 4);
1208 +#else
1209 +       skb->data += 4;
1210 +#endif
1211 +       skb->len -= 4; // minus 4 byte vlan tag
1212 +}
1213 +
1214 +int rx_port_base(struct sk_buff *skb, RXDesc *rx_desc_ptr, const struct CNS3XXXPrivate_ *priv)
1215 +{
1216 +       if (skb->data[12] == 0x81 && skb->data[13] == 0x00)  // VLAN header
1217 +       {
1218 +               take_off_vlan_header(skb);
1219 +               print_packet(skb->data, skb->len);
1220 +       }
1221 +       return 0;
1222 +}
1223 +
1224 +int rx_vlan_base(struct sk_buff *skb, RXDesc *rx_desc_ptr, const struct CNS3XXXPrivate_ *priv)
1225 +{
1226 +       return 0;
1227 +}
1228 +
1229 +int tx_port_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb)
1230 +{
1231 +#if defined(CNS3XXX_VLAN_8021Q) && defined (CNS3XXX_8021Q_HW_TX)
1232 +        if (skb && priv->vlgrp != NULL && vlan_tx_tag_present(skb)) 
1233 +       {
1234 +               tx_desc_ptr->c_vid = cpu_to_le16(vlan_tx_tag_get(skb));
1235 +               tx_desc_ptr->ctv=1;
1236 +               tx_desc_ptr->fr = 0;
1237 +
1238 +        }
1239 +       else 
1240 +#endif
1241 +       {
1242 +               tx_desc_ptr->ctv = 0;
1243 +               tx_desc_ptr->pmap = priv->net_device_priv->pmap;
1244 +               tx_desc_ptr->fr = 1;
1245 +       }
1246 +
1247 +       return 0;
1248 +}
1249 +
1250 +
1251 +int tx_vlan_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb)
1252 +{
1253 +#if defined(CNS3XXX_VLAN_8021Q)
1254 +
1255 +        if (skb && priv->vlgrp != NULL && vlan_tx_tag_present(skb)) {
1256 +               tx_desc_ptr->c_vid = cpu_to_le16(vlan_tx_tag_get(skb));
1257 +        }
1258 +#else
1259 +       tx_desc_ptr->c_vid = priv->net_device_priv->vlan_tag;
1260 +
1261 +#endif
1262 +       tx_desc_ptr->ctv=1;
1263 +       tx_desc_ptr->fr = 0;
1264 +
1265 +       return 0;
1266 +}
1267 +
1268 +#if defined (CONFIG_CNS3XXX_SPPE)
1269 +int fp_port_base(TXDesc *tx_desc_ptr, const struct CNS3XXXPrivate_ *priv, struct sk_buff *skb)
1270 +{
1271 +#if 1
1272 +       tx_desc_ptr->fr = 1;
1273 +       tx_desc_ptr->pmap = 0x8;
1274 +#else
1275 +       tx_desc_ptr->fr = 0;
1276 +       tx_desc_ptr->ctv = 1;
1277 +       tx_desc_ptr->c_vid = 80;
1278 +#endif
1279 +    return 0;
1280 +}
1281 +#endif
1282 +
1283 +static inline struct sk_buff *cns3xxx_alloc_skb(void)
1284 +{
1285 +       struct sk_buff *skb;
1286 +       u32 align_64;
1287 +
1288 +       skb = dev_alloc_skb(MAX_PACKET_LEN + 2 + RX_SDP_ALIGN);
1289 +
1290 +       if (unlikely(!skb)) {
1291 +               return NULL;
1292 +       }
1293 +       pci_dma_sync_single_for_device(NULL, virt_to_phys(skb->data), MAX_PACKET_LEN+2+RX_SDP_ALIGN, PCI_DMA_FROMDEVICE);
1294 +
1295 +       align_64=CPU_CACHE_ALIGN((u32)skb->data);
1296 +       skb_reserve(skb, align_64-(u32)skb->data);      /* 16 bytes alignment */
1297 +
1298 +#ifndef CNS3XXX_4N
1299 +       skb_reserve(skb, NET_IP_ALIGN); /* 16 bytes alignment */
1300 +#endif
1301 +
1302 +
1303 +
1304 +       return skb;
1305 +}
1306 +
1307 +static int free_rx_skb(RXRing *rx_ring)
1308 +{
1309 +       int i=0;
1310 +       RXBuffer *rx_buffer = rx_ring->head;
1311 +        //RXDesc *rx_desc = rx_ring.rx_desc_head_vir_addr;
1312 +
1313 +       for (i=0 ; i < get_rx_ring_size(rx_ring) ; ++i) {
1314 +               if (rx_buffer->rx_desc->cown==0 && rx_buffer->skb) {
1315 +                       dev_kfree_skb(rx_buffer->skb);
1316 +                       rx_buffer->skb=0;
1317 +               }
1318 +       }
1319 +       return 0;
1320 +}
1321 +
1322 +int cns3xxx_setup_all_rx_resources(RXRing *rx_ring, u8 ring_num)
1323 +{
1324 +       int i=0;
1325 +       RXBuffer *rx_buffer = 0;
1326 +        RXDesc *rx_desc = 0;
1327 +
1328 +#ifdef NCNB_TEST
1329 +       ncnb_buf = dma_alloc_coherent(NULL, 2*1024* get_rx_ring_size(rx_ring), &ncnb_buf_phy, GFP_KERNEL);
1330 +       printk("NCB_BUF: %08X PHY: %08X \n", ncnb_buf, ncnb_buf_phy);
1331 +       
1332 +#endif
1333 +
1334 +       // alloc RXDesc array
1335 +       rx_ring->rx_desc_head_vir_addr = dma_alloc_coherent(NULL, sizeof(RXDesc) * (get_rx_ring_size(rx_ring)), &rx_ring->rx_desc_head_phy_addr, GFP_KERNEL);
1336 +       if (!rx_ring->rx_desc_head_vir_addr) {
1337 +               return -ENOMEM;
1338 +       }
1339 +
1340 +       memset(rx_ring->rx_desc_head_vir_addr, 0, sizeof(RXDesc) * get_rx_ring_size(rx_ring));
1341 +
1342 +       // alloc RXBuffer array
1343 +       rx_ring->head = kmalloc(sizeof(RXBuffer) * get_rx_ring_size(rx_ring), GFP_KERNEL);
1344 +       
1345 +       if (!rx_ring->head) {
1346 +               return -ENOMEM;
1347 +       }
1348 +
1349 +       rx_buffer = rx_ring->head;
1350 +       for (i=0 ; i < get_rx_ring_size(rx_ring) ; ++i) {
1351 +               rx_buffer->skb=0;
1352 +               ++rx_buffer;
1353 +       }
1354 +
1355 +       rx_buffer = rx_ring->head;
1356 +        rx_desc = rx_ring->rx_desc_head_vir_addr;
1357 +       for (i=0 ; i < get_rx_ring_size(rx_ring) ; ++i, ++rx_buffer, ++rx_desc) {
1358 +               rx_buffer->rx_desc = rx_desc;
1359 +               rx_buffer->skb = cns3xxx_alloc_skb();
1360 +
1361 +               if (!rx_buffer->skb) {
1362 +                       
1363 +                       free_rx_skb(rx_ring);
1364 +                       kfree(rx_ring->head);
1365 +                       dma_free_coherent(NULL, sizeof(RXDesc) * get_rx_ring_size(rx_ring), rx_ring->rx_desc_head_vir_addr, rx_ring->rx_desc_head_phy_addr);
1366 +                       return -ENOMEM;
1367 +               }
1368 +
1369 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1370 +       {
1371 +               RXDesc tmp_rx_desc;
1372 +
1373 +                memset(&tmp_rx_desc, 0, sizeof(RXDesc));
1374 +                tmp_rx_desc.sdp = (u32)virt_to_phys(rx_buffer->skb->data);
1375 +                tmp_rx_desc.sdl = MAX_PACKET_LEN;
1376 +                if (i == (get_rx_ring_size(rx_ring)-1) ){
1377 +                        tmp_rx_desc.eor = 1;
1378 +                }
1379 +                tmp_rx_desc.fsd = 1;
1380 +                tmp_rx_desc.lsd = 1;
1381 +                swap_rx_desc(&tmp_rx_desc, rx_buffer->rx_desc);
1382 +       }
1383 +
1384 +#else
1385 +               rx_buffer->rx_desc->sdp = (u32)virt_to_phys(rx_buffer->skb->data);
1386 +               rx_buffer->rx_desc->sdl = MAX_PACKET_LEN;
1387 +               if (i == (get_rx_ring_size(rx_ring)-1) ){
1388 +                       rx_buffer->rx_desc->eor = 1;
1389 +               }
1390 +               rx_buffer->rx_desc->fsd = 1;
1391 +               rx_buffer->rx_desc->lsd = 1;
1392 +#endif
1393 +
1394 +       }
1395 +       rx_ring->cur_index = 0 ;
1396 +
1397 +       if (ring_num == 0){
1398 +               FS_DESC_PTR0_REG = rx_ring->rx_desc_head_phy_addr;
1399 +               FS_DESC_BASE_ADDR0_REG = rx_ring->rx_desc_head_phy_addr;
1400 +
1401 +       } else if (ring_num == 1){
1402 +               FS_DESC_PTR1_REG = rx_ring->rx_desc_head_phy_addr;
1403 +               FS_DESC_BASE_ADDR1_REG = rx_ring->rx_desc_head_phy_addr;
1404 +       }
1405 +
1406 +       return CAVM_OK;
1407 +}
1408 +
1409 +static int cns3xxx_setup_all_tx_resources(TXRing *tx_ring, u8 ring_num)
1410 +{
1411 +       int i=0;
1412 +       TXBuffer *tx_buffer = 0;
1413 +        TXDesc *tx_desc = 0;
1414 +
1415 +
1416 +       spin_lock_init(&(tx_ring->tx_lock));
1417 +
1418 +       tx_ring->tx_desc_head_vir_addr = dma_alloc_coherent(NULL, sizeof(TXDesc) * get_tx_ring_size(tx_ring), &tx_ring->tx_desc_head_phy_addr, GFP_KERNEL);
1419 +       if (!tx_ring->tx_desc_head_vir_addr) {
1420 +               return -ENOMEM;
1421 +       }
1422 +
1423 +       memset(tx_ring->tx_desc_head_vir_addr, 0, sizeof(TXDesc) * get_tx_ring_size(tx_ring));
1424 +       tx_ring->head = kmalloc(sizeof(TXBuffer) * get_tx_ring_size(tx_ring), GFP_KERNEL);
1425 +
1426 +       tx_buffer = tx_ring->head;
1427 +        tx_desc = tx_ring->tx_desc_head_vir_addr;
1428 +       for (i=0 ; i < get_tx_ring_size(tx_ring) ; ++i, ++tx_buffer, ++tx_desc) {
1429 +               tx_buffer->tx_desc = tx_desc;
1430 +
1431 +               tx_buffer->tx_desc->cown = 1;
1432 +               tx_buffer->skb = 0;
1433 +               if (i == (get_tx_ring_size(tx_ring)-1) ){
1434 +                       tx_buffer->tx_desc->eor = 1;
1435 +               }
1436 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1437 +               swap_tx_desc(tx_buffer->tx_desc, tx_buffer->tx_desc);
1438 +#endif
1439 +
1440 +       }
1441 +
1442 +       tx_ring->cur_index = 0 ;
1443 +
1444 +       if (ring_num == 0){
1445 +               TS_DESC_PTR0_REG = tx_ring->tx_desc_head_phy_addr;
1446 +               TS_DESC_BASE_ADDR0_REG = tx_ring->tx_desc_head_phy_addr;
1447 +       } else if (ring_num == 1){
1448 +               TS_DESC_PTR1_REG = tx_ring->tx_desc_head_phy_addr;
1449 +               TS_DESC_BASE_ADDR1_REG = tx_ring->tx_desc_head_phy_addr;
1450 +       }
1451 +       return CAVM_OK;
1452 +}
1453 +
1454 +int cns3xxx_free_all_rx_resources(RXRing *rx_ring)
1455 +{
1456 +       free_rx_skb(rx_ring);
1457 +       kfree(rx_ring->head);
1458 +       dma_free_coherent(NULL, sizeof(RXDesc) * get_rx_ring_size(rx_ring), rx_ring->rx_desc_head_vir_addr, rx_ring->rx_desc_head_phy_addr);
1459 +       return 0;
1460 +}
1461 +
1462 +static int free_tx_skb(TXRing *tx_ring)
1463 +{
1464 +       int i=0;
1465 +       TXBuffer *tx_buffer = tx_ring->head;
1466 +
1467 +       for (i=0 ; i < get_tx_ring_size(tx_ring) ; ++i) {
1468 +               if (tx_buffer->skb) {
1469 +                       dev_kfree_skb(tx_buffer->skb);
1470 +                       tx_buffer->skb = 0;
1471 +               }
1472 +       }
1473 +       return 0;
1474 +}
1475 +
1476 +int cns3xxx_free_all_tx_resources(TXRing *tx_ring)
1477 +{
1478 +       free_tx_skb(tx_ring);
1479 +       kfree(tx_ring->head);
1480 +       dma_free_coherent(NULL, sizeof(TXDesc) * get_tx_ring_size(tx_ring), tx_ring->tx_desc_head_vir_addr, tx_ring->tx_desc_head_phy_addr);
1481 +       return 0;
1482 +}
1483 +
1484 +static int cns3xxx_free_rx_tx_res(CNS3XXXPrivate *priv)
1485 +{
1486 +       int i=0;
1487 +
1488 +       --rc_setup_rx_tx;
1489 +       if (rc_setup_rx_tx == 0) {
1490 +               enable_port(3, 0); // disable cpu port
1491 +
1492 +               // stop RX/TX ring0 dma
1493 +               enable_rx_dma(0, 0);
1494 +               enable_tx_dma(0, 0);
1495 +
1496 +               for (i=0 ; i < priv->num_rx_queues ; ++i) {
1497 +                       cns3xxx_free_all_rx_resources(priv->rx_ring+i);
1498 +                       memset(priv->rx_ring + i, 0, sizeof(RXRing));
1499 +               }
1500 +
1501 +               for (i=0 ; i < priv->num_tx_queues ; ++i) {
1502 +                       cns3xxx_free_all_tx_resources(priv->tx_ring+i);
1503 +                       memset(priv->tx_ring + i, 0, sizeof(TXRing));
1504 +               }
1505 +               
1506 +       }
1507 +       return 0;
1508 +}
1509 +
1510 +
1511 +static int cns3xxx_setup_rx_tx_res(CNS3XXXPrivate *priv)
1512 +{
1513 +       int i=0;
1514 +
1515 +       if (rc_setup_rx_tx == 0) {
1516 +               clear_fs_dma_state(1);
1517 +               FS_DESC_PTR0_REG = 0;
1518 +               FS_DESC_BASE_ADDR0_REG = 0;
1519 +               FS_DESC_PTR1_REG = 0;
1520 +               FS_DESC_BASE_ADDR1_REG = 0;
1521 +               TS_DESC_PTR0_REG = 0;
1522 +               TS_DESC_BASE_ADDR0_REG = 0;
1523 +               TS_DESC_PTR1_REG = 0;
1524 +               TS_DESC_BASE_ADDR1_REG = 0;
1525 +
1526 +               for (i=0 ; i < priv->num_tx_queues ; ++i) {
1527 +                       spin_lock_init(&((priv->tx_ring+i)->tx_lock));
1528 +                       (priv->tx_ring+i)->max_ring_size = MAX_TX_DESC_SIZE;
1529 +                       (priv->tx_ring+i)->ring_size = TX_DESC_SIZE;
1530 +                       if (cns3xxx_setup_all_tx_resources(priv->tx_ring+i, i) != CAVM_OK)
1531 +                               return CAVM_ERR;
1532 +               }
1533 +
1534 +               for (i=0 ; i < priv->num_rx_queues ; ++i) {
1535 +                       (priv->rx_ring+i)->max_ring_size = MAX_RX_DESC_SIZE;
1536 +                       (priv->rx_ring+i)->ring_size = RX_DESC_SIZE;
1537 +                       if (cns3xxx_setup_all_rx_resources(priv->rx_ring+i, i) != CAVM_OK)
1538 +                               return CAVM_ERR;
1539 +               
1540 +               }
1541 +               clear_fs_dma_state(0);
1542 +       }
1543 +       ++rc_setup_rx_tx;
1544 +       return CAVM_OK;
1545 +}
1546 +
1547 +int free_tx_desc_skb(TXRing *tx_ring, u8 ring_num)
1548 +{
1549 +#if 1
1550 +       int i=0;
1551 +       //u32 tssd_current=0;
1552 +       TXBuffer *tx_buffer = 0;
1553 +       u32 tx_ring_size = get_tx_ring_size(tx_ring);
1554 +       // check curent hw index previous tx descriptor
1555 +       u32 cur_index = cns3xxx_get_tx_hw_index(ring_num) - 1; 
1556 +
1557 +        tx_buffer = get_tx_buffer_by_index(tx_ring, cur_index);
1558 +
1559 +
1560 +       //while (1) 
1561 +       for (i=0 ; i < tx_ring_size ; ++i) {
1562 +               if (tx_buffer->tx_desc->cown == 1 && tx_buffer->skb) {
1563 +                       dev_kfree_skb_any(tx_buffer->skb);
1564 +                       tx_buffer->skb=0;
1565 +                       //tx_buffer->tx_desc->cown == 1;
1566 +               } else {
1567 +                       break;
1568 +               }
1569 +               // --tx_desc_pair_ptr
1570 +               --cur_index;
1571 +               tx_buffer = get_tx_buffer_by_index(tx_ring, cur_index);
1572 +               
1573 +       }
1574 +#endif
1575 +       return 0;
1576 +}
1577 +
1578 +void do_arl_lookup(void)
1579 +{
1580 +}
1581 +
1582 +inline void assign_netdev(RXBuffer volatile *rx_buffer)
1583 +{
1584 +        RXDesc * rx_desc=0;
1585 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1586 +        RXDesc tmp_rx_desc;
1587 +        rx_desc = &tmp_rx_desc;
1588 +        swap_rx_desc(rx_buffer->rx_desc, rx_desc);
1589 +#else
1590 +        rx_desc = rx_buffer->rx_desc;
1591 +#endif
1592 +
1593 +
1594 +#if defined(CONFIG_CNS3XXX_PORT_BASE) || defined(CNS3XXX_VLAN_8021Q)
1595 +       // sp:
1596 +       // 0 - mac port 0
1597 +       // 1 - mac port 1
1598 +       // 4 - mac port 2
1599 +
1600 +       switch (rx_desc->sp)
1601 +       {
1602 +               case 0:
1603 +               {
1604 +                       rx_buffer->skb->dev = PORT0_NETDEV;
1605 +                       break;
1606 +               }
1607 +               case 1:
1608 +               {
1609 +                       rx_buffer->skb->dev = PORT1_NETDEV;
1610 +                       break;
1611 +               }
1612 +               case 4:
1613 +               {
1614 +                       rx_buffer->skb->dev = PORT2_NETDEV;
1615 +                       break;
1616 +               }
1617 +
1618 +       }
1619 +#endif
1620 +
1621 +#ifdef CONFIG_CNS3XXX_VLAN_BASE
1622 +{
1623 +       u16 vlan_tag;
1624 +
1625 +       vlan_tag = rx_desc->c_vid;
1626 +       rx_buffer->skb->dev = net_dev_array[vlan_tag];
1627 +
1628 +}
1629 +#endif
1630 +
1631 +}
1632 +
1633 +#if defined(CNS3XXX_VLAN_8021Q)
1634 +static int cns3xxx_vlan_rx(CNS3XXXPrivate *priv, struct sk_buff *skb, u16 vlan_tag)
1635 +{                       
1636 +        return vlan_hwaccel_receive_skb(skb, priv->vlgrp, vlan_tag);
1637 +}
1638 +#endif
1639 +
1640 +// old_priv has ring index information, current version only uses the information.
1641 +static int cns3xxx_get_rfd_buff(RXBuffer volatile *rx_buffer, CNS3XXXPrivate *old_priv)
1642 +{
1643 +       CNS3XXXPrivate *priv=0;
1644 +       //RXDesc volatile *rxdesc_ptr = rx_buffer->rx_desc;
1645 +       struct sk_buff *skb;
1646 +       //unsigned char *data;
1647 +       u32 len;
1648 +       RXDesc *rx_desc;
1649 +
1650 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1651 +
1652 +       RXDesc tmp_rx_desc;
1653 +
1654 +        rx_desc = &tmp_rx_desc;
1655 +        swap_rx_desc(rx_buffer->rx_desc, rx_desc);
1656 +
1657 +#else
1658 +        rx_desc = rx_buffer->rx_desc;
1659 +#endif
1660 +
1661 +       //rxdesc_ptr = rxring.vir_addr + index;
1662 +       skb = rx_buffer->skb;
1663 +       len = rx_desc->sdl;
1664 +
1665 +
1666 +#ifdef DEBUG_RX
1667 +       if (MSG_LEVEL == DUMP_RX_PKT_INFO) {
1668 +               print_packet(skb->data, len);   
1669 +       }
1670 +       
1671 +#endif
1672 +
1673 +       pci_dma_sync_single_for_device(NULL, virt_to_phys(skb->data), len, PCI_DMA_FROMDEVICE);
1674 +#if defined (CONFIG_CNS3XXX_SPPE)
1675 +       if (PACKET_REASON_TO_CPU == rx_buffer->rx_desc->hr) {
1676 +               if (sppe_pci_fp_ready) {
1677 +                       SPPE_PARAM param;
1678 +                       int pci_dev_index;
1679 +                       struct iphdr *iph;
1680 +       
1681 +                       skb_put(skb, len);
1682 +                       iph = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
1683 +
1684 +                       memset(&param, 0, sizeof(SPPE_PARAM));
1685 +                       param.cmd = SPPE_CMD_ARP;
1686 +                       param.op = SPPE_OP_GET;
1687 +                       param.data.sppe_arp.ip[0] = iph->daddr;
1688 +                       if (SPPE_RESULT_SUCCESS != sppe_func_hook(&param)) {
1689 +                               goto NOT_IN_PCI_FP;
1690 +                       } else {
1691 +                               pci_dev_index = param.data.sppe_arp.unused_1;
1692 +                       }
1693 +                       param.cmd = SPPE_CMD_PCI_FP_DEV;
1694 +                       param.op = SPPE_OP_GET;
1695 +                       param.data.sppe_pci_fp_dev.dev = NULL;
1696 +                       param.data.sppe_pci_fp_dev.index = pci_dev_index;
1697 +                       if (SPPE_RESULT_SUCCESS != sppe_pci_fp_hook(&param)) {
1698 +                               goto NOT_IN_PCI_FP;
1699 +                       } else {
1700 +                               skb->dev = param.data.sppe_pci_fp_dev.dev;
1701 +                       }
1702 +                       #if 1
1703 +                       dev_queue_xmit(skb);
1704 +                       #else
1705 +                       skb->dev->hard_start_xmit(skb, skb->dev);
1706 +                       #endif
1707 +
1708 +                       return 0;
1709 +               }
1710 +       }
1711 +NOT_IN_PCI_FP:
1712 +#endif
1713 +
1714 +#ifdef CNS3XXX_NON_NIC_MODE_8021Q
1715 +       if (cns3xxx_is_untag_packet(rx_desc) == 1)
1716 +               take_off_vlan_header(skb);
1717 +#endif
1718 +       
1719 +#ifdef CONFIG_CNS3XXX_PORT_BASE
1720 +       assign_netdev(rx_buffer);
1721 +
1722 +       if (rx_buffer->skb->dev) // if skb->dev is 0, means VLAN base
1723 +               goto determine_dev_ok;
1724 +
1725 +#endif /* CONFIG_CNS3XXX_PORT_BASE */
1726 +
1727 +
1728 +#ifdef CONFIG_CNS3XXX_VLAN_BASE
1729 +
1730 +#ifdef CONFIG_HAVE_VLAN_TAG
1731 +
1732 +#if defined(CNS3XXX_VLAN_8021Q)
1733 +       // some funcion need netdev like eth_type_trans(), so need to assign it.
1734 +       skb->dev = intr_netdev;
1735 +       // 8021Q module will determine right netdev by vlan tag.
1736 +#else  // defined(CNS3XXX_VLAN_8021Q)
1737 +       { 
1738 +               assign_netdev(rx_buffer);
1739 +
1740 +               take_off_vlan_header(skb);
1741 +               if (MSG_LEVEL == 5)
1742 +                       print_packet(skb->data, 32);
1743 +
1744 +               if ( rx_buffer->skb->dev == 0){
1745 +                       goto freepacket;
1746 +               }
1747 +       }
1748 +       
1749 +#endif // CNS3XXX_VLAN_8021Q
1750 +
1751 +#else  /* CONFIG_HAVE_VLAN_TAG */
1752 +
1753 +#ifdef CNS3XXX_RX_DESC_VLAN_INFO
1754 +// get VLAN information by RX descriptor field
1755 +
1756 +#endif
1757 +
1758 +#endif // CONFIG_HAVE_VLAN_TAG
1759 +
1760 +#endif // CONFIG_CNS3XXX_VLAN_BASE
1761 +
1762 +
1763 +#ifdef CONFIG_CNS3XXX_PORT_BASE
1764 +determine_dev_ok:
1765 +#endif
1766 +
1767 +       skb_put(skb, len);
1768 +
1769 +       if (skb->dev) {
1770 +               priv = netdev_priv(skb->dev);
1771 +       }
1772 +       else{
1773 +               DEBUG_MSG(WARNING_MSG, "skb_ptr->dev==NULL\n");
1774 +               goto freepacket;
1775 +       }
1776 +
1777 +#ifdef CNS3XXX_RX_HW_CHECKSUM
1778 +       switch (rx_desc->prot)
1779 +       {
1780 +               case 1 :
1781 +               case 2 :
1782 +               case 5 :
1783 +               case 6 :
1784 +               {
1785 +                       if ( rx_desc->l4f == 0) { // tcp/udp checksum is correct
1786 +                               skb->ip_summed = CHECKSUM_UNNECESSARY;
1787 +                       } else {
1788 +                               skb->ip_summed = CHECKSUM_NONE; 
1789 +                       }
1790 +                       break;
1791 +               }
1792 +               default:
1793 +               {
1794 +                       skb->ip_summed = CHECKSUM_NONE; 
1795 +                       break;
1796 +               }
1797 +       }
1798 +#else
1799 +       skb->ip_summed = CHECKSUM_NONE; 
1800 +#endif // CNS3XXX_RX_HW_CHECKSUM
1801 +
1802 +
1803 +       // this line must, if no, packet will not send to network layer
1804 +#ifdef CONFIG_FAST_BRIDGE
1805 +       if (fast_bridge_en == 0) 
1806 +#endif
1807 +       skb->protocol = eth_type_trans(skb, skb->dev);
1808 +       
1809 +       skb->dev->last_rx = jiffies;
1810 +       priv->stats.rx_packets++;
1811 +       priv->stats.rx_bytes += len;
1812 +
1813 +#ifdef CONFIG_FAST_BRIDGE
1814 +       if (fast_bridge_en == 1) {
1815 +
1816 +        skb->ip_summed = CHECKSUM_NONE;
1817 +       if ( skb->dev == PORT0_NETDEV) {
1818 +               skb->dev = PORT1_NETDEV;
1819 +       } else if ( skb->dev == PORT1_NETDEV) {
1820 +               skb->dev = PORT0_NETDEV;
1821 +       }
1822 +               //skb->dev->hard_start_xmit(skb, skb->dev);
1823 +       cns3xxx_send_packet(skb, skb->dev);
1824 +       } else {
1825 +#endif // #ifdef CONFIG_FAST_BRIDGE
1826 +
1827 +
1828 +//#if defined(CNS3XXX_VLAN_8021Q)
1829 +#if 0
1830 +       if (priv->vlgrp != NULL)
1831 +       {
1832 +               //cns3xxx_vlan_rx(priv, skb, rx_buffer->rx_desc->c_vid);
1833 +               cns3xxx_vlan_rx(priv, skb, rx_buffer->rx_desc->c_vid);
1834 +               //cns3xxx_vlan_rx(priv, skb, swab16(le32_to_cpu(rx_buffer->rx_desc->c_vid)) );
1835 +       }
1836 +       else
1837 +#else
1838 +       #ifdef CONFIG_CNS3XXX_NAPI
1839 +       netif_receive_skb(skb);
1840 +       #else
1841 +       netif_rx(skb);
1842 +       #endif
1843 +#endif
1844 +
1845 +#ifdef CONFIG_FAST_BRIDGE
1846 +       }
1847 +#endif
1848 +
1849 +       //vlan_hwaccel_receive_skb(skb, priv->vlgrp, 1);
1850 +
1851 +       return 0;
1852 +
1853 +freepacket:
1854 +       //DEBUG_MSG(NORMAL_MSG, "freepacket\n");
1855 +       dev_kfree_skb_any(skb);
1856 +       return 0;
1857 +}
1858 +
1859 +// index from 1
1860 +inline u32 get_rx_hw_index(CNS3XXXPrivate *priv)
1861 +{
1862 +       return ((FS_DESC_PTR0_REG - get_rx_head_phy_addr(&RX_RING0(priv))) / sizeof(RXDesc) );
1863 +}
1864 +
1865 +inline int get_rx_hw_index_by_reg(u8 ring_num)
1866 +{
1867 +       if (ring_num == 0 ) {
1868 +               return ((FS_DESC_PTR0_REG - FS_DESC_BASE_ADDR0_REG) / sizeof(RXDesc) );
1869 +       } else if (ring_num == 1 ) {
1870 +               return ((FS_DESC_PTR1_REG - FS_DESC_BASE_ADDR1_REG) / sizeof(RXDesc) );
1871 +       }
1872 +
1873 +       return CAVM_FAIL;
1874 +}
1875 +
1876 +void dump_rxring(void)
1877 +{
1878 +       int j=0;
1879 +       RXBuffer *rx_buffer = 0;
1880 +
1881 +       rx_buffer = get_rx_ring_head(g_ring_info.rx_ring+0);
1882 +       for (j=0 ; j < get_rx_ring_size(g_ring_info.rx_ring+0); ++j, ++rx_buffer) {
1883 +               printk("[%d] ## rx_buffer->rx_desc->cown: %d\n", j, rx_buffer->rx_desc->cown);
1884 +       }
1885 +}
1886 +
1887 +#ifdef CONFIG_CNS3XXX_NAPI
1888 +void cns3xxx_receive_packet(CNS3XXXPrivate *priv, int mode, int *work_done, int work_to_do)
1889 +#else
1890 +void cns3xxx_receive_packet(CNS3XXXPrivate *priv, int mode)
1891 +#endif
1892 +{
1893 +       int fssd_index;
1894 +       //int fssd_current;
1895 +       RXBuffer volatile *rx_buffer = 0;
1896 +       RXDesc volatile *rx_desc=0;
1897 +       struct sk_buff *skb;
1898 +#ifndef CONFIG_CNS3XXX_NAPI
1899 +       int fsqf = 0; // Queue Full Mode =0
1900 +#endif
1901 +       int i, rxcount = 0;
1902 +       u8 queue_index = priv->ring_index;
1903 +
1904 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1905 +       RXDesc tmp_rx_desc;
1906 +#endif
1907 +
1908 +       rx_buffer = get_cur_rx_buffer(&(priv->rx_ring[queue_index]));
1909 +
1910 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1911 +        rx_desc = &tmp_rx_desc;
1912 +        swap_rx_desc(rx_buffer->rx_desc, rx_desc);
1913 +#else
1914 +        rx_desc = rx_buffer->rx_desc;
1915 +#endif
1916 +
1917 +       fssd_index = get_rx_hw_index_by_reg(queue_index);
1918 +
1919 +       if (fssd_index > get_rx_cur_index(&priv->rx_ring[queue_index]) ) {
1920 +               rxcount = fssd_index - get_rx_cur_index(&priv->rx_ring[queue_index]);
1921 +       } else if (fssd_index < get_rx_cur_index(&priv->rx_ring[queue_index])) {
1922 +               rxcount = (get_rx_ring_size(&priv->rx_ring[queue_index]) - get_rx_cur_index(&priv->rx_ring[queue_index]) ) + fssd_index;
1923 +       } else { // fssd_index == rxring.cur_index
1924 +               if (rx_desc->cown == 0) { // if rx_desc->cown is 1, we can receive the RX descriptor.
1925 +                       enable_rx_dma(0, 1);
1926 +                       goto receive_packet_exit;
1927 +               } else {
1928 +                       // Queue Full
1929 +#ifndef CONFIG_CNS3XXX_NAPI
1930 +                       fsqf = 1;
1931 +#endif
1932 +                       rxcount = get_rx_ring_size(&priv->rx_ring[queue_index]);
1933 +               }
1934 +       }
1935 +#ifndef CONFIG_CNS3XXX_NAPI
1936 +       if (mode == 1) {
1937 +               fsqf = 1;
1938 +               rxcount = get_rx_ring_size(&priv->rx_ring[queue_index]);
1939 +       }
1940 +#endif
1941 +       
1942 +#ifdef CNS3XXX_FREE_TX_IN_RX_PATH
1943 +       free_tx_desc_skb(priv->tx_ring + 0, 0);
1944 +#ifdef CNS3XXX_DOUBLE_TX_RING
1945 +       free_tx_desc_skb(priv->tx_ring + 1, 1);
1946 +#endif
1947 +#endif
1948 +
1949 +       for (i = 0; i < rxcount; i++) {
1950 +
1951 +               if (rx_desc->cown != 0) { // start to get packet
1952 +                       // Alloc New skb_buff 
1953 +                       skb = cns3xxx_alloc_skb();
1954 +                       // Check skb_buff
1955 +                       if (skb) {
1956 +                               cns3xxx_get_rfd_buff(rx_buffer, priv);
1957 +                               rx_buffer->skb = skb;
1958 +#ifndef NCNB_TEST
1959 +                               rx_desc->sdp = (u32)virt_to_phys(skb->data);
1960 +#endif
1961 +                               rx_desc->sdl = MAX_PACKET_LEN;
1962 +                               rx_desc->fsd = 1;
1963 +                               rx_desc->lsd = 1;
1964 +                               rx_desc->cown = 0; // set cbit to 0 
1965 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1966 +                                swap_rx_desc(rx_desc, rx_buffer->rx_desc);
1967 +#endif
1968 +
1969 +#ifdef CONFIG_CNS3XXX_NAPI
1970 +                               ++(*work_done);
1971 +                               if (*work_done >= work_to_do) {
1972 +
1973 +               rx_index_next(&priv->rx_ring[queue_index]); // rx_ring.cur_index points to next
1974 +               rx_buffer = get_cur_rx_buffer(&priv->rx_ring[queue_index]);
1975 +               rx_desc = rx_buffer->rx_desc;
1976 +                                       break;
1977 +                               }
1978 +#endif
1979 +
1980 +                       } else {
1981 +                               // I will add dev->lp.stats->rx_dropped, it will effect the performance
1982 +                               //PDEBUG("%s: Alloc sk_buff fail, reuse the buffer\n", __FUNCTION__);
1983 +                               rx_desc->cown = 0; // set cbit to 0 
1984 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
1985 +                                swap_rx_desc(rx_desc, rx_buffer->rx_desc);
1986 +#endif
1987 +
1988 +                               return;
1989 +                       }
1990 +               } else { // cown is 0, no packets
1991 +                       //*work_done = 0;
1992 +                       return;
1993 +               }
1994 +
1995 +
1996 +               rx_index_next(&priv->rx_ring[queue_index]); // rx_ring.cur_index points to next
1997 +               rx_buffer = get_cur_rx_buffer(&priv->rx_ring[queue_index]);
1998 +               rx_desc = rx_buffer->rx_desc;
1999 +
2000 +       } // end for (i = 0; i < rxcount; i++) 
2001 +
2002 +
2003 +#ifndef CONFIG_CNS3XXX_NAPI
2004 +       if (fsqf) {
2005 +               priv->rx_ring[queue_index].cur_index = fssd_index;
2006 +               mb();
2007 +               enable_rx_dma(0, 1);
2008 +       }
2009 +#endif
2010 +
2011 +
2012 +       //spin_unlock(&rx_lock);
2013 +receive_packet_exit:
2014 +       return;
2015 +}
2016 +
2017 +irqreturn_t cns3xxx_fsrc_ring0_isr(int irq, void *dev_id)
2018 +{
2019 +       struct net_device *netdev = dev_id;
2020 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
2021 +
2022 +       priv->ring_index=0;
2023 +
2024 +#ifdef CONFIG_CNS3XXX_NAPI
2025 +{
2026 +       CNS3XXXPrivate *priv = netdev_priv(napi_dev);
2027 +       priv->ring_index=0;
2028 +
2029 +#ifdef CNS3XXX_USE_MASK
2030 +       cns3xxx_write_pri_mask(0xb0);
2031 +#else
2032 +       cns3xxx_disable_irq(FSRC_RING0_INTERRUPT_ID);
2033 +#endif
2034 +
2035 +        //if (likely(netif_rx_schedule_prep(napi_dev, &priv->napi))) {
2036 +        if (likely(napi_schedule_prep(&priv->napi))) {
2037 +                //__netif_rx_schedule(napi_dev, &priv->napi);
2038 +                __napi_schedule(&priv->napi);
2039 +       } else {
2040 +#ifdef CNS3XXX_USE_MASK
2041 +               cns3xxx_write_pri_mask(0xf0);
2042 +#else
2043 +                cns3xxx_enable_irq(FSRC_RING0_INTERRUPT_ID);
2044 +#endif
2045 +        }
2046 +}
2047 +#else // !CONFIG_CNS3XXX_NAPI
2048 +
2049 +#ifdef CNS3XXX_USE_MASK
2050 +       cns3xxx_write_pri_mask(0xb0);
2051 +#else
2052 +       cns3xxx_disable_irq(FSRC_RING0_INTERRUPT_ID);
2053 +       cns3xxx_disable_irq(FSQF_RING0_INTERRUPT_ID);
2054 +#endif
2055 +
2056 +       cns3xxx_receive_packet(priv, 0); // Receive Once
2057 +
2058 +#ifdef CNS3XXX_USE_MASK
2059 +       cns3xxx_write_pri_mask(0xf0);
2060 +#else
2061 +       cns3xxx_enable_irq(FSRC_RING0_INTERRUPT_ID);
2062 +       cns3xxx_enable_irq(FSQF_RING0_INTERRUPT_ID);
2063 +#endif
2064 +       enable_rx_dma(0, 1);
2065 +#endif
2066 +
2067 +       return IRQ_HANDLED;
2068 +}
2069 +
2070 +
2071 +#if defined(CNS3XXX_DOUBLE_RX_RING)
2072 +irqreturn_t cns3xxx_fsrc_ring1_isr(int irq, void *dev_id)
2073 +{
2074 +       struct net_device *netdev = dev_id;
2075 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
2076 +       priv->ring_index=1;
2077 +
2078 +
2079 +#if defined(CONFIG_CNS3XXX_NAPI) && defined(CNS3XXX_DOUBLE_RX_RING)
2080 +{
2081 +       CNS3XXXPrivate *priv = netdev_priv(r1_napi_dev);
2082 +       priv->ring_index=1;
2083 +
2084 +       cns3xxx_disable_irq(FSRC_RING1_INTERRUPT_ID);
2085 +
2086 +        if (likely(napi_schedule_prep(&priv->napi))) {
2087 +                __napi_schedule(&priv->napi);
2088 +       } else {
2089 +                cns3xxx_enable_irq(FSRC_RING1_INTERRUPT_ID);
2090 +        }
2091 +}
2092 +#else
2093 +
2094 +       cns3xxx_disable_irq(CNS3XXX_FSRC_RING1_INTERRUPT_ID);
2095 +       cns3xxx_disable_irq(CNS3XXX_FSQF_RING1_INTERRUPT_ID);
2096 +       cns3xxx_receive_packet(priv, 0); // Receive Once
2097 +       enable_rx_dma(1, 1);
2098 +
2099 +       cns3xxx_enable_irq(CNS3XXX_FSRC_RING1_INTERRUPT_ID);
2100 +       cns3xxx_enable_irq(CNS3XXX_FSQF_RING1_INTERRUPT_ID);
2101 +#endif
2102 +
2103 +       return IRQ_HANDLED;
2104 +}
2105 +#endif
2106 +
2107 +int cns3xxx_check_enough_tx_descriptor(TXRing *tx_ring, int need_free_tx_desc)
2108 +{
2109 +#if 1
2110 +        int i=0;
2111 +        TXDesc *tx_desc=0;
2112 +        u32 cur_index = get_tx_cur_index(tx_ring);
2113 +        TXBuffer *tx_buffer = get_tx_buffer_by_index(tx_ring, cur_index);
2114 +
2115 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
2116 +        TXDesc tmp_tx_desc;
2117 +        tx_desc = &tmp_tx_desc;
2118 +        swap_tx_desc(tx_buffer->tx_desc, tx_desc);
2119 +#else
2120 +        tx_desc = tx_buffer->tx_desc;
2121 +#endif
2122 +
2123 +
2124 +        for (i=0 ; i < need_free_tx_desc ; ++i) {
2125 +                if ( tx_desc->cown == 0 ) {
2126 +                        return 0; // no free TX descriptor
2127 +                }
2128 +                tx_buffer = get_tx_buffer_by_index(tx_ring, ++cur_index);
2129 +        }
2130 +#endif
2131 +        return 1;
2132 +}
2133 +
2134 +// if return CAVM_ERR, means pad is fail, the packet cannot send by switch.
2135 +
2136 +int fill_a_skb_to_tx_desc(TXBuffer * tx_buffer, u8 *data, int len, struct sk_buff *skb, const struct CNS3XXXPrivate_ *priv, int sg, int fsd, int lsd)
2137 +{
2138 +       //TXDesc *tx_desc_ptr = tx_buffer->tx_desc;
2139 +       static int tt=0;
2140 +
2141 +        TXDesc *tx_desc_ptr = 0;
2142 +#ifdef CONFIG_SWTICH_BIG_ENDIAN
2143 +        TXDesc tmp_tx_desc;
2144 +        tx_desc_ptr = &tmp_tx_desc;
2145 +        swap_tx_desc(tx_buffer->tx_desc, tx_desc_ptr);
2146 +#else
2147 +        tx_desc_ptr = tx_buffer->tx_desc;
2148 +#endif
2149 +
2150 +       
2151 +
2152 +               if (tx_buffer->skb) {    
2153 +                       dev_kfree_skb_any(tx_buffer->skb); 
2154 +                       tx_buffer->skb = 0 ;
2155 +               } else { 
2156 +                       //++tx_ring.non_free_tx_skb; 
2157 +               } 
2158
2159 +               tx_buffer->skb = skb;  /* for free skb */ 
2160 +               tx_desc_ptr->sdp = virt_to_phys(data); 
2161 +               tx_buffer->j = tt;
2162 +               tx_buffer->tx_index = cns3xxx_get_tx_hw_index(0);
2163 +               ++tt;
2164 +
2165 +#if 0
2166 +               {
2167 +                       static u16 previous_sn_num=10;
2168 +                       u16 sn_num=0;
2169 +                       u16 e_type=0;
2170 +
2171 +                       memcpy(&e_type, skb->data + 12, 2);
2172 +                       e_type = be16_to_cpu(e_type);
2173 +
2174 +                       if (e_type == 0x0800) {
2175 +                       memcpy(&sn_num, skb->data + 0x28, 2);
2176 +                       sn_num = be16_to_cpu(sn_num);
2177 +
2178 +                       if ( previous_sn_num == sn_num)
2179 +                               printk("dup\n");
2180 +
2181 +                       previous_sn_num = sn_num;
2182 +                       }
2183 +
2184 +               }
2185 +#endif
2186 +
2187
2188 +#ifdef CNS3XXX_TX_HW_CHECKSUM 
2189 +               tx_desc_ptr->ico = 1; 
2190 +               tx_desc_ptr->uco = 1; 
2191 +               tx_desc_ptr->tco = 1; 
2192 +#else 
2193 +               tx_desc_ptr->ico = 0; 
2194 +               tx_desc_ptr->uco = 0; 
2195 +               tx_desc_ptr->tco = 0; 
2196 +#endif 
2197 +               // Wake interrupt
2198 +#ifdef CNS3XXX_TSTC_RING0_ISR
2199 +               tx_desc_ptr->interrupt = 1;
2200 +#else
2201 +               tx_desc_ptr->interrupt = 0;
2202 +#endif
2203
2204 +               /* fill 0 to MIN_PACKET_LEN size */ 
2205 +               // can change MIN_PACKET_LEN to 14
2206 +               if (sg==0 && len < MIN_PACKET_LEN) { 
2207 +                       if (skb_padto(skb, MIN_PACKET_LEN))
2208 +                               return CAVM_ERR;
2209 +
2210 +                       //memset(skb->data + len, 0, MIN_PACKET_LEN - len); 
2211 +                       //skb->len = MIN_PACKET_LEN;
2212 +                       tx_desc_ptr->sdl = MIN_PACKET_LEN; 
2213 +               } else { 
2214 +                       tx_desc_ptr->sdl = len; 
2215 +               } 
2216 +
2217 +               dma_cache_maint(data, tx_desc_ptr->sdl, PCI_DMA_TODEVICE); 
2218 +
2219 +               /* VLAN base or port base function to set TX descriptor */ 
2220 +               /* reference: tx_//port_base(), tx_vlan_base() */ 
2221 +               priv->net_device_priv->tx_func(tx_desc_ptr, priv, skb); 
2222 +                tx_desc_ptr->fsd = fsd;
2223 +                tx_desc_ptr->lsd = lsd;
2224 +
2225 +               /* NOT SG packet */
2226 +               if( fsd == 1 && lsd == 1) 
2227 +                       tx_desc_ptr->cown = 0;
2228 +
2229 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
2230 +                swap_tx_desc(tx_desc_ptr, tx_buffer->tx_desc);
2231 +#endif
2232 +
2233 +       return CAVM_OK;
2234 +} 
2235 +
2236 +int cns3xxx_send_packet(struct sk_buff *skb, struct net_device *netdev)
2237 +{
2238 +
2239 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
2240 +       TXBuffer *tx_buffer = 0;
2241 +        unsigned long flags;
2242 +       int nr_frags =skb_shinfo(skb)->nr_frags;
2243 +
2244 +       TXDesc *tx_desc[10]; // FIXME: ensure to maximum sg size
2245 +       int     tx_desc_count=0;
2246 +       int i=0;
2247 +
2248 +#ifdef DEBUG_TX
2249 +       if (MSG_LEVEL == DUMP_TX_PKT_INFO) {
2250 +               print_packet(tx_buffer->skb->data, tx_buffer->tx_desc->sdl);
2251 +               //dump_tx_desc(tx_buffer->tx_desc);
2252 +       }
2253 +#endif
2254 +
2255 +        spin_lock_irqsave(&tx_lock, flags);
2256 +
2257 +       if (cns3xxx_check_enough_tx_descriptor(priv->tx_ring + ring_index, (nr_frags==0 ) ? 1 : nr_frags) == 0) { 
2258 +               // no enough tx descriptor
2259 +               spin_unlock_irqrestore(&tx_lock, flags);
2260 +               // re-queue the skb
2261 +               return NETDEV_TX_BUSY;
2262 +       } 
2263 +
2264 +       tx_buffer = get_cur_tx_buffer(priv->tx_ring + ring_index);
2265 +
2266 +       if (nr_frags == 0) { // non scatter/gather I/O
2267 +
2268 +               fill_a_skb_to_tx_desc(tx_buffer, skb->data, skb->len, skb, priv, 0, 1, 1);
2269 +
2270 +               tx_index_next(priv->tx_ring + ring_index);
2271 +
2272 +       } else { // scatter/gather I/O
2273 +               struct skb_frag_struct *frag = 0;
2274 +
2275 +
2276 +               fill_a_skb_to_tx_desc(tx_buffer, skb->data, skb->len - skb->data_len, 0, priv, 1, 1, 0);
2277 +               tx_desc[tx_desc_count++] = tx_buffer->tx_desc;
2278 +               tx_index_next(priv->tx_ring + ring_index);
2279 +               tx_buffer = get_cur_tx_buffer(priv->tx_ring + ring_index);
2280 +
2281 +               for (i=0 ; i < nr_frags-1 ; ++i) {
2282 +                       frag = &skb_shinfo(skb)->frags[i];
2283 +
2284 +                       fill_a_skb_to_tx_desc(tx_buffer, page_address(frag->page) + frag->page_offset, frag->size, 0, priv, 1, 0, 0);
2285 +                       tx_desc[tx_desc_count++] = tx_buffer->tx_desc;
2286 +
2287 +                       tx_index_next(priv->tx_ring + ring_index);
2288 +                       tx_buffer = get_cur_tx_buffer(priv->tx_ring + ring_index);
2289 +               }
2290 +               frag = &skb_shinfo(skb)->frags[nr_frags-1];
2291 +
2292 +               // last fragment
2293 +               fill_a_skb_to_tx_desc(tx_buffer, page_address(frag->page) + frag->page_offset, frag->size, skb, priv, 1, 0, 1);
2294 +               tx_desc[tx_desc_count++] = tx_buffer->tx_desc;
2295 +
2296 +               tx_index_next(priv->tx_ring + ring_index);
2297 +               tx_buffer = get_cur_tx_buffer(priv->tx_ring + ring_index);
2298 +       }
2299 +
2300 +
2301 +       if( nr_frags != 0) {
2302 +
2303 +               for (i = 0; i < tx_desc_count ; i++ )
2304 +                       tx_desc[i]->cown = 0 ; 
2305 +       }
2306 +
2307 +       mb();
2308 +       enable_tx_dma(ring_index, 1);
2309 +
2310 +       priv->stats.tx_packets++;
2311 +       priv->stats.tx_bytes += skb->len;
2312 +       netdev->trans_start = jiffies;
2313 +
2314 +               spin_unlock_irqrestore(&tx_lock, flags);
2315 +       return NETDEV_TX_OK;
2316 +}
2317 +
2318 +
2319 +#ifdef CNS3XXX_FSQF_RING0_ISR
2320 +irqreturn_t cns3xxx_fsqf_ring0_isr(int irq, void *dev_id)
2321 +{
2322 +#ifndef CONFIG_CNS3XXX_NAPI
2323 +       struct net_device *netdev = dev_id;
2324 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
2325 +#endif
2326 +
2327 +#ifdef CONFIG_CNS3XXX_NAPI
2328 +{
2329 +       CNS3XXXPrivate *priv = netdev_priv(napi_dev);
2330 +       // because in normal state, fsql only invoke once and set_bit is atomic function.
2331 +       // so I don't mask it.
2332 +       set_bit(0, &priv->is_qf);
2333 +}
2334 +#else
2335 +#ifdef CNS3XXX_USE_MASK
2336 +       cns3xxx_write_pri_mask(0xb0);
2337 +#else
2338 +       cns3xxx_disable_irq(FSRC_RING0_INTERRUPT_ID);
2339 +       cns3xxx_disable_irq(FSQF_RING0_INTERRUPT_ID);
2340 +#endif
2341 +
2342 +
2343 +       cns3xxx_receive_packet(priv, 1); // Receive at Queue Full Mode
2344 +
2345 +#ifdef CNS3XXX_USE_MASK
2346 +       cns3xxx_write_pri_mask(0xf0);
2347 +#else
2348 +       cns3xxx_enable_irq(FSRC_RING0_INTERRUPT_ID);
2349 +       cns3xxx_enable_irq(FSQF_RING0_INTERRUPT_ID);
2350 +#endif
2351 +
2352 +       enable_rx_dma(0, 1);
2353 +#endif // CONFIG_CNS3XXX_NAPI
2354 +
2355 +       return IRQ_HANDLED;
2356 +}
2357 +#endif
2358 +
2359 +
2360 +#if defined(CNS3XXX_DOUBLE_RX_RING)
2361 +#ifdef CNS3XXX_FSQF_RING1_ISR
2362 +irqreturn_t cns3xxx_fsqf_ring1_isr(int irq, void *dev_id)
2363 +{
2364 +       struct net_device *netdev = dev_id;
2365 +       CNS3XXXPrivate *priv = netdev_priv(netdev);
2366 +       //INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GSW_FSQF_BIT_INDEX);
2367 +
2368 +#ifdef CONFIG_CNS3XXX_NAPI
2369 +{
2370 +       CNS3XXXPrivate *priv = netdev_priv(r1_napi_dev);
2371 +       // because in normal state, fsqf only invoke once and set_bit is atomic function.
2372 +       // so don't mask it.
2373 +       set_bit(0, &priv->is_qf);
2374 +}
2375 +#else
2376 +       cns3xxx_disable_irq(FSRC_RING1_INTERRUPT_ID);
2377 +       cns3xxx_disable_irq(FSQF_RING1_INTERRUPT_ID);
2378 +
2379 +       cns3xxx_receive_packet(priv, 1); // Receive at Queue Full Mode
2380 +       enable_rx_dma(1, 1);
2381 +
2382 +       cns3xxx_enable_irq(FSRC_RING1_INTERRUPT_ID);
2383 +       cns3xxx_enable_irq(FSQF_RING1_INTERRUPT_ID);
2384 +#endif
2385 +       return IRQ_HANDLED;
2386 +}
2387 +#endif
2388 +#endif //#if defined(CNS3XXX_DOUBLE_RX_RING)
2389 +
2390 +
2391 +#ifdef CNS3XXX_STATUS_ISR
2392 +irqreturn_t cns3xxx_status_isr(int irq, void *dev_id)
2393 +{
2394 +       u32 int_status = INTR_STAT_REG;
2395 +       u32 i=0;
2396 +
2397 +       cns3xxx_disable_irq(STATUS_INTERRUPT_ID);
2398 +       for (i = 0; i < 32; i++) {
2399 +               if (int_status & (1 << i)) {
2400 +                       PRINT_INFO(cns3xxx_gsw_status_tbl[i]);
2401 +               }
2402 +       }
2403 +       INTR_STAT_REG = 0xffffffff; // write 1 for clear.
2404 +       cns3xxx_enable_irq(STATUS_INTERRUPT_ID);
2405 +       return IRQ_HANDLED;
2406 +}
2407 +#endif
2408 +
2409 +
2410 +#ifdef CNS3XXX_TSTC_RING0_ISR
2411 +irqreturn_t cns3xxx_tstc_ring0_isr(int irq, void *dev_id)
2412 +{
2413 +       return IRQ_HANDLED;
2414 +}
2415 +#endif
2416 +
2417 +
2418 +static int cns3xxx_install_isr(struct net_device *dev)
2419 +{
2420 +       int retval;
2421 +       CNS3XXXPrivate *priv = netdev_priv(dev);
2422 +       
2423 +       if (install_isr_rc == 0) {
2424 +
2425 +               retval = request_irq(FSRC_RING0_INTERRUPT_ID, cns3xxx_fsrc_ring0_isr, IRQF_SHARED, "FSRC_RING0", intr_netdev);
2426 +
2427 +               if (retval) {
2428 +                       return 1;
2429 +               }
2430 +
2431 +#ifdef CNS3XXX_FSQF_RING0_ISR
2432 +               retval = request_irq(FSQF_RING0_INTERRUPT_ID, cns3xxx_fsqf_ring0_isr, IRQF_SHARED, "FSQF_RING0", intr_netdev);
2433 +
2434 +               if (retval) {
2435 +                       PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "FSQF_RING0", FSQF_RING0_INTERRUPT_ID, retval);
2436 +                       return 2;
2437 +               }
2438 +#endif 
2439 +
2440 +#ifdef CNS3XXX_TSTC_RING0_ISR
2441 +               retval = request_irq(TSTC_RING0_INTERRUPT_ID, cns3xxx_tstc_ring0_isr, IRQF_SHARED, "TSTC_RING0", intr_netdev);
2442 +
2443 +               if (retval) {
2444 +                       PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "TSTC_RING0", FSQF_RING0_INTERRUPT_ID, retval);
2445 +                       return 3;
2446 +               }
2447 +
2448 +#endif
2449 +
2450 +
2451 +       if (priv->num_rx_queues == 2) {
2452 +#if defined(CNS3XXX_DOUBLE_RX_RING)
2453 +               retval = request_irq(FSRC_RING1_INTERRUPT_ID, cns3xxx_fsrc_ring1_isr, IRQF_SHARED, "FSRC_RING1", intr_netdev);
2454 +
2455 +               if (retval) {
2456 +                       return 1;
2457 +               }
2458 +
2459 +#ifdef CNS3XXX_FSQF_RING1_ISR
2460 +               retval = request_irq(FSQF_RING1_INTERRUPT_ID, cns3xxx_fsqf_ring1_isr, IRQF_SHARED, "FSQF_RING1", intr_netdev);
2461 +
2462 +               if (retval) {
2463 +                       PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "FSQF_RING1", FSQF_RING1_INTERRUPT_ID, retval);
2464 +                       return 2;
2465 +               }
2466 +#endif 
2467 +
2468 +#endif
2469 +       }
2470 +
2471 +#ifdef CNS3XXX_STATUS_ISR
2472 +               retval = request_irq(STATUS_INTERRUPT_ID, cns3xxx_status_isr, IRQF_SHARED, "GSW_STATUS", intr_netdev);
2473 +
2474 +               if (retval) {
2475 +                       PRINT_INFO("%s: unable to get IRQ %d (irqval=%d).\n", "GSW STATUS INT", STATUS_INTERRUPT_ID, retval);
2476 +                       return 3;
2477 +               }
2478 +               INTR_MASK_REG = 0;
2479 +#endif
2480 +
2481 +
2482 +
2483 +
2484 +
2485 +
2486 +#ifdef CONFIG_CNS3XXX_NAPI
2487 +{
2488 +       CNS3XXXPrivate *sp = netdev_priv(napi_dev);    
2489 +        napi_enable(&sp->napi);
2490 +        netif_start_queue(napi_dev);
2491 +
2492 +#ifdef CNS3XXX_DOUBLE_RX_RING
2493 +       sp = netdev_priv(r1_napi_dev);    
2494 +        napi_enable(&sp->napi);
2495 +        netif_start_queue(r1_napi_dev);
2496 +#endif
2497 +}
2498 +#endif
2499 +       // enable cpu port
2500 +       enable_port(3, 1);
2501 +
2502 +       } // end if (install_isr_rc == 0) 
2503 +
2504 +       ++install_isr_rc;
2505 +
2506 +       return 0;
2507 +}
2508 +
2509 +
2510 +int cns3xxx_open(struct net_device *dev)
2511 +{
2512 +       CNS3XXXPrivate *priv = netdev_priv(dev);
2513 +       //static int init_state=0;
2514 +       
2515 +       if (cns3xxx_setup_rx_tx_res(priv) != CAVM_OK) {
2516 +               return -1;
2517 +       }
2518 +
2519 +       netif_start_queue(dev);
2520 +       priv->net_device_priv->open();
2521 +
2522 +       cns3xxx_install_isr(dev);
2523 +
2524 +       enable_rx_dma(0, 1);
2525 +
2526 +       if (priv->num_rx_queues == 2) 
2527 +               enable_rx_dma(1, 1);
2528 +
2529 +       netif_carrier_on(dev);
2530 +
2531 +       return 0;
2532 +}
2533 +
2534 +static int cns3xxx_uninstall_isr(struct net_device *dev)
2535 +{
2536 +       CNS3XXXPrivate *priv = netdev_priv(dev);
2537 +       --install_isr_rc;
2538 +       if (install_isr_rc == 0) {
2539 +               enable_port(3, 0);
2540 +               free_irq(FSRC_RING0_INTERRUPT_ID, intr_netdev);
2541 +#ifdef CNS3XXX_STATUS_ISR
2542 +               free_irq(STATUS_INTERRUPT_ID, intr_netdev);
2543 +#endif
2544 +
2545 +#ifdef CNS3XXX_FSQF_RING0_ISR
2546 +               free_irq(FSQF_RING0_INTERRUPT_ID, intr_netdev);
2547 +#endif
2548 +
2549 +#ifdef CNS3XXX_TSTC_RING0_ISR
2550 +               free_irq(TSTC_RING0_INTERRUPT_ID, intr_netdev);
2551 +#endif
2552 +
2553 +       if (priv->num_rx_queues == 2) {
2554 +               free_irq(FSRC_RING1_INTERRUPT_ID, intr_netdev);
2555 +
2556 +#ifdef CNS3XXX_FSQF_RING1_ISR
2557 +               free_irq(FSQF_RING1_INTERRUPT_ID, intr_netdev);
2558 +#endif
2559 +       }
2560 +
2561 +
2562 +
2563 +#ifdef CONFIG_CNS3XXX_NAPI
2564 +{
2565 +       CNS3XXXPrivate *sp = netdev_priv(napi_dev);
2566 +
2567 +       napi_disable(&sp->napi);
2568 +       netif_stop_queue(napi_dev);
2569 +#ifdef CNS3XXX_DOUBLE_RX_RING
2570 +       sp = netdev_priv(r1_napi_dev);
2571 +
2572 +       napi_disable(&sp->napi);
2573 +       netif_stop_queue(r1_napi_dev);
2574 +#endif
2575 +}
2576 +#endif
2577 +
2578 +
2579 +       }
2580 +
2581 +       return 0;
2582 +}
2583 +
2584 +int cns3xxx_close(struct net_device *dev)
2585 +{
2586 +       CNS3XXXPrivate *priv = netdev_priv(dev);
2587 +
2588 +       enable_rx_dma(0, 0);
2589 +       enable_tx_dma(0, 0);
2590 +
2591 +       if (priv->num_rx_queues == 2) 
2592 +               enable_tx_dma(1, 0);
2593 +
2594 +       if (priv->num_tx_queues == 2) 
2595 +               enable_rx_dma(1, 0);
2596 +
2597 +        netif_stop_queue(dev);
2598 +
2599 +       priv->net_device_priv->close();
2600 +       cns3xxx_uninstall_isr(dev);
2601 +       cns3xxx_free_rx_tx_res(priv);
2602 +       netif_carrier_off(dev);
2603 +       return 0;
2604 +}
2605 +
2606 +
2607 +
2608 +//#define MAC_PORT(p) MAC##p##_CFG_REG
2609 +
2610 +void broadcast_storm_cfg(u8 port, u8 boradcast, u8 multicast, u8 unknown)
2611 +{
2612 +       switch (port)
2613 +       {
2614 +               case 0:
2615 +               {
2616 +                       (boradcast == 1) ? (MAC0_CFG_REG |= (1 << 30)) : (MAC0_CFG_REG &= (~(1 << 30))) ;
2617 +                       (multicast == 1) ? (MAC0_CFG_REG |= (1 << 29)) : (MAC0_CFG_REG &= (~(1 << 29))) ;
2618 +                       (unknown == 1) ? (MAC0_CFG_REG |= (1 << 28)) : (MAC0_CFG_REG &= (~(1 << 28))) ;
2619 +                       break;
2620 +               }
2621 +               case 1:
2622 +               {
2623 +                       (boradcast == 1) ? (MAC1_CFG_REG |= (1 << 30)) : (MAC1_CFG_REG &= (~(1 << 30))) ;
2624 +                       (multicast == 1) ? (MAC1_CFG_REG |= (1 << 29)) : (MAC1_CFG_REG &= (~(1 << 29))) ;
2625 +                       (unknown == 1) ? (MAC1_CFG_REG |= (1 << 28)) : (MAC1_CFG_REG &= (~(1 << 28))) ;
2626 +                       break;
2627 +               }
2628 +               case 2:
2629 +               {
2630 +                       (boradcast == 1) ? (MAC2_CFG_REG |= (1 << 30)) : (MAC2_CFG_REG &= (~(1 << 30))) ;
2631 +                       (multicast == 1) ? (MAC2_CFG_REG |= (1 << 29)) : (MAC2_CFG_REG &= (~(1 << 29))) ;
2632 +                       (unknown == 1) ? (MAC2_CFG_REG |= (1 << 28)) : (MAC2_CFG_REG &= (~(1 << 28))) ;
2633 +                       break;
2634 +               }
2635 +       }
2636 +}
2637 +
2638 +void broadcast_storm_rate(u8 rate)
2639 +{
2640 +       TC_CTRL_REG &= (~(0xf << 24));
2641 +       TC_CTRL_REG |= (rate << 24);
2642 +}
2643 +
2644 +// port: 0, 1, 2 ; port0, port1 and port2
2645 +// config general mac port configuration
2646 +void cns3xxx_general_mac_cfg(u8 port)
2647 +{
2648 +       u32 cfg=0;
2649 +
2650 +       switch (port)
2651 +       {
2652 +               case 0:
2653 +               {
2654 +                       cfg = MAC0_CFG_REG;
2655 +                       break;
2656 +               }
2657 +               case 1:
2658 +               {
2659 +                       cfg = MAC1_CFG_REG;
2660 +                       break;
2661 +               }
2662 +               case 2:
2663 +               {
2664 +                       cfg = MAC2_CFG_REG;
2665 +                       break;
2666 +               }
2667 +       }
2668 +
2669 +
2670 +       // txc_check_en: 1 
2671 +       cfg |= (1 << 13);
2672 +
2673 +       // bp_en: 1
2674 +       cfg |= (1 << 17);
2675 +
2676 +#ifdef CNS3XXX_LEARN_ENABLE
2677 +       // learn_dis: 0
2678 +       cfg &= (~(1 << 19));
2679 +#else
2680 +       // learn disable
2681 +       cfg |= (1 << 19);
2682 +#endif
2683 +
2684 +       // blocking_state: 0
2685 +       cfg &= (~(1 << 20));
2686 +
2687 +       // block_mode: 0
2688 +       cfg &= (~(1 << 21));
2689 +
2690 +#ifdef CNS3XXX_AGE_ENABLE
2691 +       // age_en: 1
2692 +       cfg |= (1 << 22);
2693 +
2694 +#else
2695 +       // age disable
2696 +       cfg &= (~(1 << 22));
2697 +#endif
2698 +
2699 +       // SA_secured: 0
2700 +       cfg &= (~(1 << 23));
2701 +
2702 +       switch (port)
2703 +       {
2704 +               case 0:
2705 +               {
2706 +                       MAC0_CFG_REG = cfg;
2707 +                       break;
2708 +               }
2709 +               case 1:
2710 +               {
2711 +                       MAC1_CFG_REG = cfg;
2712 +                       break;
2713 +               }
2714 +               case 2:
2715 +               {
2716 +                       MAC2_CFG_REG = cfg;
2717 +                       break;
2718 +               }
2719 +       }
2720 +
2721 +}
2722 +
2723 +void cns3xxx_configu_cpu_port(void)
2724 +{
2725 +       // Set CPU port to general configuration
2726 +       
2727 +#ifdef CNS3XXX_LEARN_ENABLE
2728 +       CPU_CFG_REG &= (~(1 << 19));
2729 +#else
2730 +       // learn_dis: 1
2731 +       CPU_CFG_REG |= (1 << 19);
2732 +#endif
2733 +
2734 +#ifdef CNS3XXX_AGE_ENABLE
2735 +       // age_en: 1
2736 +       CPU_CFG_REG |= (1 << 22);
2737 +#else
2738 +       // age disable
2739 +       CPU_CFG_REG &= (~(1 << 22));
2740 +#endif
2741 +
2742 +       // SA_secured: 0
2743 +       CPU_CFG_REG &= (~(1 << 23));
2744 +
2745 +       // go to hnat:1
2746 +       CPU_CFG_REG |= (1 << 29);
2747 +
2748 +       //offset 4N +2 
2749 +       CPU_CFG_REG &= (~(1 << 30));
2750 +#ifdef CNS3XXX_4N
2751 +       CPU_CFG_REG |= (1 << 30);
2752 +#endif
2753 +
2754 +       // cpu flow control disable
2755 +       CPU_CFG_REG &= (~(1 << 31));
2756 +#ifdef CNS3XXX_CPU_PORT_FC
2757 +       // cpu flow control enable
2758 +       CPU_CFG_REG |= (1 << 31);
2759 +#endif
2760 +       
2761 +}
2762 +
2763 +static void __init cns3xxx_gsw_hw_init(void)
2764 +{
2765 +       //u32 mac_port_config;
2766 +       int i;
2767 +       //u32 cfg_reg = 0;
2768 +        u32 reg_config = 0;
2769 +
2770 +#ifdef CONFIG_SILICON
2771 +
2772 +       //GPIOB_PIN_EN_REG |= (1 << 14); //enable GMII2_CRS
2773 +       //GPIOB_PIN_EN_REG |= (1 << 15); //enable GMII2_COL
2774 +       GPIOB_PIN_EN_REG |= (1 << 20); //enable MDC
2775 +       GPIOB_PIN_EN_REG |= (1 << 21); //enable MDIO
2776 +       
2777 +       cns3xxx_gsw_power_enable();
2778 +       cns3xxx_gsw_software_reset();
2779 +#endif
2780 +
2781 +#ifdef CNS3XXX_CONFIG_SIM_MODE
2782 +        SLK_SKEW_CTRL_REG |= (1 << 31);
2783 +#endif
2784 +
2785 +
2786 +#if 1
2787 +       while (((SRAM_TEST_REG >> 20) & 1) == 0);
2788 +#endif
2789 +
2790 +       clear_fs_dma_state(1);
2791 +       
2792 +
2793 +       // disable port mac0, mac1, mac2, cpu port
2794 +       enable_port(0, 0);
2795 +       enable_port(1, 0);
2796 +       enable_port(2, 0);
2797 +       enable_port(3, 0);
2798 +
2799 +       // disable RX0/TX0 RX1/TX1 DMA
2800 +       enable_tx_dma(0, 0);
2801 +       enable_tx_dma(1, 0);
2802 +       enable_rx_dma(0, 0);
2803 +       enable_rx_dma(1, 0);
2804 +
2805 +       INTR_STAT_REG = 0xffffffff; // write 1 for clear.
2806 +
2807 +#ifdef CNS3XXX_DELAYED_INTERRUPT
2808 +       DELAY_INTR_CFG_REG = (1 << 16) | (max_pend_int_cnt << 8) | (max_pend_time);
2809 +#endif
2810 +
2811 +        reg_config = PHY_AUTO_ADDR_REG;
2812 +        reg_config &= ~(3 << 30);
2813 +#ifdef CONFIG_CNS3XXX_JUMBO_FRAME
2814 +        reg_config |= (3 << 30); // maximum frame length: 9600 bytes
2815 +#else
2816 +        reg_config |= (2 << 30); // maximum frame length: 1536 bytes
2817 +#endif
2818 +
2819 +        PHY_AUTO_ADDR_REG = reg_config;
2820 +
2821 +
2822 +       // Set general value for MAC_GLOB_CFG_REG
2823 +       // age_time: 2 ^(1-1) * 300 sec 
2824 +       MAC_GLOB_CFG_REG &= (~0xf);
2825 +       MAC_GLOB_CFG_REG |= 1;
2826 +
2827 +
2828 +       // bkoff_mode: 111 follow standard
2829 +       MAC_GLOB_CFG_REG &= (~(0x7 << 9));
2830 +       MAC_GLOB_CFG_REG |= (0x7 << 9);
2831 +
2832 +       // jam_no: 1010: 
2833 +       MAC_GLOB_CFG_REG &= (~(0xf << 12));
2834 +       MAC_GLOB_CFG_REG |= (0xa << 12);
2835 +
2836 +       // bp_mode: 10: 
2837 +       MAC_GLOB_CFG_REG &= (~(0x3 << 16));
2838 +       MAC_GLOB_CFG_REG |= (0x2 << 16);
2839 +
2840 +       // res_mc_flt: 0
2841 +       MAC_GLOB_CFG_REG &= (~(0x1 << 28));
2842 +
2843 +       // col_mode: 11
2844 +       MAC_GLOB_CFG_REG &= (~(0x3 << 18));
2845 +       MAC_GLOB_CFG_REG |= (0x3 << 18);
2846 +
2847 +       // crc_stripping: 1
2848 +       MAC_GLOB_CFG_REG |= (0x1 << 20);
2849 +
2850 +
2851 +       // ACCEPT_CRC_BAD_PKT : 0
2852 +       MAC_GLOB_CFG_REG &= (~(0x1 << 21));
2853 +
2854 +#ifdef ACCEPT_CRC_BAD_PKT
2855 +       MAC_GLOB_CFG_REG |= (0x1 << 21);
2856 +#endif
2857 +
2858 +       // SVL
2859 +       MAC_GLOB_CFG_REG &= (~(0x1 << 7));
2860 +
2861 +#ifdef IVL
2862 +       // IVL: 1 (IVL), 0 (SVL)
2863 +       MAC_GLOB_CFG_REG |= (0x1 << 7);
2864 +#endif
2865 +
2866 +
2867 +       // HNAT_en: 0
2868 +       MAC_GLOB_CFG_REG &= (~(0x1 << 26));
2869 +
2870 +       // Firewall_mode: 0
2871 +       MAC_GLOB_CFG_REG &= (~(0x1 << 27));
2872 +
2873 +
2874 +
2875 +       cns3xxx_general_mac_cfg(0);
2876 +       cns3xxx_general_mac_cfg(1);
2877 +       cns3xxx_general_mac_cfg(2);
2878 +       cns3xxx_configu_cpu_port();
2879 +
2880 +       // write vlan table
2881 +       // set cpu port vlan table
2882 +       cns3xxx_vlan_table_add(&cpu_vlan_table_entry);
2883 +       for (i=0 ; i < sizeof(vlan_table_entry)/sizeof(VLANTableEntry) ; ++i) 
2884 +               cns3xxx_vlan_table_add(&vlan_table_entry[i]);
2885 +       
2886 +       cns3xxx_set_pvid(0, PORT0_PVID);
2887 +       cns3xxx_set_pvid(1, PORT1_PVID);
2888 +       cns3xxx_set_pvid(2, PORT2_PVID);
2889 +       cns3xxx_set_pvid(3, CPU_PVID);
2890 +
2891 +#ifdef CNS3XXX_SET_ARL_TABLE
2892 +       // set arl table
2893 +       cns3xxx_arl_table_flush();
2894 +#endif
2895 +}
2896 +
2897 +static int cns3xxx_set_mac_addr(struct net_device *dev, void *p)
2898 +{
2899 +       //struct sockaddr *sock_addr = addr;
2900 +       CNS3XXXPrivate *priv = netdev_priv(dev);
2901 +
2902 +        struct sockaddr *addr= p;
2903 +
2904 +
2905 +       spin_lock_irq(&priv->lock);
2906 +
2907 +
2908 +        if (!is_valid_ether_addr(addr->sa_data))
2909 +                return -EADDRNOTAVAIL;
2910 +
2911 +       // 1. delete old arl mac entry
2912 +       // 2. add new arl mac entry
2913 +       // 3. copy new mac to netdev field
2914 +
2915 +       if (priv->net_device_priv->arl_table_entry) {
2916 +               cns3xxx_arl_table_invalid(priv->net_device_priv->arl_table_entry);
2917 +               memcpy(priv->net_device_priv->arl_table_entry->mac, addr->sa_data, dev->addr_len);
2918 +               //print_arl_table_entry(priv->net_device_priv->arl_table_entry);
2919 +               cns3xxx_arl_table_add(priv->net_device_priv->arl_table_entry);
2920 +       }
2921 +        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
2922 +
2923 +       spin_unlock_irq(&priv->lock);
2924 +       return 0;
2925 +}
2926 +
2927 +
2928 +int set_fc_rls(struct ifreq *ifr)
2929 +{
2930 +       CNS3XXXSARLEntry ctl;
2931 +
2932 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2933 +               return -EFAULT; 
2934 +       FC_GLOB_THRS_REG &= (~(0x1ff << 16));
2935 +       FC_GLOB_THRS_REG |= (ctl.val << 16);
2936 +       return CAVM_OK;
2937 +}
2938 +
2939 +int get_fc_rls(struct ifreq *ifr)
2940 +{
2941 +       CNS3XXXSARLEntry ctl;
2942 +
2943 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2944 +               return -EFAULT; 
2945 +
2946 +       ctl.val = ((FC_GLOB_THRS_REG >> 16) & 0x1ff);
2947 +
2948 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
2949 +               return -EFAULT; 
2950 +       return CAVM_OK;
2951 +}
2952 +
2953 +int set_fc_set(struct ifreq *ifr)
2954 +{
2955 +       CNS3XXXSARLEntry ctl;
2956 +
2957 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2958 +               return -EFAULT; 
2959 +       FC_GLOB_THRS_REG &= (~0x1ff);
2960 +       FC_GLOB_THRS_REG |= ctl.val;
2961 +       return CAVM_OK;
2962 +}
2963 +
2964 +int get_fc_set(struct ifreq *ifr)
2965 +{
2966 +       CNS3XXXSARLEntry ctl;
2967 +
2968 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2969 +               return -EFAULT; 
2970 +
2971 +       ctl.val = ((FC_GLOB_THRS_REG) & 0x1ff);
2972 +
2973 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
2974 +               return -EFAULT; 
2975 +       return CAVM_OK;
2976 +}
2977 +
2978 +
2979 +int set_sarl_rls(struct ifreq *ifr)
2980 +{
2981 +       CNS3XXXSARLEntry ctl;
2982 +
2983 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2984 +               return -EFAULT; 
2985 +       SARL_CTRL_REG &= (~(0x1ff << 12));
2986 +       SARL_CTRL_REG |= (ctl.val << 12);
2987 +       return CAVM_OK;
2988 +}
2989 +
2990 +int get_sarl_rls(struct ifreq *ifr)
2991 +{
2992 +       CNS3XXXSARLEntry ctl;
2993 +
2994 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
2995 +               return -EFAULT; 
2996 +
2997 +       ctl.val = ((SARL_CTRL_REG >> 12) & 0x1ff);
2998 +
2999 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
3000 +               return -EFAULT; 
3001 +       return CAVM_OK;
3002 +}
3003 +
3004 +int set_sarl_enable(struct ifreq *ifr)
3005 +{
3006 +       CNS3XXXSARLEntry ctl;
3007 +
3008 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3009 +               return -EFAULT; 
3010 +       SARL_CTRL_REG &= (~(0x1 << 31));
3011 +       SARL_CTRL_REG |= (ctl.val << 31);
3012 +       return CAVM_OK;
3013 +}
3014 +
3015 +int get_sarl_enable(struct ifreq *ifr)
3016 +{
3017 +       CNS3XXXSARLEntry ctl;
3018 +
3019 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3020 +               return -EFAULT; 
3021 +       ctl.val = ((SARL_CTRL_REG >> 31 ) & 0x1);
3022 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
3023 +               return -EFAULT; 
3024 +       return CAVM_OK;
3025 +}
3026 +int set_sarl_set(struct ifreq *ifr)
3027 +{
3028 +       CNS3XXXSARLEntry ctl;
3029 +
3030 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3031 +               return -EFAULT; 
3032 +       SARL_CTRL_REG &= (~0x1ff);
3033 +       SARL_CTRL_REG |= ctl.val;
3034 +       return CAVM_OK;
3035 +}
3036 +
3037 +int get_sarl_set(struct ifreq *ifr)
3038 +{
3039 +       CNS3XXXSARLEntry ctl;
3040 +
3041 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3042 +               return -EFAULT; 
3043 +
3044 +       ctl.val = ((SARL_CTRL_REG) & 0x1ff);
3045 +
3046 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
3047 +               return -EFAULT; 
3048 +       return CAVM_OK;
3049 +}
3050 +
3051 +int set_sarl_oq(struct ifreq *ifr)
3052 +{
3053 +       CNS3XXXSARLEntry ctl;
3054 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3055 +               return -EFAULT; 
3056 +
3057 +       switch (ctl.gyr)
3058 +       {
3059 +               case 0: // green
3060 +               {
3061 +                       SARL_OQ_GTH_REG &= (~(0xff << ctl.tc*8));
3062 +                       SARL_OQ_GTH_REG |= (ctl.val << ctl.tc*8);
3063 +                       break;
3064 +               }
3065 +               case 1: // yellow
3066 +               {
3067 +                       SARL_OQ_YTH_REG &= (~(0xff << ctl.tc*8));
3068 +                       SARL_OQ_YTH_REG |= (ctl.val << ctl.tc*8);
3069 +                       break;
3070 +               }
3071 +               case 2: // red
3072 +               {
3073 +                       SARL_OQ_RTH_REG &= (~(0xff << ctl.tc*8));
3074 +                       SARL_OQ_RTH_REG |= (ctl.val << ctl.tc*8);
3075 +                       break;
3076 +               }
3077 +       }
3078 +       return CAVM_OK;
3079 +}
3080 +
3081 +int get_sarl_oq(struct ifreq *ifr)
3082 +{
3083 +       CNS3XXXSARLEntry ctl;
3084 +
3085 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXSARLEntry)) )  
3086 +               return -EFAULT; 
3087 +
3088 +       switch (ctl.gyr)
3089 +       {
3090 +               case 0: // green
3091 +               {
3092 +                       ctl.val = ((SARL_OQ_GTH_REG >> ctl.tc*8) & 0xff);
3093 +                       break;
3094 +               }
3095 +               case 1: // yellow
3096 +               {
3097 +                       ctl.val = ((SARL_OQ_YTH_REG >> ctl.tc*8) & 0xff);
3098 +                       break;
3099 +               }
3100 +               case 2: // red
3101 +               {
3102 +                       ctl.val = ((SARL_OQ_RTH_REG >> ctl.tc*8) & 0xff);
3103 +                       break;
3104 +               }
3105 +       }
3106 +
3107 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXSARLEntry)) )  
3108 +               return -EFAULT; 
3109 +       return CAVM_OK;
3110 +}
3111 +
3112 +int set_queue_weight(struct ifreq *ifr)
3113 +{
3114 +       CNS3XXXQueueWeightEntry ctl;
3115 +
3116 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXQueueWeightEntry)) )  
3117 +               return -EFAULT; 
3118 +       switch (ctl.which_port)
3119 +       {
3120 +               case 0:
3121 +               {
3122 +                       QUEUE_WEIGHT_SET(0, ctl)
3123 +                       return 0;
3124 +               }
3125 +               case 1:
3126 +               {
3127 +                       QUEUE_WEIGHT_SET(1, ctl)
3128 +                       return 0;
3129 +               }
3130 +               case 2:
3131 +               {
3132 +                       QUEUE_WEIGHT_SET(2, ctl)
3133 +                       return 0;
3134 +               }
3135 +               case 3: // cpu port 
3136 +               {
3137 +                       CPU_PRI_CTRL_REG &= ~(0x3ffff);
3138 +                       CPU_PRI_CTRL_REG |= (ctl.sch_mode << 16);
3139 +                       CPU_PRI_CTRL_REG |= (ctl.q0_w);
3140 +                       CPU_PRI_CTRL_REG |= (ctl.q1_w << 4);
3141 +                       CPU_PRI_CTRL_REG |= (ctl.q2_w << 8);
3142 +                       CPU_PRI_CTRL_REG |= (ctl.q3_w << 12);
3143 +                       return 0;
3144 +               }
3145 +               case 4: // PPE port 
3146 +               {
3147 +                       HNAT_PRI_CTRL_REG &= ~(0x3ffff);
3148 +                       HNAT_PRI_CTRL_REG |= (ctl.sch_mode << 16);
3149 +                       HNAT_PRI_CTRL_REG |= (ctl.q0_w);
3150 +                       HNAT_PRI_CTRL_REG |= (ctl.q1_w << 4);
3151 +                       HNAT_PRI_CTRL_REG |= (ctl.q2_w << 8);
3152 +                       HNAT_PRI_CTRL_REG |= (ctl.q3_w << 12);
3153 +                       return 0;
3154 +               }
3155 +               default:
3156 +               {
3157 +                       return -EFAULT;
3158 +               }
3159 +       }
3160 +}
3161 +
3162 +int get_queue_weight(struct ifreq *ifr)
3163 +{
3164 +       CNS3XXXQueueWeightEntry ctl;
3165 +
3166 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXQueueWeightEntry)) )  
3167 +               return -EFAULT; 
3168 +
3169 +       switch (ctl.which_port)
3170 +       {
3171 +               case 0:
3172 +               {
3173 +                       QUEUE_WEIGHT_GET(0, ctl)
3174 +                       break;
3175 +               }
3176 +               case 1:
3177 +               {
3178 +                       QUEUE_WEIGHT_GET(1, ctl)
3179 +                       break;
3180 +               }
3181 +               case 2:
3182 +               {
3183 +                       QUEUE_WEIGHT_GET(2, ctl)
3184 +                       break;
3185 +               }
3186 +               case 3:
3187 +               {
3188 +                       ctl.sch_mode = ((CPU_PRI_CTRL_REG >> 16 ) & 0x3); 
3189 +                       ctl.q0_w = ((CPU_PRI_CTRL_REG >> 0 ) & 0x7); 
3190 +                       ctl.q1_w = ((CPU_PRI_CTRL_REG >> 4 ) & 0x7);
3191 +                       ctl.q2_w = ((CPU_PRI_CTRL_REG >> 8 ) & 0x7); 
3192 +                       ctl.q3_w = ((CPU_PRI_CTRL_REG >> 12 ) & 0x7); 
3193 +                       break;
3194 +               }
3195 +               case 4:
3196 +               {
3197 +                       ctl.sch_mode = ((HNAT_PRI_CTRL_REG >> 16 ) & 0x3); 
3198 +                       ctl.q0_w = ((HNAT_PRI_CTRL_REG >> 0 ) & 0x7); 
3199 +                       ctl.q1_w = ((HNAT_PRI_CTRL_REG >> 4 ) & 0x7);
3200 +                       ctl.q2_w = ((HNAT_PRI_CTRL_REG >> 8 ) & 0x7); 
3201 +                       ctl.q3_w = ((HNAT_PRI_CTRL_REG >> 12 ) & 0x7); 
3202 +                       break;
3203 +               }
3204 +       }
3205 +
3206 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXQueueWeightEntry)) )  
3207 +               return -EFAULT; 
3208 +
3209 +       return CAVM_OK;
3210 +}
3211 +
3212 +int set_rate_limit(struct ifreq *ifr)
3213 +{
3214 +       CNS3XXXRateLimitEntry ctl;
3215 +
3216 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXRateLimitEntry)) )  
3217 +               return -EFAULT; 
3218 +       switch (ctl.which_port)
3219 +       {
3220 +               case 0:
3221 +               {
3222 +                       RATE_CTRL_REG &= (~(0x7f << 8));
3223 +                       RATE_CTRL_REG |= ( ctl.band_width << 8);
3224 +                       RATE_CTRL_REG &= (~(0x3));
3225 +                       RATE_CTRL_REG |= ctl.base_rate;
3226 +                       return 0;
3227 +               }
3228 +               case 1:
3229 +               {
3230 +                       RATE_CTRL_REG &= (~(0x7f << 16));
3231 +                       RATE_CTRL_REG |= ( ctl.band_width << 16);
3232 +                       RATE_CTRL_REG &= (~(0x3 << 2));
3233 +                       RATE_CTRL_REG |= (ctl.base_rate << 2);
3234 +                       return 0;
3235 +               }
3236 +               case 2:
3237 +               {
3238 +                       RATE_CTRL_REG &= (~(0x7f << 24));
3239 +                       RATE_CTRL_REG |= ( ctl.band_width << 24);
3240 +                       RATE_CTRL_REG &= (~(0x3 << 4));
3241 +                       RATE_CTRL_REG |= (ctl.base_rate << 4);
3242 +                       return 0;
3243 +               }
3244 +               case 3: // port 0 extra dma
3245 +               {
3246 +                       TC_CTRL_REG &= (~0x7f);
3247 +                       TC_CTRL_REG |= ctl.band_width;
3248 +                       RATE_CTRL_REG &= (~(0x3 << 6));
3249 +                       RATE_CTRL_REG |= (ctl.base_rate << 6);
3250 +                       return 0;
3251 +               }
3252 +               default:
3253 +               {
3254 +                       return -EFAULT;
3255 +               }
3256 +       }
3257 +}
3258 +
3259 +int get_rate_limit(struct ifreq *ifr)
3260 +{
3261 +       CNS3XXXRateLimitEntry ctl;
3262 +
3263 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXRateLimitEntry)) )  
3264 +               return -EFAULT; 
3265 +       switch (ctl.which_port)
3266 +       {
3267 +               case 0:
3268 +               {
3269 +                       ctl.band_width = (RATE_CTRL_REG >> 8) & 0x7f;
3270 +                       ctl.base_rate = RATE_CTRL_REG & 0x3;
3271 +                       break;
3272 +               }
3273 +               case 1:
3274 +               {
3275 +                       ctl.band_width = (RATE_CTRL_REG >> 16) & 0x7f;
3276 +                       ctl.base_rate = (RATE_CTRL_REG >> 2) & 0x3;
3277 +                       break;
3278 +               }
3279 +               case 2:
3280 +               {
3281 +                       ctl.band_width = (RATE_CTRL_REG >> 24) & 0x7f;
3282 +                       ctl.base_rate = (RATE_CTRL_REG >> 4) & 0x3;
3283 +                       break;
3284 +               }
3285 +               case 3: // port 0 extra dma
3286 +               {
3287 +                       ctl.band_width = (TC_CTRL_REG) & 0x7f;
3288 +                       ctl.base_rate = (RATE_CTRL_REG >> 6) & 0x3;
3289 +                       break;
3290 +               }
3291 +               default:
3292 +               {
3293 +                       return -EFAULT;
3294 +               }
3295 +       }
3296 +
3297 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXRateLimitEntry)) )  
3298 +               return -EFAULT; 
3299 +
3300 +       return CAVM_OK;
3301 +}
3302 +
3303 +int set_fc(struct ifreq *ifr)
3304 +{
3305 +       CNS3XXXFCEntry ctl;
3306 +       u32 port_offset[]={0x0c, 0x10, 0x18, 0x14}; // 0x14 is cpu port offset
3307 +       u32 val=0;
3308 +
3309 +
3310 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXFCEntry)) )  
3311 +               return -EFAULT; 
3312 +
3313 +       val = SWITCH_REG_VALUE(port_offset[ctl.port]);
3314 +       if (ctl.port == 3) { // cpu port, only can set rx fc
3315 +               val &= (~(1 << 31));
3316 +               if (ctl.fc_en) 
3317 +                       val |= (1 << 31);
3318 +       } else {
3319 +               val &= (~(1 << 11)); // disable rx fc
3320 +               val &= (~(1 << 12)); // disable tx fc
3321 +               val |= (ctl.fc_en << 11);
3322 +       }
3323 +
3324 +       SWITCH_REG_VALUE(port_offset[ctl.port]) = val;
3325 +       return CAVM_OK;
3326 +}
3327 +
3328 +int get_fc(struct ifreq *ifr)
3329 +{
3330 +       CNS3XXXFCEntry ctl;
3331 +       u32 port_offset[]={0x0c, 0x10, 0x18, 0x14}; // 0x14 is cpu port offset
3332 +       u32 val=0;
3333 +
3334 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXFCEntry)) )  
3335 +               return -EFAULT; 
3336 +
3337 +       val = SWITCH_REG_VALUE(port_offset[ctl.port]);
3338 +       if (ctl.port == 3) { // cpu port, only can set rx fc
3339 +               ctl.fc_en = ((val >> 31) & 1);
3340 +       } else {
3341 +               ctl.fc_en = ((val >> 11) & 3);
3342 +
3343 +       }
3344 +
3345 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXFCEntry)) )  
3346 +               return -EFAULT; 
3347 +
3348 +       return CAVM_OK;
3349 +}
3350 +
3351 +int set_ivl(struct ifreq *ifr)
3352 +{
3353 +       CNS3XXXIVLEntry ctl;
3354 +
3355 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXIVLEntry)) )  
3356 +               return -EFAULT; 
3357 +
3358 +       cns3xxx_ivl(ctl.enable);
3359 +
3360 +       return CAVM_OK;
3361 +}
3362 +
3363 +int get_ivl(struct ifreq *ifr)
3364 +{
3365 +       CNS3XXXIVLEntry ctl;
3366 +
3367 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXIVLEntry)) )  
3368 +               return -EFAULT; 
3369 +
3370 +       ctl.enable = ((MAC_GLOB_CFG_REG >> 7) & 0x1);
3371 +
3372 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXIVLEntry)) )  
3373 +               return -EFAULT; 
3374 +
3375 +       return CAVM_OK;
3376 +}
3377 +
3378 +int set_wan_port(struct ifreq *ifr)
3379 +{
3380 +       CNS3XXXWANPortEntry ctl;
3381 +
3382 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXWANPortEntry)) )  
3383 +               return -EFAULT; 
3384 +       VLAN_CFG &= (~(0x1f << 8));
3385 +       VLAN_CFG |= (ctl.wan_port << 8);
3386 +
3387 +       return CAVM_OK;
3388 +}
3389 +int get_wan_port(struct ifreq *ifr)
3390 +{
3391 +       CNS3XXXWANPortEntry ctl;
3392 +
3393 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXWANPortEntry)) )  
3394 +               return -EFAULT; 
3395 +
3396 +       ctl.wan_port = ((VLAN_CFG >> 8) & 0x1f);
3397 +
3398 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXWANPortEntry)) )  
3399 +               return -EFAULT; 
3400 +
3401 +       return CAVM_OK;
3402 +}
3403 +
3404 +int set_pvid(struct ifreq *ifr)
3405 +{
3406 +       CNS3XXXPVIDEntry ctl;
3407 +
3408 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPVIDEntry)) )  
3409 +               return -EFAULT; 
3410 +       cns3xxx_set_pvid(ctl.which_port, ctl.pvid);
3411 +
3412 +       return CAVM_OK;
3413 +}
3414 +
3415 +int get_pvid(struct ifreq *ifr)
3416 +{
3417 +       CNS3XXXPVIDEntry ctl;
3418 +
3419 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPVIDEntry)) )  
3420 +               return -EFAULT; 
3421 +
3422 +       ctl.pvid = cns3xxx_get_pvid(ctl.which_port);
3423 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXPVIDEntry)) )  
3424 +               return -EFAULT; 
3425 +       return CAVM_OK;
3426 +}
3427 +
3428 +int set_qa(struct ifreq *ifr)
3429 +{
3430 +       CNS3XXXQAEntry ctl;
3431 +
3432 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXQAEntry)) )  
3433 +               return -EFAULT; 
3434 +
3435 +       MAC_GLOB_CFG_EXT_REG &= ~(0x7 << 27);
3436 +       MAC_GLOB_CFG_EXT_REG |= (ctl.qa << 27);
3437 +       
3438 +       return CAVM_OK;
3439 +}
3440 +
3441 +int get_qa(struct ifreq *ifr)
3442 +{
3443 +       CNS3XXXQAEntry ctl;
3444 +
3445 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXQAEntry)) )  
3446 +               return -EFAULT; 
3447 +
3448 +       ctl.qa = (MAC_GLOB_CFG_EXT_REG >> 27) & 0x7;
3449 +
3450 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXQAEntry)) )  
3451 +               return -EFAULT; 
3452 +       return CAVM_OK;
3453 +}
3454 +
3455 +int get_packet_max_len(struct ifreq *ifr)
3456 +{
3457 +       CNS3XXXMaxLenEntry ctl;
3458 +
3459 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXMaxLenEntry)) )  
3460 +               return -EFAULT; 
3461 +
3462 +       ctl.max_len = (PHY_AUTO_ADDR_REG >> 30) & 0x3;
3463 +
3464 +       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXMaxLenEntry)) )  
3465 +               return -EFAULT; 
3466 +       return CAVM_OK;
3467 +}
3468 +
3469 +int set_packet_max_len(struct ifreq *ifr)
3470 +{
3471 +       CNS3XXXMaxLenEntry ctl;
3472 +
3473 +       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXMaxLenEntry)) )  
3474 +               return -EFAULT; 
3475 +
3476 +       PHY_AUTO_ADDR_REG &= (~(3 << 30));
3477 +       PHY_AUTO_ADDR_REG |= (ctl.max_len << 30);
3478 +
3479 +       return CAVM_OK;
3480 +}
3481 +
3482 +int set_udp_range(struct ifreq *ifr)
3483 +{
3484 +       CNS3XXXUdpRangeEtypeControl conf;
3485 +
3486 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXUdpRangeEtypeControl)) )  
3487 +               return -EFAULT; 
3488 +
3489 +       switch (conf.udp_range_num)
3490 +       {
3491 +               case 0:
3492 +               {
3493 +                       UDP_RANGE0_REG = 0;
3494 +                       UDP_RANGE0_REG |= conf.port_start;
3495 +                       UDP_RANGE0_REG |= (conf.port_end << 16);
3496 +                       break;
3497 +               }
3498 +               case 1:
3499 +               {
3500 +                       UDP_RANGE1_REG = 0;
3501 +                       UDP_RANGE1_REG |= conf.port_start;
3502 +                       UDP_RANGE1_REG |= (conf.port_end << 16);
3503 +                       break;
3504 +               }
3505 +               case 2:
3506 +               {
3507 +                       UDP_RANGE2_REG = 0;
3508 +                       UDP_RANGE2_REG |= conf.port_start;
3509 +                       UDP_RANGE2_REG |= (conf.port_end << 16);
3510 +                       break;
3511 +               }
3512 +               case 3:
3513 +               {
3514 +                       UDP_RANGE3_REG = 0;
3515 +                       UDP_RANGE3_REG |= conf.port_start;
3516 +                       UDP_RANGE3_REG |= (conf.port_end << 16);
3517 +                       break;
3518 +               }
3519 +       }
3520 +
3521 +       return CAVM_OK;
3522 +}
3523 +
3524 +int get_udp_range(struct ifreq *ifr)
3525 +{
3526 +       CNS3XXXUdpRangeEtypeControl conf;
3527 +
3528 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXUdpRangeEtypeControl)) )  
3529 +               return -EFAULT; 
3530 +
3531 +       switch (conf.udp_range_num)
3532 +       {
3533 +               case 0:
3534 +               {
3535 +                       conf.port_start = (UDP_RANGE0_REG & 0xffff);
3536 +                       conf.port_end = ((UDP_RANGE0_REG >> 16 )& 0xffff);
3537 +                       break;
3538 +               }
3539 +               case 1:
3540 +               {
3541 +                       conf.port_start = (UDP_RANGE1_REG & 0xffff);
3542 +                       conf.port_end = ((UDP_RANGE1_REG >> 16 )& 0xffff);
3543 +                       break;
3544 +               }
3545 +               case 2:
3546 +               {
3547 +                       conf.port_start = (UDP_RANGE2_REG & 0xffff);
3548 +                       conf.port_end = ((UDP_RANGE2_REG >> 16 )& 0xffff);
3549 +                       break;
3550 +               }
3551 +               case 3:
3552 +               {
3553 +                       conf.port_start = (UDP_RANGE3_REG & 0xffff);
3554 +                       conf.port_end = ((UDP_RANGE3_REG >> 16 )& 0xffff);
3555 +                       break;
3556 +               }
3557 +       }
3558 +
3559 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXEtypeControl)) )  
3560 +               return -EFAULT; 
3561 +
3562 +       return CAVM_OK;
3563 +}
3564 +
3565 +int get_etype(struct ifreq *ifr)
3566 +{
3567 +       CNS3XXXEtypeControl conf;
3568 +
3569 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXEtypeControl)) )  
3570 +               return -EFAULT; 
3571 +       switch (conf.etype_num)
3572 +       {
3573 +               case 0:
3574 +               {
3575 +                       conf.val = (ETYPE1_ETYPE0_REG & 0xffff);
3576 +                       conf.pri = (PRIO_ETYPE_UDP_REG & 0x7);
3577 +                       break;
3578 +               }
3579 +               case 1:
3580 +               {
3581 +                       conf.val = ((ETYPE1_ETYPE0_REG >> 16 )& 0xffff);
3582 +                       conf.pri = ((PRIO_ETYPE_UDP_REG >> 4) & 0x7);
3583 +                       break;
3584 +               }
3585 +               case 2:
3586 +               {
3587 +                       conf.val = (ETYPE3_ETYPE2_REG & 0xffff);
3588 +                       conf.pri = ((PRIO_ETYPE_UDP_REG >> 8) & 0x7);
3589 +                       break;
3590 +               }
3591 +               case 3:
3592 +               {
3593 +                       conf.val = ((ETYPE3_ETYPE2_REG >> 16 )& 0xffff);
3594 +                       conf.pri = ((PRIO_ETYPE_UDP_REG >> 12) & 0x7);
3595 +                       break;
3596 +               }
3597 +       }
3598 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXEtypeControl)) )  
3599 +               return -EFAULT; 
3600 +
3601 +       return CAVM_OK;
3602 +}
3603 +
3604 +int set_etype(struct ifreq *ifr)
3605 +{
3606 +       CNS3XXXEtypeControl conf;
3607 +
3608 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXEtypeControl)) )  
3609 +               return -EFAULT; 
3610 +       switch (conf.etype_num)
3611 +       {
3612 +               case 0:
3613 +               {
3614 +                       ETYPE1_ETYPE0_REG &= (~0xffff);
3615 +                       ETYPE1_ETYPE0_REG |= conf.val;
3616 +
3617 +                       PRIO_ETYPE_UDP_REG &= (~7);
3618 +                       PRIO_ETYPE_UDP_REG |= (conf.pri);
3619 +                       break;
3620 +               }
3621 +               case 1:
3622 +               {
3623 +                       ETYPE1_ETYPE0_REG &= (~(0xffff << 16));
3624 +                       ETYPE1_ETYPE0_REG |= (conf.val << 16);
3625 +
3626 +                       PRIO_ETYPE_UDP_REG &= (~(7 << 4));
3627 +                       PRIO_ETYPE_UDP_REG |= (conf.pri << 4);
3628 +                       break;
3629 +               }
3630 +               case 2:
3631 +               {
3632 +                       ETYPE3_ETYPE2_REG &= (~0xffff);
3633 +                       ETYPE3_ETYPE2_REG |= conf.val;
3634 +
3635 +                       PRIO_ETYPE_UDP_REG &= (~(7 << 8));
3636 +                       PRIO_ETYPE_UDP_REG |= (conf.pri << 8);
3637 +                       break;
3638 +               }
3639 +               case 3:
3640 +               {
3641 +                       ETYPE3_ETYPE2_REG &= (~(0xffff << 16));
3642 +                       ETYPE3_ETYPE2_REG |= (conf.val << 16);
3643 +
3644 +                       PRIO_ETYPE_UDP_REG &= (~(7 << 12));
3645 +                       PRIO_ETYPE_UDP_REG |= (conf.pri << 12);
3646 +                       break;
3647 +               }
3648 +       }
3649 +       return CAVM_OK;
3650 +}
3651 +
3652 +int get_pri_ip_dscp(struct ifreq *ifr)
3653 +{
3654 +       CNS3XXXPriIpDscpControl conf;
3655 +
3656 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXPriIpDscpControl)) )  
3657 +               return -EFAULT; 
3658 +
3659 +       if ( 0 <= conf.ip_dscp_num && conf.ip_dscp_num <= 7) {
3660 +               conf.pri = ((PRIO_IPDSCP_7_0_REG >> (conf.ip_dscp_num * 4)) & 0x7);
3661 +       } else if ( 8 <= conf.ip_dscp_num && conf.ip_dscp_num <= 15) {
3662 +                       conf.pri = ((PRIO_IPDSCP_15_8_REG >> ((conf.ip_dscp_num-8) * 4)) & 0x7);
3663 +                } else if ( 16 <= conf.ip_dscp_num && conf.ip_dscp_num <= 23) {
3664 +                               conf.pri = ((PRIO_IPDSCP_23_16_REG >> ((conf.ip_dscp_num-16) * 4)) & 0x7);
3665 +                       } else if ( 24 <= conf.ip_dscp_num && conf.ip_dscp_num <= 31) {
3666 +                                       conf.pri = ((PRIO_IPDSCP_31_24_REG >> ((conf.ip_dscp_num-24) * 4)) & 0x7);
3667 +                               } else if ( 32 <= conf.ip_dscp_num && conf.ip_dscp_num <= 39) {
3668 +                                               conf.pri = ((PRIO_IPDSCP_39_32_REG >> ((conf.ip_dscp_num-32) * 4)) & 0x7);
3669 +                                       } else if ( 40 <= conf.ip_dscp_num && conf.ip_dscp_num <= 47) {
3670 +                                                       conf.pri = ((PRIO_IPDSCP_47_40_REG >> ((conf.ip_dscp_num-40) * 4)) & 0x7);
3671 +                                               } else if ( 48 <= conf.ip_dscp_num && conf.ip_dscp_num <= 55) {
3672 +                                                               conf.pri = ((PRIO_IPDSCP_55_48_REG >> ((conf.ip_dscp_num-48) * 4)) & 0x7);
3673 +                                                       } else if ( 56 <= conf.ip_dscp_num && conf.ip_dscp_num <= 63) {
3674 +                                                                       conf.pri = ((PRIO_IPDSCP_63_56_REG >> ((conf.ip_dscp_num-56) * 4)) & 0x7);
3675 +                                                               } else {
3676 +                                                                       return CAVM_ERR;
3677 +                                                                       }
3678 +
3679 +
3680 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXPriIpDscpControl)) )  
3681 +               return -EFAULT; 
3682 +       return CAVM_OK;
3683 +}
3684 +
3685 +
3686 +int set_pri_ip_dscp(struct ifreq *ifr)
3687 +{
3688 +       CNS3XXXPriIpDscpControl conf;
3689 +
3690 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXPriIpDscpControl)) )  
3691 +               return -EFAULT; 
3692 +
3693 +       if ( 0 <= conf.ip_dscp_num && conf.ip_dscp_num <= 7) {
3694 +               PRIO_IPDSCP_7_0_REG &=  (~(0x7 << (conf.ip_dscp_num * 4) ) );
3695 +               PRIO_IPDSCP_7_0_REG |= (conf.pri << (conf.ip_dscp_num * 4));
3696 +       } else if ( 8 <= conf.ip_dscp_num && conf.ip_dscp_num <= 15) {
3697 +                       PRIO_IPDSCP_15_8_REG &=  (~(0x7 << ((conf.ip_dscp_num-8) * 4) ) );
3698 +                       PRIO_IPDSCP_15_8_REG |= (conf.pri << ((conf.ip_dscp_num-8) * 4));
3699 +                } else if ( 16 <= conf.ip_dscp_num && conf.ip_dscp_num <= 23) {
3700 +                               PRIO_IPDSCP_23_16_REG &=  (~(0x7 << ((conf.ip_dscp_num-16) * 4) ) );
3701 +                               PRIO_IPDSCP_23_16_REG |= (conf.pri << ((conf.ip_dscp_num-16) * 4));
3702 +
3703 +                       } else if ( 24 <= conf.ip_dscp_num && conf.ip_dscp_num <= 31) {
3704 +                                       PRIO_IPDSCP_31_24_REG &=  (~(0x7 << ((conf.ip_dscp_num-24) * 4) ) );
3705 +                                       PRIO_IPDSCP_31_24_REG |= (conf.pri << ((conf.ip_dscp_num-24) * 4));
3706 +
3707 +                               } else if ( 32 <= conf.ip_dscp_num && conf.ip_dscp_num <= 39) {
3708 +                                               PRIO_IPDSCP_39_32_REG &=  (~(0x7 << ((conf.ip_dscp_num-32) * 4) ) );
3709 +                                               PRIO_IPDSCP_39_32_REG |= (conf.pri << ((conf.ip_dscp_num-32) * 4));
3710 +
3711 +                                       } else if ( 40 <= conf.ip_dscp_num && conf.ip_dscp_num <= 47) {
3712 +                                                       PRIO_IPDSCP_47_40_REG &=  (~(0x7 << ((conf.ip_dscp_num-40) * 4) ) );
3713 +                                                       PRIO_IPDSCP_47_40_REG |= (conf.pri << ((conf.ip_dscp_num-40) * 4));
3714 +                                               } else if ( 48 <= conf.ip_dscp_num && conf.ip_dscp_num <= 55) {
3715 +                                                               PRIO_IPDSCP_55_48_REG &=  (~(0x7 << ((conf.ip_dscp_num-48) * 4) ) );
3716 +                                                               PRIO_IPDSCP_55_48_REG |= (conf.pri << ((conf.ip_dscp_num-48) * 4));
3717 +                                                       } else if ( 56 <= conf.ip_dscp_num && conf.ip_dscp_num <= 63) {
3718 +                                                                       PRIO_IPDSCP_63_56_REG &=  (~(0x7 << ((conf.ip_dscp_num-56) * 4) ) );
3719 +                                                                       PRIO_IPDSCP_63_56_REG |= (conf.pri << ((conf.ip_dscp_num-56) * 4));
3720 +                                                               } else {
3721 +                                                                       return CAVM_ERR;
3722 +                                                                       }
3723 +       return CAVM_OK;
3724 +}
3725 +
3726 +
3727 +int bcm53115M_reg_read_ioctl(struct ifreq *ifr)
3728 +{
3729 +       int bcm53115M_reg_read(int page, int offset, u8 *buf, int len);
3730 +       CNS3XXXBCM53115M conf;
3731 +       int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state);
3732 +
3733 +
3734 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXBCM53115M)) )  
3735 +               return -EFAULT; 
3736 +       printk("conf.page: %x\n", conf.page);
3737 +       printk("conf.offset: %x\n", conf.offset);
3738 +       printk("conf.data_len: %x\n", conf.data_len);
3739 +       switch (conf.data_len)
3740 +       {
3741 +               case 1:
3742 +               {
3743 +                       bcm53115M_reg_read(conf.page, conf.offset, (u8 *)&conf.u8_val, 1);
3744 +                       printk("conf.u8_val: %x\n", conf.u8_val);
3745 +                       break;
3746 +               }
3747 +               case 2:
3748 +               {
3749 +                       bcm53115M_reg_read(conf.page, conf.offset, (u8 *)&conf.u16_val, 2);
3750 +                       printk("conf.u16_val: %x\n", conf.u16_val);
3751 +                       break;
3752 +               }
3753 +               case 4:
3754 +               {
3755 +                       bcm53115M_reg_read(conf.page, conf.offset, (u8 *)&conf.u32_val, 4);
3756 +                       printk("conf.u32_val: %x\n", conf.u32_val);
3757 +                       break;
3758 +               }
3759 +               default:
3760 +               {
3761 +                       printk("[kernel mode]: don't support date length: %d\n", conf.data_len);
3762 +               }
3763 +       }
3764 +
3765 +
3766 +
3767 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXBCM53115M)) )  
3768 +               return -EFAULT; 
3769 +       return CAVM_OK;
3770 +}
3771 +
3772 +int bcm53115M_reg_write_ioctl(struct ifreq *ifr)
3773 +{
3774 +       int bcm53115M_reg_write(int page, int offset, u8 *buf, int len);
3775 +       CNS3XXXBCM53115M conf;
3776 +
3777 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXBCM53115M)) )  
3778 +               return -EFAULT; 
3779 +
3780 +       switch (conf.data_len)
3781 +       {
3782 +               case 1:
3783 +               {
3784 +                       bcm53115M_reg_write(conf.page, conf.offset, (u8 *)&conf.u8_val, 1);
3785 +                       break;
3786 +               }
3787 +               case 2:
3788 +               {
3789 +                       bcm53115M_reg_write(conf.page, conf.offset, (u8 *)&conf.u16_val, 2);
3790 +                       break;
3791 +               }
3792 +               case 4:
3793 +               {
3794 +                       bcm53115M_reg_write(conf.page, conf.offset, (u8 *)&conf.u32_val, 4);
3795 +                       break;
3796 +               }
3797 +               default:
3798 +               {
3799 +                       printk("[kernel mode]: don't support date length: %d\n", conf.data_len);
3800 +               }
3801 +       }
3802 +       return CAVM_OK;
3803 +}
3804 +
3805 +#if 0
3806 +int get_rxring(struct ifreq *ifr)
3807 +{
3808 +       CNS3XXXRingStatus conf;
3809 +
3810 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXRingStatus)) )  
3811 +               return -EFAULT; 
3812 +       conf.rx_ring=g_ring_info.rx_ring;
3813 +       conf.tx_ring=0;
3814 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXRingStatus)) )  
3815 +               return -EFAULT; 
3816 +}
3817 +#endif
3818 +
3819 +int dump_mib_counter(struct ifreq *ifr)
3820 +{
3821 +       CNS3XXXMIBCounter conf;
3822 +       int addr=0,i=0;
3823 +
3824 +       if (copy_from_user(&conf, ifr->ifr_data, sizeof(CNS3XXXMIBCounter)) )  
3825 +               return -EFAULT; 
3826 +
3827 +       for (addr=0x300; addr <= 0x334 ; addr+=4)
3828 +               conf.mib[i++]=SWITCH_REG_VALUE(addr);
3829 +       for (addr=0x400; addr <= 0x434 ; addr+=4)
3830 +               conf.mib[i++]=SWITCH_REG_VALUE(addr);
3831 +       for (addr=0x600; addr <= 0x634 ; addr+=4)
3832 +               conf.mib[i++]=SWITCH_REG_VALUE(addr);
3833 +       // cpu mib counter
3834 +       for (addr=0x500; addr <= 0x528 ; addr+=4)
3835 +               conf.mib[i++]=SWITCH_REG_VALUE(addr);
3836 +       conf.mib_len=i;
3837 +       if (copy_to_user(ifr->ifr_data, &conf, sizeof(CNS3XXXMIBCounter)) )  
3838 +               return -EFAULT; 
3839 +       return 0;
3840 +}
3841 +
3842 +// reference e100.c
3843 +int cns3xxx_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
3844 +{
3845 +       CNS3XXXIoctlCmd ioctl_cmd;
3846 +
3847 +       //printk("cns3xxx_do_ioctl begin\n");
3848 +
3849 +        if (cmd != SIOCDEVPRIVATE) {
3850 +                return -EOPNOTSUPP;
3851 +        }
3852 +        if (copy_from_user(&ioctl_cmd, ifr->ifr_data, sizeof(CNS3XXXIoctlCmd))) 
3853 +                return -EFAULT;
3854 +
3855 +       //printk("ioctl_cmd: %d\n", ioctl_cmd);
3856 +       switch (ioctl_cmd) {
3857 +               case CNS3XXX_ARP_REQUEST_SET:
3858 +               {
3859 +                       CNS3XXXArpRequestControl ctl;
3860 +
3861 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXArpRequestControl)) ) 
3862 +                               return -EFAULT;
3863 +
3864 +                       (ctl.val==0) ? (MAC_GLOB_CFG_REG &= (~(1 << 23)) ): (MAC_GLOB_CFG_REG |= (1 << 23) );
3865 +
3866 +               }
3867 +
3868 +               case CNS3XXX_ARP_REQUEST_GET:
3869 +               {
3870 +                       CNS3XXXArpRequestControl ctl;
3871 +
3872 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXArpRequestControl)) ) 
3873 +                               return -EFAULT;
3874 +
3875 +                       ctl.val = ((MAC_GLOB_CFG_REG >> 23) & 1);
3876 +
3877 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXArpRequestControl)) )  
3878 +                               return -EFAULT; 
3879 +                       return CAVM_OK;
3880 +               }
3881 +       
3882 +               case CNS3XXX_HOL_PREVENT_SET:
3883 +               {
3884 +                       CNS3XXXHOLPreventControl ctl;
3885 +
3886 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXHOLPreventControl)) ) 
3887 +                               return -EFAULT;
3888 +                       (ctl.enable == 1) ? (TC_CTRL_REG |= (1 << 29)) : (TC_CTRL_REG &= (~(1 << 29))) ;
3889 +
3890 +                       return CAVM_OK;
3891 +               }
3892 +               case CNS3XXX_HOL_PREVENT_GET:
3893 +               {
3894 +                       CNS3XXXHOLPreventControl ctl;
3895 +
3896 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXHOLPreventControl)) ) 
3897 +                               return -EFAULT;
3898 +
3899 +                       ctl.enable = ((TC_CTRL_REG >> 29) & 0x1);
3900 +
3901 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXHOLPreventControl)) )  
3902 +                               return -EFAULT; 
3903 +                       return CAVM_OK;
3904 +               }
3905 +
3906 +               // for S component or C conponent
3907 +               case CNS3XXX_BRIDGE_SET:
3908 +               {
3909 +                       CNS3XXXBridgeControl ctl;
3910 +
3911 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXBridgeControl)) ) 
3912 +                               return -EFAULT;
3913 +                       (ctl.type == 1) ? (VLAN_CFG |= (1 << 1)) : (VLAN_CFG &= (~(1 << 1))) ;
3914 +
3915 +
3916 +               }
3917 +               case CNS3XXX_BRIDGE_GET:
3918 +               {
3919 +                       CNS3XXXBridgeControl ctl;
3920 +
3921 +                       ctl.type = ((VLAN_CFG >> 1) & 0x1);
3922 +                       printk("[kernel mode] ctl.type: %d\n", ctl.type);
3923 +
3924 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXBridgeControl)) )  
3925 +                               return -EFAULT; 
3926 +
3927 +                       return CAVM_OK;
3928 +               }
3929 +
3930 +               case CNS3XXX_PORT_NEIGHBOR_SET:
3931 +               {
3932 +                       CNS3XXXPortNeighborControl ctl;
3933 +
3934 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPortNeighborControl)) ) 
3935 +                               return -EFAULT;
3936 +                       switch (ctl.which_port)
3937 +                       {
3938 +                               case 0:
3939 +                               {
3940 +                                       (ctl.type == 1) ? (VLAN_CFG |= (1 << 4)) : (VLAN_CFG &= (~(1 << 4))) ;
3941 +                                       return 0;
3942 +                               }
3943 +                               case 1:
3944 +                               {
3945 +                                       (ctl.type == 1) ? (VLAN_CFG |= (1 << 5)) : (VLAN_CFG &= (~(1 << 5))) ;
3946 +                                       return 0;
3947 +                               }
3948 +                               case 2:
3949 +                               {
3950 +                                       (ctl.type == 1) ? (VLAN_CFG |= (1 << 7)) : (VLAN_CFG &= (~(1 << 7))) ;
3951 +                                       return 0;
3952 +                               }
3953 +                               case 3: // cpu port
3954 +                               {
3955 +                                       (ctl.type == 1) ? (VLAN_CFG |= (1 << 6)) : (VLAN_CFG &= (~(1 << 6))) ;
3956 +                                       return 0;
3957 +                               }
3958 +                               default:
3959 +                                       return -EFAULT;
3960 +                       }
3961 +
3962 +               }
3963 +
3964 +               case CNS3XXX_PORT_NEIGHBOR_GET:
3965 +               {
3966 +                       CNS3XXXPortNeighborControl ctl;
3967 +
3968 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPortNeighborControl)) ) 
3969 +                               return -EFAULT;
3970 +                       switch (ctl.which_port)
3971 +                       {
3972 +                               case 0:
3973 +                               {
3974 +                                       ctl.type = ((VLAN_CFG >> 4 ) & 0x1);
3975 +                                       break;
3976 +                               }
3977 +                               case 1:
3978 +                               {
3979 +                                       ctl.type = ((VLAN_CFG >> 5 ) & 0x1);
3980 +                                       break;
3981 +                               }
3982 +                               case 2:
3983 +                               {
3984 +                                       ctl.type = ((VLAN_CFG >> 7 ) & 0x1);
3985 +                                       break;
3986 +                               }
3987 +                               case 3: // cpu port
3988 +                               {
3989 +                                       ctl.type = ((VLAN_CFG >> 6 ) & 0x1);
3990 +                                       break;
3991 +                               }
3992 +                       }
3993 +
3994 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXPortNeighborControl)) )  
3995 +                               return -EFAULT; 
3996 +
3997 +                       return CAVM_OK;
3998 +               }
3999 +
4000 +               case CNS3XXX_VLAN_TABLE_LOOKUP:
4001 +               {
4002 +                       CNS3XXXVLANTableEntry ctl;
4003 +
4004 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXVLANTableEntry)) ) 
4005 +                               return -EFAULT;
4006 +                       if (cns3xxx_vlan_table_lookup(&ctl.entry) ==  CAVM_NOT_FOUND) {
4007 +                               return CAVM_NOT_FOUND;
4008 +                       }
4009 +
4010 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXVLANTableEntry)))
4011 +                               return -EFAULT;
4012 +
4013 +                       return CAVM_FOUND;
4014 +               }
4015 +               case CNS3XXX_VLAN_TABLE_READ:
4016 +               {
4017 +                       CNS3XXXVLANTableEntry ctl;
4018 +
4019 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXVLANTableEntry)) ) 
4020 +                       {
4021 +                               return -EFAULT;
4022 +                       }
4023 +                       cns3xxx_vlan_table_read(&ctl.entry);
4024 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXVLANTableEntry)))
4025 +                               return -EFAULT;
4026 +
4027 +                       return 0;
4028 +               }
4029 +               case CNS3XXX_VLAN_TABLE_ADD:
4030 +               {       
4031 +                       CNS3XXXVLANTableEntry ctl;
4032 +
4033 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXVLANTableEntry)) ) 
4034 +                               return -EFAULT;
4035 +                       cns3xxx_vlan_table_add(&ctl.entry);
4036 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXVLANTableEntry)))
4037 +                               return -EFAULT;
4038 +
4039 +                       return 0;
4040 +               }
4041 +
4042 +               case CNS3XXX_ARL_TABLE_ADD:
4043 +               {       
4044 +                       CNS3XXXARLTableEntry ctl;
4045 +
4046 +                       printk("[kernel mode] CNS3XXX_ARL_TABLE_ADD\n");
4047 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4048 +                               return -EFAULT;
4049 +                       cns3xxx_arl_table_add(&ctl.entry);
4050 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4051 +                               return -EFAULT;
4052 +
4053 +                       return 0;
4054 +               }
4055 +
4056 +
4057 +               case CNS3XXX_ARL_TABLE_DEL:
4058 +               {       
4059 +                       CNS3XXXARLTableEntry ctl;
4060 +
4061 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4062 +                               return -EFAULT;
4063 +                       cns3xxx_arl_table_invalid(&ctl.entry);
4064 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4065 +                               return -EFAULT;
4066 +
4067 +                       return 0;
4068 +               }
4069 +               case CNS3XXX_VLAN_TABLE_DEL:
4070 +               {       
4071 +                       CNS3XXXARLTableEntry ctl;
4072 +
4073 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4074 +                               return -EFAULT;
4075 +                       cns3xxx_arl_table_invalid(&ctl.entry);
4076 +
4077 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4078 +                               return -EFAULT;
4079 +
4080 +                       return CAVM_FOUND;
4081 +               }
4082 +
4083 +               case CNS3XXX_ARL_TABLE_SEARCH:
4084 +               {       
4085 +                       CNS3XXXARLTableEntry ctl;
4086 +
4087 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4088 +                               return -EFAULT;
4089 +                       if (cns3xxx_arl_table_search(&ctl.entry) == CAVM_NOT_FOUND){
4090 +                               printk("[kernel mode] not found\n");
4091 +                               return CAVM_NOT_FOUND;
4092 +                       }
4093 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4094 +                               return -EFAULT;
4095 +
4096 +                       return CAVM_FOUND;
4097 +               }
4098 +               case CNS3XXX_ARL_IS_TABLE_END:
4099 +               {       
4100 +                       CNS3XXXARLTableEntry ctl;
4101 +
4102 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4103 +                               return -EFAULT;
4104 +                       if (cns3xxx_is_arl_table_end() == CAVM_ERR)
4105 +                               return CAVM_ERR;
4106 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4107 +                               return -EFAULT;
4108 +
4109 +                       return CAVM_OK;
4110 +               }
4111 +
4112 +               case CNS3XXX_ARL_TABLE_SEARCH_AGAIN:
4113 +               {       
4114 +                       CNS3XXXARLTableEntry ctl;
4115 +
4116 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4117 +                               return -EFAULT;
4118 +                       if (cns3xxx_arl_table_search_again(&ctl.entry) == CAVM_NOT_FOUND)
4119 +                               return CAVM_NOT_FOUND;
4120 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4121 +                               return -EFAULT;
4122 +
4123 +                       return CAVM_FOUND;
4124 +               }
4125 +
4126 +               case CNS3XXX_ARL_TABLE_FLUSH:
4127 +               {       
4128 +                       CNS3XXXARLTableEntry ctl;
4129 +
4130 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4131 +                               return -EFAULT;
4132 +
4133 +                       cns3xxx_arl_table_flush();
4134 +
4135 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4136 +                               return -EFAULT;
4137 +
4138 +                       return CAVM_FOUND;
4139 +               }
4140 +
4141 +
4142 +
4143 +               case CNS3XXX_ARL_TABLE_LOOKUP:
4144 +               {       
4145 +                       CNS3XXXARLTableEntry ctl;
4146 +
4147 +               
4148 +                       printk("[kernel mode] in CNS3XXX_ARL_TABLE_LOOKUP\n");
4149 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXARLTableEntry)) ) 
4150 +                               return -EFAULT;
4151 +                       if (cns3xxx_arl_table_lookup(&ctl.entry) == CAVM_NOT_FOUND)
4152 +                               return CAVM_NOT_FOUND;
4153 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXARLTableEntry)))
4154 +                               return -EFAULT;
4155 +
4156 +                       return CAVM_FOUND;
4157 +               }
4158 +
4159 +               case CNS3XXX_TC_SET:
4160 +               {       
4161 +                       CNS3XXXTrafficClassControl ctl;
4162 +
4163 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXTrafficClassControl)) ) 
4164 +                               return -EFAULT;
4165 +                       TC_CTRL_REG &= (~(0x3 << 30));
4166 +                       TC_CTRL_REG |= (ctl.tc << 30);
4167 +                       return CAVM_OK;
4168 +               }
4169 +               case CNS3XXX_TC_GET:
4170 +               {
4171 +                       CNS3XXXTrafficClassControl ctl;
4172 +
4173 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXTrafficClassControl)) ) 
4174 +                               return -EFAULT;
4175 +
4176 +                       ctl.tc = ((TC_CTRL_REG >> 30) & 0x3);
4177 +
4178 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXTrafficClassControl)) )  
4179 +                               return -EFAULT; 
4180 +
4181 +                       return CAVM_OK;
4182 +               }
4183 +
4184 +               case CNS3XXX_PRI_CTRL_SET:
4185 +               {
4186 +                       CNS3XXXPriCtrlControl ctl;
4187 +
4188 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPriCtrlControl)) ) 
4189 +                               return -EFAULT;
4190 +
4191 +                       switch (ctl.which_port)
4192 +                       {
4193 +                               case 0:
4194 +                               {
4195 +                                       MAC0_PRI_CTRL_REG &= (~(0x7 << 24));
4196 +                                       MAC0_PRI_CTRL_REG &= (~(0xf << 18));
4197 +                                       
4198 +                                       MAC0_PRI_CTRL_REG |= (ctl.port_pri << 24);
4199 +
4200 +                                       MAC0_PRI_CTRL_REG |= (ctl.ether_pri_en << 18);
4201 +                                       MAC0_PRI_CTRL_REG |= (ctl.vlan_pri_en << 19);
4202 +                                       MAC0_PRI_CTRL_REG |= (ctl.dscp_pri_en << 20);
4203 +                                       MAC0_PRI_CTRL_REG |= (ctl.udp_pri_en << 21);
4204 +                                       break;
4205 +                               }
4206 +                               case 1:
4207 +                               {
4208 +                                       MAC1_PRI_CTRL_REG &= (~(0x7 << 24));
4209 +                                       MAC1_PRI_CTRL_REG &= (~(0xf << 18));
4210 +                                       
4211 +                                       MAC1_PRI_CTRL_REG |= (ctl.port_pri << 24);
4212 +
4213 +                                       MAC1_PRI_CTRL_REG |= (ctl.ether_pri_en << 18);
4214 +                                       MAC1_PRI_CTRL_REG |= (ctl.vlan_pri_en << 19);
4215 +                                       MAC1_PRI_CTRL_REG |= (ctl.dscp_pri_en << 20);
4216 +                                       MAC1_PRI_CTRL_REG |= (ctl.udp_pri_en << 21);
4217 +                                       break;
4218 +                               }
4219 +                               case 2:
4220 +                               {
4221 +                                       MAC2_PRI_CTRL_REG &= (~(0x7 << 24));
4222 +                                       MAC2_PRI_CTRL_REG &= (~(0xf << 18));
4223 +                                       
4224 +                                       MAC2_PRI_CTRL_REG |= (ctl.port_pri << 24);
4225 +
4226 +                                       MAC2_PRI_CTRL_REG |= (ctl.ether_pri_en << 18);
4227 +                                       MAC2_PRI_CTRL_REG |= (ctl.vlan_pri_en << 19);
4228 +                                       MAC2_PRI_CTRL_REG |= (ctl.dscp_pri_en << 20);
4229 +                                       MAC2_PRI_CTRL_REG |= (ctl.udp_pri_en << 21);
4230 +                                       break;
4231 +                               }
4232 +                               case 3: // cpu
4233 +                               {
4234 +                                       printk("[kernel mode] CPU_PRI_CTRL_REG: %#x\n", CPU_PRI_CTRL_REG);
4235 +                                       CPU_PRI_CTRL_REG &= (~(0x7 << 24));
4236 +                                       CPU_PRI_CTRL_REG &= (~(0xf << 18));
4237 +                                       
4238 +                                       CPU_PRI_CTRL_REG |= (ctl.port_pri << 24);
4239 +
4240 +                                       CPU_PRI_CTRL_REG |= (ctl.ether_pri_en << 18);
4241 +                                       CPU_PRI_CTRL_REG |= (ctl.vlan_pri_en << 19);
4242 +                                       CPU_PRI_CTRL_REG |= (ctl.dscp_pri_en << 20);
4243 +                                       CPU_PRI_CTRL_REG |= (ctl.udp_pri_en << 21);
4244 +                                       break;
4245 +                               }
4246 +                       }
4247 +
4248 +                       return CAVM_OK;
4249 +               }
4250 +
4251 +               case CNS3XXX_PRI_CTRL_GET:
4252 +               {
4253 +                       CNS3XXXPriCtrlControl ctl;
4254 +
4255 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXPriCtrlControl)) ) 
4256 +                               return -EFAULT;
4257 +
4258 +
4259 +                       if (copy_to_user(ifr->ifr_data, &ctl, sizeof(CNS3XXXPriCtrlControl)) )  
4260 +                               return -EFAULT; 
4261 +
4262 +                       return CAVM_OK;
4263 +               }
4264 +
4265 +               case CNS3XXX_DMA_RING_CTRL_SET:
4266 +               {
4267 +                       CNS3XXXDmaRingCtrlControl ctl;
4268 +
4269 +                       if (copy_from_user(&ctl, ifr->ifr_data, sizeof(CNS3XXXDmaRingCtrlControl)) ) 
4270 +                               return -EFAULT;
4271 +
4272 +                       (ctl.ts_double_ring_en == 0) ? DMA_RING_CTRL_REG &= (~(0x1 << 16)) : (DMA_RING_CTRL_REG |= (ctl.ts_double_ring_en << 16));
4273 +                       (ctl.fs_double_ring_en == 0) ? DMA_RING_CTRL_REG &= (~(0x1 << 0)) : (DMA_RING_CTRL_REG |= (ctl.fs_double_ring_en << 0));
4274 +                       (ctl.fs_pkt_allocate == 0) ? DMA_RING_CTRL_REG &= (~(0x1 << 1)) : (DMA_RING_CTRL_REG |= (ctl.fs_pkt_allocate << 1));
4275 +               }
4276 +
4277 +               case CNS3XXX_PRI_IP_DSCP_SET:
4278 +               {
4279 +                       return set_pri_ip_dscp(ifr);
4280 +               }
4281 +               case CNS3XXX_PRI_IP_DSCP_GET:
4282 +               {
4283 +                       return get_pri_ip_dscp(ifr);
4284 +               }
4285 +
4286 +               case CNS3XXX_ETYPE_SET:
4287 +               {
4288 +                       return set_etype(ifr);
4289 +               }
4290 +               case CNS3XXX_ETYPE_GET:
4291 +               {
4292 +                       return get_etype(ifr);
4293 +               }
4294 +
4295 +               case CNS3XXX_UDP_RANGE_SET:
4296 +               {
4297 +                       return set_udp_range(ifr);
4298 +               }
4299 +               case CNS3XXX_UDP_RANGE_GET:
4300 +               {
4301 +                       return get_udp_range(ifr);
4302 +               }
4303 +
4304 +               case CNS3XXX_RATE_LIMIT_SET:
4305 +               {
4306 +                       return set_rate_limit(ifr);
4307 +               }
4308 +               case CNS3XXX_RATE_LIMIT_GET:
4309 +               {
4310 +                       return get_rate_limit(ifr);
4311 +               }
4312 +               case CNS3XXX_QUEUE_WEIGHT_SET:
4313 +               {
4314 +                       return set_queue_weight(ifr);
4315 +               }
4316 +               case CNS3XXX_QUEUE_WEIGHT_GET:
4317 +               {
4318 +                       return get_queue_weight(ifr);
4319 +               }
4320 +
4321 +               case CNS3XXX_FC_RLS_SET:
4322 +               {
4323 +                       return set_fc_rls(ifr);
4324 +               }
4325 +               case CNS3XXX_FC_RLS_GET:
4326 +               {
4327 +                       return get_fc_rls(ifr);
4328 +               }
4329 +
4330 +               case CNS3XXX_FC_SET_SET:
4331 +               {
4332 +                       return set_fc_set(ifr);
4333 +               }
4334 +               case CNS3XXX_FC_SET_GET:
4335 +               {
4336 +                       return get_fc_set(ifr);
4337 +               }
4338 +
4339 +               case CNS3XXX_SARL_RLS_SET:
4340 +               {
4341 +                       return set_sarl_rls(ifr);
4342 +               }
4343 +               case CNS3XXX_SARL_RLS_GET:
4344 +               {
4345 +                       return get_sarl_rls(ifr);
4346 +               }
4347 +
4348 +               case CNS3XXX_SARL_SET_SET:
4349 +               {
4350 +                       return set_sarl_set(ifr);
4351 +               }
4352 +               case CNS3XXX_SARL_SET_GET:
4353 +               {
4354 +                       return get_sarl_set(ifr);
4355 +               }
4356 +
4357 +               case CNS3XXX_SARL_OQ_SET:
4358 +               {
4359 +                       return set_sarl_oq(ifr);
4360 +               }
4361 +               case CNS3XXX_SARL_OQ_GET:
4362 +               {
4363 +                       return get_sarl_oq(ifr);
4364 +               }
4365 +
4366 +               case CNS3XXX_SARL_ENABLE_SET:
4367 +               {
4368 +                       return set_sarl_enable(ifr);
4369 +               }
4370 +               case CNS3XXX_SARL_ENABLE_GET:
4371 +               {
4372 +                       return get_sarl_enable(ifr);
4373 +               }
4374 +
4375 +               case CNS3XXX_FC_SET:
4376 +               {
4377 +                       return set_fc(ifr);
4378 +               }
4379 +               case CNS3XXX_FC_GET:
4380 +               {
4381 +                       return get_fc(ifr);
4382 +               }
4383 +
4384 +               case CNS3XXX_IVL_SET:
4385 +               {
4386 +                       return set_ivl(ifr);
4387 +               }
4388 +               case CNS3XXX_IVL_GET:
4389 +               {
4390 +                       return get_ivl(ifr);
4391 +               }
4392 +
4393 +               case CNS3XXX_WAN_PORT_SET:
4394 +               {
4395 +                       return set_wan_port(ifr);
4396 +               }
4397 +               case CNS3XXX_WAN_PORT_GET:
4398 +               {
4399 +                       return get_wan_port(ifr);
4400 +               }
4401 +
4402 +               case CNS3XXX_PVID_SET:
4403 +               {
4404 +                       return set_pvid(ifr);
4405 +               }
4406 +               case CNS3XXX_PVID_GET:
4407 +               {
4408 +                       return get_pvid(ifr);
4409 +               }
4410 +
4411 +               case CNS3XXX_QA_GET:
4412 +               {
4413 +                       return get_qa(ifr);
4414 +               }
4415 +               case CNS3XXX_QA_SET:
4416 +               {
4417 +                       return set_qa(ifr);
4418 +               }
4419 +
4420 +               case CNS3XXX_PACKET_MAX_LEN_GET:
4421 +               {
4422 +                       return get_packet_max_len(ifr);
4423 +               }
4424 +               case CNS3XXX_PACKET_MAX_LEN_SET:
4425 +               {
4426 +                       return set_packet_max_len(ifr);
4427 +               }
4428 +
4429 +               case CNS3XXX_BCM53115M_REG_READ:
4430 +               {
4431 +                       return bcm53115M_reg_read_ioctl(ifr);
4432 +               }
4433 +               case CNS3XXX_BCM53115M_REG_WRITE:
4434 +               {
4435 +                       return bcm53115M_reg_write_ioctl(ifr);
4436 +               }
4437 +
4438 +#if 0
4439 +               case CNS3XXX_RXRING_STATUS:
4440 +               {
4441 +                       return get_rxring(ifr);
4442 +               }
4443 +#endif
4444 +               case CNS3XXX_DUMP_MIB_COUNTER:
4445 +               {
4446 +                       return dump_mib_counter(ifr);
4447 +               }
4448 +       
4449 +
4450 +               default:
4451 +               {
4452 +                       printk("[kernel mode] don't match any command\n");
4453 +                       break;
4454 +               }
4455 +
4456 +       } // end switch (ioctl_cmd) 
4457 +       return 0;
4458 +}
4459 +
4460 +#ifdef CONFIG_CNS3XXX_NAPI
4461 +static int cns3xxx_poll(struct napi_struct *napi, int budget)
4462 +{
4463 +
4464 +       CNS3XXXPrivate *sp = container_of(napi, CNS3XXXPrivate, napi);
4465 +       int work_done = 0;
4466 +       int work_to_do = budget; // define minima value
4467 +
4468 +       cns3xxx_receive_packet(sp, 0, &work_done, work_to_do);
4469 +
4470 +       budget -= work_done;
4471 +
4472 +        if (work_done) {
4473 +               if (test_bit(0, (unsigned long *)&sp->is_qf) == 1){
4474 +                       clear_bit(0, (unsigned long *)&sp->is_qf);
4475 +                       enable_rx_dma(sp->ring_index, 1);
4476 +                       return 1;
4477 +               }
4478 +        } else {
4479 +               //netif_rx_complete(napi_dev, &sp->napi);
4480 +               napi_complete(napi);
4481 +#ifdef CNS3XXX_USE_MASK
4482 +               cns3xxx_write_pri_mask(0xf0);
4483 +#else
4484 +       if (sp->ring_index == 0)
4485 +               cns3xxx_enable_irq(FSRC_RING0_INTERRUPT_ID);
4486 +       else
4487 +               cns3xxx_enable_irq(FSRC_RING1_INTERRUPT_ID);
4488 +#endif
4489 +            return 0;
4490 +        }
4491 +
4492 +       return 1;
4493 +}
4494 +#endif
4495 +
4496 +static struct net_device_stats *cns3xxx_get_stats(struct net_device *dev)
4497 +{
4498 +       CNS3XXXPrivate *priv = netdev_priv(dev);
4499 +
4500 +       return &priv->stats;
4501 +}
4502 +
4503 +static int cns3xxx_change_mtu(struct net_device *dev, int new_mtu)
4504 +{
4505 +       if (new_mtu < cns3xxx_min_mtu() || new_mtu > cns3xxx_max_mtu())
4506 +               return -EINVAL;
4507 +
4508 +       dev->mtu = new_mtu;
4509 +
4510 +       return 0;
4511 +}
4512 +
4513 +static void cns3xxx_timeout(struct net_device *dev)
4514 +{
4515 +       //star_gsw_enable(dev);
4516 +       netif_wake_queue(dev);
4517 +       dev->trans_start = jiffies;
4518 +}
4519 +
4520 +#ifdef LINUX2631
4521 +static const struct net_device_ops cns3xxx_netdev_ops = {
4522 +        .ndo_open               = cns3xxx_open,
4523 +        .ndo_stop               = cns3xxx_close,
4524 +        .ndo_start_xmit         = cns3xxx_send_packet,
4525 +        //.ndo_validate_addr      = eth_validate_addr,
4526 +        //.ndo_set_multicast_list = cns3xxx_set_multicast_list,
4527 +        .ndo_set_mac_address    = cns3xxx_set_mac_addr,
4528 +        .ndo_change_mtu         = cns3xxx_change_mtu,
4529 +        .ndo_do_ioctl           = cns3xxx_do_ioctl,
4530 +        .ndo_tx_timeout         = cns3xxx_timeout,
4531 +       .ndo_get_stats          = cns3xxx_get_stats,
4532 +
4533 +#if defined(CNS3XXX_VLAN_8021Q)
4534 +        .ndo_vlan_rx_register   = cns3xxx_vlan_rx_register,
4535 +        //.ndo_vlan_rx_add_vid    = e1000_vlan_rx_add_vid,
4536 +        .ndo_vlan_rx_kill_vid   = cns3xxx_vlan_rx_kill_vid,
4537 +#endif
4538 +
4539 +#ifdef CONFIG_NET_POLL_CONTROLLER
4540 +        .ndo_poll_controller    = cns3xxx_netpoll,
4541 +#endif
4542 +};
4543 +#endif // LINUX2631
4544 +
4545 +static int __init cns3xxx_probe(RingInfo ring_info)
4546 +{
4547 +       void cns3xxx_set_ethtool_ops(struct net_device *netdev);
4548 +
4549 +       int netdev_size = sizeof(net_device_prive)/sizeof(NetDevicePriv);
4550 +       int i=0, err=0;
4551 +       struct net_device *netdev=0;
4552 +       CNS3XXXPrivate *priv=0;
4553 +        struct sockaddr sock_addr;
4554 +
4555 +       for (i=0 ; i < netdev_size ; ++i) {
4556 +               if (init_port & (1 << i)) {
4557 +
4558 +               netdev = alloc_etherdev(sizeof(CNS3XXXPrivate));
4559 +               if (!netdev) {
4560 +                       err = -ENOMEM;
4561 +                       goto err_alloc_etherdev;
4562 +               }
4563 +               if (net_device_prive[i].name)
4564 +                       strcpy(netdev->name, net_device_prive[i].name);
4565 +
4566 +
4567 +               net_dev_array[net_device_prive[i].vlan_tag] = netdev;
4568 +               if (intr_netdev==0)
4569 +                       intr_netdev = netdev;
4570 +
4571 +               SET_NETDEV_DEV(netdev, NULL);
4572 +               priv = netdev_priv(netdev);
4573 +               spin_lock_init(&priv->lock);
4574 +               memset(priv, 0, sizeof(CNS3XXXPrivate));
4575 +
4576 +#if 1
4577 +               priv->num_rx_queues = ring_info.num_rx_queues;
4578 +               priv->num_tx_queues = ring_info.num_tx_queues;
4579 +               priv->rx_ring = ring_info.rx_ring;
4580 +               priv->tx_ring = ring_info.tx_ring;
4581 +#endif
4582 +
4583 +               priv->net_device_priv = &net_device_prive[i];
4584 +
4585 +               // set netdev MAC address
4586 +               memcpy(sock_addr.sa_data, net_device_prive[i].mac, 6);
4587 +               cns3xxx_set_mac_addr(netdev, &sock_addr);
4588 +
4589 +#ifdef LINUX2631
4590 +               netdev->netdev_ops = &cns3xxx_netdev_ops;
4591 +#endif
4592 +
4593 +               cns3xxx_set_ethtool_ops(netdev);
4594 +#ifdef LINUX2627
4595 +               //netdev->base_addr             = IO_ADDRESS(GSW_BASE_ADDR);
4596 +               netdev->base_addr = 0;
4597 +               netdev->open = cns3xxx_open;
4598 +               netdev->stop = cns3xxx_close;
4599 +               netdev->hard_start_xmit = cns3xxx_send_packet;
4600 +               //netdev->hard_start_xmit       = 0;
4601 +               netdev->do_ioctl = cns3xxx_do_ioctl;
4602 +               netdev->change_mtu = cns3xxx_change_mtu;
4603 +
4604 +               //netdev->get_stats = cns3xxx_get_stats;
4605 +               netdev->watchdog_timeo = 5 * HZ; // ref e1000_main.c
4606 +               netdev->tx_timeout = cns3xxx_timeout;
4607 +               netdev->set_mac_address = cns3xxx_set_mac_addr;
4608 +#endif
4609 +
4610 +#if defined(CNS3XXX_TX_HW_CHECKSUM)
4611 +               netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG);
4612 +               //netdev->features |= (NETIF_F_HW_CSUM | NETIF_F_SG);
4613 +#endif
4614 +
4615 +
4616 +#ifdef CONFIG_CNS3XXX_NAPI
4617 +               //netif_napi_add(netdev, &priv->napi, cns3xxx_poll, CNS3XXX_NAPI_WEIGHT);
4618 +#endif
4619 +
4620 +#if defined(CNS3XXX_VLAN_8021Q)
4621 +               // do not let 8021Q module insert vlan tag
4622 +               // can use the snippet code to get vlan tage
4623 +               // if (priv->vlgrp && vlan_tx_tag_present(skb)) 
4624 +               //   vlan_tag = cpu_to_be16(vlan_tx_tag_get(skb));
4625 +#ifdef CNS3XXX_8021Q_HW_TX
4626 +               // hardware support insert VLAN tag on TX path
4627 +               netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
4628 +#else
4629 +               netdev->features |= NETIF_F_HW_VLAN_RX; // remove NETIF_F_HW_VLAN_TX flag that 8021Q module to insert vlan tag.
4630 +#endif
4631 +
4632 +               //netdev->vlan_rx_register = cns3xxx_vlan_rx_register;
4633 +               //netdev->vlan_rx_kill_vid = cns3xxx_vlan_rx_kill_vid;
4634 +#endif
4635 +
4636 +
4637 +               err = register_netdev(netdev);
4638 +               if (err) {
4639 +                       goto err_register_netdev;
4640 +               }
4641 +
4642 +               netif_carrier_off(netdev);
4643 +               netdev = 0;
4644 +               }
4645 +       } // for (i=0 ; i < netdev_size ; ++i) 
4646 +
4647 +       return 0;
4648 +
4649 +
4650 +err_register_netdev:
4651 +       free_netdev(netdev);
4652 +
4653 +err_alloc_etherdev:
4654 +       return err;
4655 +}
4656 +
4657 +int cns3xxx_gsw_config_mac_port0(void)
4658 +{
4659 +       INIT_PORT0_PHY
4660 +       INIT_PORT0_MAC
4661 +       PORT0_LINK_DOWN
4662 +       return 0;
4663 +}
4664 +
4665 +int cns3xxx_gsw_config_mac_port1(void)
4666 +{
4667 +       INIT_PORT1_PHY
4668 +       INIT_PORT1_MAC
4669 +       PORT1_LINK_DOWN
4670 +       return 0;
4671 +}
4672 +
4673 +int cns3xxx_gsw_config_mac_port2(void)
4674 +{
4675 +       INIT_PORT2_PHY
4676 +       INIT_PORT2_MAC
4677 +       PORT2_LINK_DOWN
4678 +       return 0;
4679 +}
4680 +
4681 +static int cns3xxx_notify_reboot(struct notifier_block *nb, unsigned long event, void *ptr)
4682 +{
4683 +       // stop the DMA
4684 +       enable_rx_dma(0, 0);
4685 +       enable_tx_dma(0, 0);
4686 +       enable_rx_dma(1, 0);
4687 +       enable_tx_dma(1, 0);
4688 +
4689 +       // disable Port 0
4690 +       enable_port(0, 0); 
4691 +       enable_port(1, 0); 
4692 +       enable_port(2, 0); 
4693 +       enable_port(3, 0); 
4694 +       return NOTIFY_DONE;
4695 +}
4696 +
4697 +#ifdef CONFIG_CNS3XXX_NAPI
4698 +static struct net_device *init_napi_dev(struct net_device *ndev, const RingInfo *ring_info)
4699 +{
4700 +       CNS3XXXPrivate *priv;
4701 +
4702 +       ndev = alloc_etherdev(sizeof(CNS3XXXPrivate));
4703 +       if (!ndev) {
4704 +               BUG();
4705 +       }
4706 +       priv = netdev_priv(ndev);
4707 +       memset(priv, 0, sizeof(CNS3XXXPrivate));
4708 +
4709 +       //priv = netdev_priv(napi_dev);
4710 +       priv->num_rx_queues = ring_info->num_rx_queues;
4711 +       priv->num_tx_queues = ring_info->num_tx_queues;
4712 +       priv->rx_ring = ring_info->rx_ring;
4713 +       priv->tx_ring = ring_info->tx_ring;
4714 +       //priv->is_qf=0; // because of memset, so need not the line
4715 +
4716 +       netif_napi_add(ndev, &priv->napi , cns3xxx_poll, CNS3XXX_NAPI_WEIGHT);
4717 +        dev_hold(ndev);
4718 +       set_bit(__LINK_STATE_START, &ndev->state);
4719 +
4720 +       return ndev;
4721 +}
4722 +#endif
4723 +
4724 +
4725 +void cns3xxx_config_intr(void)
4726 +{
4727 +       u32 v=0xffffffff;
4728 +
4729 +       get_interrupt_type(FSRC_RING0_INTERRUPT_ID, &v);
4730 +#if 1
4731 +       set_interrupt_type(FSRC_RING0_INTERRUPT_ID, RISING_EDGE);
4732 +       get_interrupt_type(FSRC_RING0_INTERRUPT_ID, &v);
4733 +
4734 +       get_interrupt_type(FSRC_RING1_INTERRUPT_ID, &v);
4735 +       set_interrupt_type(FSRC_RING1_INTERRUPT_ID, RISING_EDGE);
4736 +       get_interrupt_type(FSRC_RING1_INTERRUPT_ID, &v);
4737 +
4738 +       get_interrupt_type(FSQF_RING0_INTERRUPT_ID, &v);
4739 +       set_interrupt_type(FSQF_RING0_INTERRUPT_ID, RISING_EDGE);
4740 +       get_interrupt_type(FSQF_RING0_INTERRUPT_ID, &v);
4741 +
4742 +       get_interrupt_type(FSQF_RING1_INTERRUPT_ID, &v);
4743 +       set_interrupt_type(FSQF_RING1_INTERRUPT_ID, RISING_EDGE);
4744 +       get_interrupt_type(FSQF_RING1_INTERRUPT_ID, &v);
4745 +
4746 +       #ifdef CNS3XXX_USE_MASK
4747 +               get_interrupt_pri(FSRC_RING0_INTERRUPT_ID, &v);
4748 +               set_interrupt_pri(FSRC_RING0_INTERRUPT_ID, 0xc);
4749 +               get_interrupt_pri(FSRC_RING0_INTERRUPT_ID, &v);
4750 +
4751 +               get_interrupt_pri(FSRC_RING1_INTERRUPT_ID, &v);
4752 +               set_interrupt_pri(FSRC_RING1_INTERRUPT_ID, 0xc);
4753 +               get_interrupt_pri(FSRC_RING1_INTERRUPT_ID, &v);
4754 +
4755 +               get_interrupt_pri(FSQF_RING1_INTERRUPT_ID, &v);
4756 +               set_interrupt_pri(FSQF_RING1_INTERRUPT_ID, 0xc);
4757 +               get_interrupt_pri(FSQF_RING1_INTERRUPT_ID, &v);
4758 +
4759 +       #ifndef CONFIG_CNS3XXX_NAPI
4760 +               set_interrupt_pri(FSQF_RING0_INTERRUPT_ID, 0xc);
4761 +       #endif
4762 +       
4763 +
4764 +       #endif // CNS3XXX_USE_MASK
4765 +#endif
4766 +}
4767 +
4768 +static int __devinit cns3xxx_init(struct platform_device *pdev)
4769 +{
4770 +       // when tx_ring/rx_ring alloc memory, 
4771 +       // don't free them until cns3xxx_exit_module
4772 +
4773 +       struct eth_plat_info *plat = pdev->dev.platform_data;
4774 +       init_port = plat->ports;
4775 +       memcpy(cpu_vlan_table_entry.my_mac, plat->cpu_hwaddr, ETH_ALEN);
4776 +#if defined (CONFIG_CNS3XXX_SPPE)
4777 +       memcpy(net_device_prive[3].mac, plat->cpu_hwaddr, ETH_ALEN);
4778 +#endif
4779 +
4780 +       RingInfo ring_info; 
4781 +       int i=0;
4782 +       //spin_lock_init(&star_gsw_send_lock);
4783 +
4784 +
4785 +#ifdef CNS3XXX_DOUBLE_RX_RING
4786 +        ring_info.num_rx_queues = 2;
4787 +#else
4788 +        ring_info.num_rx_queues = 1;
4789 +#endif
4790 +
4791 +#ifdef CNS3XXX_DOUBLE_TX_RING
4792 +        ring_info.num_tx_queues = 2;
4793 +#else
4794 +        ring_info.num_tx_queues = 1;
4795 +#endif
4796 +
4797 +       ring_info.rx_ring = kcalloc(ring_info.num_rx_queues, sizeof(RXRing), GFP_KERNEL);
4798 +       if (!ring_info.rx_ring)
4799 +               return -ENOMEM;
4800 +       
4801 +       for (i=0 ; i < ring_info.num_rx_queues ; ++i) {
4802 +               memset(ring_info.rx_ring + i, 0, sizeof(RXRing));
4803 +       }
4804 +
4805 +
4806 +       ring_info.tx_ring = kcalloc(ring_info.num_tx_queues, sizeof(TXRing), GFP_KERNEL);
4807 +
4808 +
4809 +       if (!ring_info.tx_ring)
4810 +               return -ENOMEM;
4811 +
4812 +       for (i=0 ; i < ring_info.num_tx_queues ; ++i) {
4813 +               memset(ring_info.tx_ring + i, 0, sizeof(TXRing));
4814 +       }
4815 +
4816 +
4817 +       g_ring_info = ring_info;
4818 +
4819 +       cns3xxx_gsw_hw_init();
4820 +
4821 +#ifdef CONFIG_FPGA
4822 +       // GIGA mode disable
4823 +       MAC0_CFG_REG &= (~(1<<16));
4824 +       MAC1_CFG_REG &= (~(1<<16));
4825 +       MAC2_CFG_REG &= (~(1<<16));
4826 +#endif
4827 +
4828 +       if ((init_port & 1) == 1) {
4829 +               memcpy(vlan_table_entry[0].my_mac, plat->eth0_hwaddr, ETH_ALEN);
4830 +               memcpy(arl_table_entry[0].mac, plat->eth0_hwaddr, ETH_ALEN);
4831 +               memcpy(net_device_prive[0].mac, plat->eth0_hwaddr, ETH_ALEN);
4832 +               cns3xxx_gsw_config_mac_port0();
4833 +       }
4834 +
4835 +       if (((init_port >> 1) & 1) == 1) {
4836 +               memcpy(vlan_table_entry[1].my_mac, plat->eth1_hwaddr, ETH_ALEN);
4837 +               memcpy(arl_table_entry[1].mac, plat->eth1_hwaddr, ETH_ALEN);
4838 +               memcpy(net_device_prive[1].mac, plat->eth1_hwaddr, ETH_ALEN);
4839 +               cns3xxx_gsw_config_mac_port1();
4840 +       }
4841 +
4842 +       if (((init_port >> 2) & 1) == 1) {
4843 +               memcpy(vlan_table_entry[2].my_mac, plat->eth2_hwaddr, ETH_ALEN);
4844 +               memcpy(arl_table_entry[2].mac, plat->eth2_hwaddr, ETH_ALEN);
4845 +               memcpy(net_device_prive[2].mac, plat->eth2_hwaddr, ETH_ALEN);
4846 +               cns3xxx_gsw_config_mac_port2();
4847 +       }
4848 +
4849 +       cns3xxx_probe(ring_info);
4850 +       cns3xxx_config_intr();
4851 +
4852 +#ifdef CNS3XXX_VLAN_8021Q
4853 +#ifdef CNS3XXX_NIC_MODE_8021Q
4854 +       cns3xxx_nic_mode(1);
4855 +#endif
4856 +#endif
4857 +       spin_lock_init(&tx_lock);
4858 +       spin_lock_init(&rx_lock);
4859 +
4860 +#ifdef CONFIG_CNS3XXX_NAPI
4861 +       napi_dev = init_napi_dev(napi_dev, &ring_info);
4862 +       #ifdef CNS3XXX_DOUBLE_RX_RING
4863 +       r1_napi_dev = init_napi_dev(r1_napi_dev, &ring_info);
4864 +       #endif
4865 +#endif
4866 +
4867 +       register_reboot_notifier(&cns3xxx_notifier_reboot);
4868 +       clear_fs_dma_state(0);
4869 +
4870 +       if (ring_info.num_rx_queues == 2) {
4871 +               // enable RX dobule ring
4872 +               DMA_RING_CTRL_REG |= 1;
4873 +       }
4874 +
4875 +       if (ring_info.num_tx_queues == 2 ) {
4876 +               // enable TX dobule ring
4877 +               DMA_RING_CTRL_REG |= (1 << 16);
4878 +       }
4879 +
4880 +
4881 +       return 0;
4882 +}
4883 +
4884 +static int __devexit cns3xxx_remove(struct platform_device *pdev)
4885 +{
4886 +       int i=0;
4887 +
4888 +#if 1
4889 +       for (i=0 ; i < NETDEV_SIZE ; ++i) {
4890 +               CNS3XXXPrivate *priv = 0;
4891 +
4892 +               if (net_dev_array[i]){
4893 +                       priv = netdev_priv(net_dev_array[i]);
4894 +
4895 +                       kfree(priv->tx_ring);
4896 +                       priv->tx_ring = 0;
4897 +
4898 +                       kfree(priv->rx_ring);
4899 +                       priv->rx_ring = 0;
4900 +
4901 +                       unregister_netdev(net_dev_array[i]);
4902 +                       free_netdev(net_dev_array[i]);
4903 +               }
4904 +
4905 +
4906 +#if 0
4907 +               sprintf(netdev_name, "eth%d", i);
4908 +               netdev=__dev_get_by_name(&init_net, netdev_name);
4909 +               // if no unregister_netdev and free_netdev,
4910 +               // after remove module, ifconfig will hang.
4911 +               #if 1
4912 +               if (netdev) {
4913 +                       unregister_netdev(netdev);
4914 +                       free_netdev(netdev);
4915 +               }
4916 +#endif
4917 +               #endif
4918 +       }
4919 +#endif
4920 +
4921 +#ifdef CONFIG_CNS3XXX_NAPI
4922 +       free_netdev(napi_dev);
4923 +       #ifdef CNS3XXX_DOUBLE_RX_RING
4924 +       free_netdev(r1_napi_dev);
4925 +       #endif
4926 +#endif
4927 +
4928 +
4929 +#if 0
4930 +       //star_gsw_buffer_free(); 
4931 +#endif
4932 +       unregister_reboot_notifier(&cns3xxx_notifier_reboot);
4933 +}
4934 +
4935 +
4936 +// this snippet code ref 8139cp.c
4937 +#if defined(CNS3XXX_VLAN_8021Q)
4938 +void cns3xxx_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
4939 +{
4940 +        CNS3XXXPrivate *priv = netdev_priv(dev);
4941 +        unsigned long flags;
4942 +
4943 +        spin_lock_irqsave(&priv->lock, flags);
4944 +        priv->vlgrp = grp;
4945 +        spin_unlock_irqrestore(&priv->lock, flags);
4946 +}
4947 +
4948 +void cns3xxx_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
4949 +{
4950 +        CNS3XXXPrivate *priv = netdev_priv(dev);
4951 +        unsigned long flags;
4952 +
4953 +        spin_lock_irqsave(&priv->lock, flags);
4954 +        // reference: linux-2.6.24-current/drivers/netvia-velocity.c
4955 +        vlan_group_set_device(priv->vlgrp, vid, NULL);
4956 +                //priv->vlgrp->vlan_devices[vid] = NULL;
4957 +        spin_unlock_irqrestore(&priv->lock, flags);
4958 +}
4959 +
4960 +#endif
4961 +
4962 +static struct platform_driver drv = {
4963 +       .driver.name = "cns3xxx-net",
4964 +       .probe = cns3xxx_init,
4965 +       .remove = cns3xxx_remove,
4966 +};
4967 +
4968 +static int __init cns3xxx_init_module(void)
4969 +{
4970 +       return platform_driver_register(&drv);
4971 +}
4972 +
4973 +static void __exit cns3xxx_exit_module(void)
4974 +{
4975 +       platform_driver_unregister(&drv);
4976 +}
4977 +
4978 +MODULE_AUTHOR("Cavium Networks, <tech@XXXX.com>");
4979 +MODULE_DESCRIPTION("CNS3XXX Switch Driver");
4980 +MODULE_LICENSE("GPL");
4981 +MODULE_VERSION(DRV_VERSION);
4982 +
4983 +module_init(cns3xxx_init_module);
4984 +module_exit(cns3xxx_exit_module);
4985 +
4986 --- /dev/null
4987 +++ b/drivers/net/cns3xxx/cns3xxx_phy.c
4988 @@ -0,0 +1,1968 @@
4989 +/*******************************************************************************
4990 + *
4991 + *
4992 + *   Copyright (c) 2009 Cavium Networks 
4993 + *
4994 + *   This program is free software; you can redistribute it and/or modify it
4995 + *   under the terms of the GNU General Public License as published by the Free
4996 + *   Software Foundation; either version 2 of the License, or (at your option)
4997 + *   any later version.
4998 + *
4999 + *   This program is distributed in the hope that it will be useful, but WITHOUT
5000 +1*   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5001 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5002 + *   more details.
5003 + *
5004 + *   You should have received a copy of the GNU General Public License along with
5005 + *   this program; if not, write to the Free Software Foundation, Inc., 59
5006 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
5007 + *
5008 + *   The full GNU General Public License is included in this distribution in the
5009 + *   file called LICENSE.
5010 + *
5011 + ********************************************************************************/
5012 +
5013 +#include "cns3xxx_phy.h"
5014 +#include "cns3xxx_symbol.h"
5015 +
5016 +
5017 +#if defined(LINUX_KERNEL)
5018 +#include "cns3xxx_tool.h"
5019 +#include <linux/cns3xxx/switch_api.h> // for CAVM_OK ... macro
5020 +#include <linux/delay.h>
5021 +#include "cns3xxx_config.h"
5022 +#else // u-boot
5023 +#include <common.h>
5024 +#include "cns3xxx_switch_type.h"
5025 +#define printk printf
5026 +#endif
5027 +
5028 +int cns3xxx_phy_reset(u8 phy_addr)
5029 +{
5030 +       u16 phy_data=0;
5031 +
5032 +       if (cns3xxx_read_phy(phy_addr, 0, &phy_data) != CAVM_OK)
5033 +               return CAVM_ERR;
5034 +       phy_data |= (0x1 << 15); 
5035 +       if (cns3xxx_write_phy(phy_addr, 0, phy_data) != CAVM_OK)
5036 +               return CAVM_ERR;
5037 +
5038 +       return CAVM_OK;
5039 +}
5040 +
5041 +// mac_port: 0, 1, 2
5042 +int cns3xxx_enable_mac_clock(u8 mac_port, u8 en)
5043 +{
5044 +       switch (mac_port) 
5045 +       {
5046 +               case 0:
5047 +               {
5048 +                       (en==1)?(PHY_AUTO_ADDR_REG |= 1 << 7) :(PHY_AUTO_ADDR_REG &= (~(1 << 7)) );
5049 +                       break;
5050 +               }
5051 +               case 1:
5052 +               {
5053 +                       (en==1)?(PHY_AUTO_ADDR_REG |= (1 << 15)) :(PHY_AUTO_ADDR_REG &= (~(1 << 15)) );
5054 +                       break;
5055 +               }
5056 +               case 2:
5057 +               {
5058 +                       (en==1)?(PHY_AUTO_ADDR_REG |= (1 << 23)) :(PHY_AUTO_ADDR_REG &= (~(1 << 23)) );
5059 +                       break;
5060 +               }
5061 +       }
5062 +
5063 +       return CAVM_OK;
5064 +}
5065 +
5066 +// dis: 1 disable
5067 +// dis: 0 enable
5068 +int cns3xxx_phy_auto_polling_enable(u8 port, u8 en)
5069 +{
5070 +       u8 phy_addr[]={5, 13, 21};
5071 +
5072 +       PHY_AUTO_ADDR_REG &= (~(1 << phy_addr[port]));
5073 +       if (en) {
5074 +               PHY_AUTO_ADDR_REG |= (1 << phy_addr[port]);
5075 +       }
5076 +       return CAVM_OK;
5077 +}
5078 +
5079 +// dis: 1 disable
5080 +// dis: 0 enable
5081 +int cns3xxx_mdc_mdio_disable(u8 dis)
5082 +{
5083 +
5084 +       PHY_CTRL_REG &= (~(1 << 7));
5085 +       if (dis) {
5086 +               PHY_CTRL_REG |= (1 << 7);
5087 +       }
5088 +       return CAVM_OK;
5089 +}
5090 +
5091 +
5092 +static int cns3xxx_phy_auto_polling_conf(int mac_port, u8 phy_addr)
5093 +{
5094 +       if ( (mac_port < 0) || (mac_port > 2) ) {
5095 +               return CAVM_ERR;
5096 +       }
5097 +
5098 +       switch (mac_port) 
5099 +       {
5100 +               case 0:
5101 +               {
5102 +                       PHY_AUTO_ADDR_REG &= (~0x1f);
5103 +                       PHY_AUTO_ADDR_REG |= phy_addr;
5104 +                       break;
5105 +               }
5106 +               case 1:
5107 +               {
5108 +                       PHY_AUTO_ADDR_REG &= (~(0x1f << 8));
5109 +                       PHY_AUTO_ADDR_REG |= (phy_addr << 8);
5110 +                       break;
5111 +               }
5112 +               case 2:
5113 +               {
5114 +                       PHY_AUTO_ADDR_REG &= (~(0x1f << 16));
5115 +                       PHY_AUTO_ADDR_REG |= (phy_addr << 16);
5116 +                       break;
5117 +               }
5118 +       }
5119 +       cns3xxx_phy_auto_polling_enable(mac_port, 1);
5120 +       return CAVM_OK;
5121 +}
5122 +
5123 +
5124 +
5125 +int cns3xxx_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data)
5126 +{
5127 +       int delay=0;
5128 +       u32 volatile tmp = PHY_CTRL_REG;
5129 +
5130 +       PHY_CTRL_REG |= (1 << 15); // clear "command completed" bit
5131 +       // delay
5132 +       for (delay=0; delay<10; delay++);
5133 +       tmp &= (~0x1f);
5134 +       tmp |= phy_addr;
5135 +
5136 +       tmp &= (~(0x1f << 8));
5137 +       tmp |= (phy_reg << 8);
5138 +
5139 +       tmp |= (1 << 14); // read command
5140 +
5141 +       PHY_CTRL_REG = tmp;
5142 +
5143 +       // wait command complete
5144 +       while ( ((PHY_CTRL_REG >> 15) & 1) == 0);
5145 +
5146 +       *read_data = (PHY_CTRL_REG >> 16);
5147 +
5148 +       PHY_CTRL_REG |= (1 << 15); // clear "command completed" bit
5149 +
5150 +       return CAVM_OK;
5151 +}
5152 +
5153 +int cns3xxx_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data)
5154 +{
5155 +       int delay=0;
5156 +       u32 tmp = PHY_CTRL_REG;
5157 +
5158 +       PHY_CTRL_REG |= (1 << 15); // clear "command completed" bit
5159 +       // delay
5160 +       for (delay=0; delay<10; delay++);
5161 +
5162 +       tmp &= (~(0xffff << 16));
5163 +       tmp |= (write_data << 16);
5164 +
5165 +       tmp &= (~0x1f);
5166 +       tmp |= phy_addr;
5167 +
5168 +       tmp &= (~(0x1f << 8));
5169 +       tmp |= (phy_reg << 8);
5170 +
5171 +       tmp |= (1 << 13); // write command
5172 +
5173 +       PHY_CTRL_REG = tmp;
5174 +
5175 +       // wait command complete
5176 +       while ( ((PHY_CTRL_REG >> 15) & 1) == 0);
5177 +
5178 +       return CAVM_OK;
5179 +}
5180 +
5181 +// port 0,1,2
5182 +void cns3xxx_rxc_dly(u8 port, u8 val)
5183 +{
5184 +       switch (port)
5185 +       {
5186 +               case 0:
5187 +               {
5188 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 4));
5189 +                       SLK_SKEW_CTRL_REG |= (val << 4);
5190 +                       break;
5191 +               }
5192 +               case 1:
5193 +               {
5194 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 12));
5195 +                       SLK_SKEW_CTRL_REG |= (val << 12);
5196 +                       break;
5197 +               }
5198 +               case 2:
5199 +               {
5200 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 20));
5201 +                       SLK_SKEW_CTRL_REG |= (val << 20);
5202 +                       break;
5203 +               }
5204 +       }
5205 +}
5206 +
5207 +// port 0,1,2
5208 +void cns3xxx_txc_dly(u8 port, u8 val)
5209 +{
5210 +       switch (port)
5211 +       {
5212 +               case 0:
5213 +               {
5214 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 6));
5215 +                       SLK_SKEW_CTRL_REG |= (val << 6);
5216 +                       break;
5217 +               }
5218 +               case 1:
5219 +               {
5220 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 14));
5221 +                       SLK_SKEW_CTRL_REG |= (val << 14);
5222 +                       break;
5223 +               }
5224 +               case 2:
5225 +               {
5226 +                       SLK_SKEW_CTRL_REG &= (~(0x3 << 22));
5227 +                       SLK_SKEW_CTRL_REG |= (val << 22);
5228 +                       break;
5229 +               }
5230 +       }
5231 +}
5232 +
5233 +void cns3xxx_mac2_gtxd_dly(u8 val)
5234 +{
5235 +               SLK_SKEW_CTRL_REG &= (~(0x3 << 24));
5236 +               SLK_SKEW_CTRL_REG |= (val << 24);
5237 +}
5238 +
5239 +// VITESSE suggest use isolate bit.
5240 +int vsc8601_power_down(int phy_addr, int y)
5241 +{
5242 +        u16 phy_data = 0;
5243 +        /* set isolate bit instead of powerdown */
5244 +        cns3xxx_read_phy(phy_addr, 0, &phy_data);
5245 +        if (y==1) // set isolate
5246 +                phy_data |= (0x1 << 10);
5247 +        if (y==0) // unset isolate
5248 +                phy_data &= (~(0x1 << 10));
5249 +        cns3xxx_write_phy(phy_addr, 0, phy_data);
5250 +
5251 +        return 0;
5252 +}
5253 +
5254 +
5255 +// port : 0 => port0 ; port : 1 => port1
5256 +// y = 1 ; disable AN
5257 +void disable_AN(int port, int y)
5258 +{
5259 +       u32 mac_port_config=0;
5260 +
5261 +       switch (port)
5262 +       {
5263 +               case 0:
5264 +               {
5265 +                       mac_port_config = MAC0_CFG_REG;
5266 +                       break;
5267 +               }
5268 +               case 1:
5269 +               {
5270 +                       mac_port_config = MAC1_CFG_REG;
5271 +                       break;
5272 +               }
5273 +               case 2:
5274 +               {
5275 +                       mac_port_config = MAC2_CFG_REG;
5276 +                       break;
5277 +               }
5278 +       }
5279 +
5280 +
5281 +       // disable PHY's AN
5282 +       if (y==1)
5283 +       {
5284 +         mac_port_config &= ~(0x1 << 7);
5285 +       }
5286 +
5287 +       // enable PHY's AN
5288 +       if (y==0)
5289 +       {
5290 +         mac_port_config |= (0x1 << 7);
5291 +       }
5292 +
5293 +       switch (port)
5294 +       {
5295 +               case 0:
5296 +               {
5297 +                       MAC0_CFG_REG = mac_port_config;
5298 +                       break;
5299 +               }
5300 +               case 1:
5301 +               {
5302 +                       MAC1_CFG_REG = mac_port_config;
5303 +                       break;
5304 +               }
5305 +               case 2:
5306 +               {
5307 +                       MAC2_CFG_REG = mac_port_config;
5308 +                       break;
5309 +               }
5310 +       }
5311 +}
5312 +
5313 +int cns3xxx_std_phy_power_down(int phy_addr, int y)
5314 +{
5315 +        u16 phy_data = 0;
5316 +        // power-down or up the PHY
5317 +        cns3xxx_read_phy(phy_addr, 0, &phy_data);
5318 +        if (y==1) // down
5319 +                phy_data |= (0x1 << 11);
5320 +        if (y==0) // up
5321 +                phy_data &= (~(0x1 << 11));
5322 +        cns3xxx_write_phy(phy_addr, 0, phy_data);
5323 +
5324 +       phy_data=0;
5325 +        cns3xxx_read_phy(phy_addr, 0, &phy_data);
5326 +
5327 +        return 0;
5328 +}
5329 +
5330 +
5331 +#if defined(LINUX_KERNEL)
5332 +int cns3xxx_spi_tx_rx_n(u32 tx_data, u32 *rx_data, u32 tx_channel, u32 tx_eof_flag)
5333 +{
5334 +       u8 cns3xxx_spi_tx_rx(u8 tx_channel, u8 tx_eof, u32 tx_data, u32 * rx_data);
5335 +
5336 +       return cns3xxx_spi_tx_rx(tx_channel, tx_eof_flag, tx_data, rx_data);
5337 +}
5338 +
5339 +int bcm53115M_reg_read(int page, int offset, u8 *buf, int len)
5340 +{
5341 +       u32 ch = BCM53115_SPI_CHANNEL;
5342 +       u8 cmd_byte;
5343 +       u32     dumy_word;
5344 +       u32 spi_status;
5345 +       int i;
5346 +
5347 +       /*
5348 +        * Normal SPI Mode (Command Byte)
5349 +        * Bit7         Bit6            Bit5            Bit4            Bit3            Bit2            Bit1            Bit0
5350 +        * 0            1                       1                       Mode=0          CHIP_ID2        ID1                     ID0(lsb)        Rd/Wr(0/1)      
5351 +        *
5352 +        */
5353 +
5354 +       /* Normal Read Operation */
5355 +       /* 1. Issue a normal read command(0x60) to poll the SPIF bit in the 
5356 +             SPI status register(0XFE) to determine the operation can start */
5357 +       do 
5358 +        {
5359 +               cmd_byte = 0x60;      
5360 +               cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5361 +               cns3xxx_spi_tx_rx_n(0xFE, &dumy_word, ch, 0);
5362 +               cns3xxx_spi_tx_rx_n(0x00, &spi_status, ch, 1);
5363 +               udelay(100);
5364 +       }while ((spi_status >> ROBO_SPIF_BIT) & 1) ; // wait SPI bit to 0
5365 +
5366 +       /* 2. Issue a normal write command(0x61) to write the register page value
5367 +                 into the SPI page register(0xFF)       */
5368 +       cmd_byte = 0x61;      
5369 +       cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5370 +       cns3xxx_spi_tx_rx_n(0xFF, &dumy_word, ch, 0);
5371 +       cns3xxx_spi_tx_rx_n(page, &dumy_word, ch, 1);
5372 +
5373 +       /* 3. Issue a normal read command(0x60) to setup the required RobiSwitch register
5374 +                 address        */
5375 +       cmd_byte = 0x60;          
5376 +       cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5377 +       cns3xxx_spi_tx_rx_n(offset, &dumy_word, ch, 0);
5378 +       cns3xxx_spi_tx_rx_n(0x00, &dumy_word, ch, 1);
5379 +
5380 +       /* 4. Issue a normal read command(0x60) to poll the RACK bit in the 
5381 +             SPI status register(0XFE) to determine the completion of read      */
5382 +       do 
5383 +       {
5384 +               cmd_byte = 0x60;          
5385 +               cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5386 +               cns3xxx_spi_tx_rx_n(0xFE, &dumy_word, ch, 0);
5387 +               cns3xxx_spi_tx_rx_n(0x00, &spi_status, ch, 1);
5388 +               udelay(100);
5389 +       }while (((spi_status >> ROBO_RACK_BIT) & 1) == 0); // wait RACK bit to 1
5390 +        
5391 +       /* 5. Issue a normal read command(0x60) to read the specific register's conternt
5392 +                 placed in the SPI data I/O register(0xF0)      */
5393 +       cmd_byte = 0x60;          
5394 +       cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5395 +       cns3xxx_spi_tx_rx_n(0xF0, &dumy_word, ch, 0);
5396 +       // read content
5397 +       for (i=0; i<len; i++) {
5398 +               cns3xxx_spi_tx_rx_n(0x00, &dumy_word, ch, ((i==(len-1)) ? 1 : 0));
5399 +               buf[i] = (u8)dumy_word;
5400 +       }
5401 +       
5402 +       return 0;
5403 +
5404 +}
5405 +
5406 +int bcm53115M_reg_write(int page, int offset, u8 *buf, int len)
5407 +{
5408 +       u32 ch = BCM53115_SPI_CHANNEL;
5409 +       u8 cmd_byte;
5410 +       u32 dumy_word;
5411 +       u32 spi_status;
5412 +       int i;
5413 +
5414 +       /*
5415 +        * Normal SPI Mode (Command Byte)
5416 +        * Bit7         Bit6            Bit5            Bit4            Bit3            Bit2            Bit1            Bit0
5417 +        * 0            1                       1                       Mode=0          CHIP_ID2        ID1                     ID0(lsb)        Rd/Wr(0/1)      
5418 +        *
5419 +        */
5420 +
5421 +       /* Normal Write Operation */
5422 +       /* 1. Issue a normal read command(0x60) to poll the SPIF bit in the 
5423 +             SPI status register(0XFE) to determine the operation can start */
5424 +
5425 +       do 
5426 +        {
5427 +               cmd_byte = 0x60;      
5428 +               cns3xxx_spi_tx_rx_n(cmd_byte, &dumy_word, ch, 0);
5429 +               cns3xxx_spi_tx_rx_n(0xFE, &dumy_word, ch, 0);
5430 +               cns3xxx_spi_tx_rx_n(0x00, &spi_status, ch, 1);
5431 +       }while ((spi_status >> ROBO_SPIF_BIT) & 1) ; // wait SPI bit to 0
5432 +
5433 +       /* 2. Issue a normal write command(0x61) to write the register page value
5434 +                 into the SPI page register(0xFF)       */
5435 +       cmd_byte = 0x61;      
5436 +       cns3xxx_spi_tx_rx_n((u32)cmd_byte, &dumy_word, ch, 0);
5437 +       cns3xxx_spi_tx_rx_n(0xFF, &dumy_word, ch, 0);
5438 +       cns3xxx_spi_tx_rx_n(page, &dumy_word, ch, 1);
5439 +
5440 +       /* 3. Issue a normal write command(0x61) and write the address of the accessed
5441 +                 register followed by the write content starting from a lower byte */
5442 +       cmd_byte = 0x61;          
5443 +       cns3xxx_spi_tx_rx_n((u32)cmd_byte, &dumy_word, ch, 0);
5444 +       cns3xxx_spi_tx_rx_n(offset, &dumy_word, ch, 0);
5445 +       // write content
5446 +       for (i=0; i<len; i++) {
5447 +               cns3xxx_spi_tx_rx_n((u32)buf[i], &dumy_word, ch, ((i==(len-1)) ? 1 : 0));
5448 +       }
5449 +
5450 +       return 0;
5451 +}
5452 +
5453 +int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state);
5454 +
5455 +void bcm53115M_init_mac(u8 mac_port, u16 phy_addr)
5456 +{
5457 +       u32 mac_port_config = 0;
5458 +       u8 mac_addr[]={0x0c, 0x10, 0x18};
5459 +
5460 +       cns3xxx_enable_mac_clock(mac_port, 1);
5461 +       cns3xxx_phy_auto_polling_enable(mac_port, 0);
5462 +
5463 +       mac_port_config = SWITCH_REG_VALUE(mac_addr[mac_port]);
5464 +
5465 +       // enable GMII, MII, reverse MII
5466 +       mac_port_config &= (~(1 << 15));
5467 +
5468 +       // enable RGMII
5469 +       mac_port_config |= (1 << 15);
5470 +
5471 +        // disable GIGA mode
5472 +        mac_port_config &= (~(1<<16));
5473 +
5474 +        // enable GIGA mode
5475 +        mac_port_config |= (1<<16);
5476 +
5477 +        // disable PHY's AN
5478 +       mac_port_config &= (~(0x1 << 7));
5479 +
5480 +       // force 1000Mbps
5481 +       mac_port_config &= (~(0x3 << 8));
5482 +       mac_port_config |= (0x2 << 8);
5483 +
5484 +       // force duplex
5485 +       mac_port_config |= (0x1 << 10);
5486 +
5487 +       // TX flow control on
5488 +       mac_port_config |= (0x1 << 12);
5489 +
5490 +       // RX flow control on
5491 +       mac_port_config |= (0x1 << 11);
5492 +
5493 +       // Turn off GSW_PORT_TX_CHECK_EN_BIT
5494 +       mac_port_config &= (~(0x1 << 13));
5495 +
5496 +       // Turn on GSW_PORT_TX_CHECK_EN_BIT
5497 +       mac_port_config |= (0x1 << 13);
5498 +
5499 +       SWITCH_REG_VALUE(mac_addr[mac_port]) = mac_port_config;
5500 +}
5501 +
5502 +typedef struct bcm53115M_vlan_entry_t
5503 +{
5504 +       u16 vid;
5505 +       u16 forward_map;
5506 +       u16 untag_map;
5507 +}bcm53115M_vlan_entry;
5508 +
5509 +
5510 +
5511 +int bcm53115M_write_vlan(bcm53115M_vlan_entry *v)
5512 +{
5513 +       u8 bval;
5514 +       u16 wval;
5515 +       u32 dwval;
5516 +
5517 +       // fill vid
5518 +       wval = (u16)v->vid;
5519 +       bcm53115M_reg_write(0x05, 0x81, (u8*)&wval, 2);
5520 +
5521 +       // fill table content
5522 +       dwval = 0;
5523 +       dwval |= (v->forward_map & 0x1FF);
5524 +       dwval |= ((v->untag_map& 0x1FF) << 9);
5525 +       bcm53115M_reg_write(0x05, 0x83, (u8*)&wval, 4);
5526 +
5527 +       // write cmd
5528 +       bval = VLAN_WRITE_CMD;
5529 +       bval |= (1 << VLAN_START_BIT);
5530 +       bcm53115M_reg_write(0x05, 0x80, (u8*)&bval, 1);
5531 +
5532 +       // wait cmd complete
5533 +       while(1) {
5534 +               bcm53115M_reg_read(0x05, 0x80, (u8*)&bval, 1);  
5535 +               if (((bval >> VLAN_START_BIT) & 1) == 0) break;
5536 +       }
5537 +
5538 +       return CAVM_OK;
5539 +}
5540 +
5541 +typedef struct bcm_port_cfg_t
5542 +{
5543 +       u8 link;
5544 +       u8 fdx;
5545 +       BCM_PORT_SPEED speed;
5546 +       u8 rx_flw_ctrl;
5547 +       u8 tx_flw_ctrl;
5548 +       u8 ow;
5549 +}bcm_port_cfg;
5550 +
5551 +
5552 +
5553 +int bcm53115M_mac_port_config(int port, bcm_port_cfg *cfg)
5554 +{
5555 +       u8 bval = 0;
5556 +       int page, addr;
5557 +
5558 +       if (cfg->link) bval |= (1<<0);
5559 +       if (cfg->fdx) bval |= (1<<1);
5560 +       bval |= ((cfg->speed&0x3) << 2);
5561 +       if (cfg->rx_flw_ctrl) bval |= (1<<4);
5562 +       if (cfg->tx_flw_ctrl) bval |= (1<<5);
5563 +       
5564 +       if (port == BCM_PORT_IMP) {
5565 +               bval |= (1<<7); // Use content of this register         
5566 +               page = 0x00;
5567 +               addr = 0x0E;
5568 +       }else {
5569 +               page = 0x00;
5570 +               addr = 0x58+port;
5571 +       }
5572 +
5573 +       bcm53115M_reg_write(page, addr, &bval, 1);
5574 +
5575 +       return 0;
5576 +}
5577 +
5578 +int bcm53115M_init_internal_phy(void)
5579 +{
5580 +       int p, page;
5581 +       u16 wval;
5582 +
5583 +       for (p=BCM_PORT_0; p<=BCM_PORT_4; p++) {
5584 +               page = 0x10+p;
5585 +               
5586 +               // reset phy
5587 +               bcm53115M_reg_read(page, 0x00, (u8*)&wval, 2);
5588 +               wval |= 0x8000;
5589 +               bcm53115M_reg_write(page, 0x00, (u8*)&wval, 2);
5590 +
5591 +               // config auto-nego & all advertisement
5592 +               bcm53115M_reg_read(page, 0x00, (u8*)&wval, 2);
5593 +               wval |= (1<<12); // auto-nego
5594 +               bcm53115M_reg_write(page, 0x00, (u8*)&wval, 2);
5595 +
5596 +               bcm53115M_reg_read(page, 0x08, (u8*)&wval, 2);
5597 +               wval |= 0x1E0; // advertisement all
5598 +               bcm53115M_reg_write(page, 0x08, (u8*)&wval, 2);
5599 +
5600 +               // 1000BASE-T
5601 +               bcm53115M_reg_read(page, 0x12, (u8*)&wval, 2);
5602 +               wval &= ~(1<<12); // automatic master/slave configuration
5603 +               wval |= 0x300; // 1000-base full/half advertisements
5604 +               bcm53115M_reg_write(page, 0x12, (u8*)&wval, 2);
5605 +       }
5606 +
5607 +       return 0;
5608 +}
5609 +
5610 +int bcm53115M_led_init(void)
5611 +{
5612 +       u16 led_func, bval, wval; 
5613 +               
5614 +       /* LED function 1G/ACT, 100M/ACT, 10M/ACT, not used */
5615 +       led_func = 0x2C00;
5616 +       bcm53115M_reg_write(0x00, 0x10, (u8*)&led_func, 2);
5617 +       bcm53115M_reg_write(0x00, 0x12, (u8*)&led_func, 2);
5618 +
5619 +       /* LED map enable */
5620 +       wval = 0x1F; // port0~4
5621 +       bcm53115M_reg_write(0x00, 0x16, (u8*)&wval, 2);
5622 +
5623 +       /* LED mode map */
5624 +       wval = 0x1F; // led auto mode
5625 +       bcm53115M_reg_write(0x00, 0x18, (u8*)&wval, 2);
5626 +       bcm53115M_reg_write(0x00, 0x1A, (u8*)&wval, 2);
5627 +
5628 +       /* LED enable */
5629 +       bcm53115M_reg_read(0x00, 0x0F, (u8*)&bval, 1);
5630 +       bval |= 0x80;
5631 +       bcm53115M_reg_write(0x00, 0x0F, (u8*)&bval, 1);
5632 +       
5633 +       return 0;
5634 +}
5635 +
5636 +//#define BCM53115M_DUMMY_SWITCH
5637 +#define BCM53115M_DISABLE_LEARNING
5638 +
5639 +int bcm53115M_init(u8 mac_port, u16 phy_addr)
5640 +{
5641 +       u32 u32_val=0;
5642 +       u16 u16_val=0;
5643 +       u8 bval=0;
5644 +       int i=0;
5645 +       bcm53115M_vlan_entry v_ent;
5646 +       bcm_port_cfg pc;
5647 +       u8 page=0, offset=0;
5648 +
5649 +       printk("bcm53115M init\n");
5650 +
5651 +       memset(&v_ent, 0, sizeof(bcm53115M_vlan_entry));
5652 +
5653 +       // gpio B pin 18
5654 +       gpio_direction_output(50, 0);
5655 +       bcm53115M_init_mac(0, 0);
5656 +       bcm53115M_init_mac(1, 1);
5657 +
5658 +       // read device id
5659 +       bcm53115M_reg_read(0x02, 0x30, (u8*)&u32_val, 4);
5660 +       printk("bcm53115M device id:(0x%x)\r\n", u32_val);
5661 +
5662 +       if (u32_val != 0x53115) {
5663 +               printk("bad device id(0x%x)\r\n", u32_val);
5664 +               return -1;
5665 +       }
5666 +
5667 +       u16_val=0;
5668 +       // read phy id
5669 +       bcm53115M_reg_read(0x10, 0x04, (u8 *)&u16_val, 2);
5670 +       printk("bcm53115M phy id_1:(0x%x)\r\n", u16_val);
5671 +
5672 +       if (u16_val != 0x143) {
5673 +               printk("bad phy id1(0x%x)\r\n", u16_val);
5674 +               return CAVM_ERR;
5675 +       }
5676 +
5677 +       u16_val=0;
5678 +       // read phy id2
5679 +       bcm53115M_reg_read(0x10, 0x06, (u8 *)&u16_val, 2);
5680 +       printk("bcm53115M phy id_2:(0x%x)\r\n", u16_val);
5681 +
5682 +#ifdef BCM53115M_DUMMY_SWITCH
5683 +       bval=0;
5684 +       bcm53115M_reg_read(0x00, 0x0e, (u8 *)&bval, 1);
5685 +       printk("bcm53115M page:0 addr:0x0e ## %x\n", bval);
5686 +       bval |= (1 << 7);
5687 +       bval |= 1;
5688 +
5689 +       bval = 0x8b;
5690 +       bval |= (1 << 5);
5691 +       bval |= (1 << 4);
5692 +       printk("bval : %x\n", bval);
5693 +       bcm53115M_reg_write(0x00, 0x0e, (u8 *)&bval, 1);
5694 +       bcm53115M_reg_read(0x00, 0x0e, (u8 *)&bval, 1);
5695 +       printk("bcm53115M page:0 addr:0x0e ## %x\n", bval);
5696 +
5697 +       /* Unmanagement mode */
5698 +       // Switch Mode. Page 00h,Address 0Bh
5699 +       bval = 0x06; // forward enable, unmanaged mode
5700 +       //bval = 0x3; // forward enable, managed mode
5701 +       bcm53115M_reg_write(0x0, 0xb, &bval, 1);
5702 +       bcm53115M_reg_read(0x0, 0xb, (u8 *)&bval, 1);
5703 +       printk("bcm53115M page:0 addr:0xb ## %x\n", bval);
5704 +
5705 +       page=0x0;
5706 +       offset=0x5d; // port 5
5707 +       bval=0x7b;
5708 +       bcm53115M_reg_write(page, offset, (u8 *)&bval, 1);
5709 +       bcm53115M_reg_read(page, offset, (u8 *)&bval, 1);
5710 +
5711 +       printk("bcm53115M page:%x addr:%x ## %x\n", page, offset, bval);
5712 +
5713 +       page=0x0;
5714 +       offset=0x58; // port 0
5715 +       bval=0x7b;
5716 +       bcm53115M_reg_write(page, offset, (u8 *)&bval, 1);
5717 +       bcm53115M_reg_read(page, offset, (u8 *)&bval, 1);
5718 +       printk("bcm53115M page:%x addr:%x ## %x\n", page, offset, bval);
5719 +
5720 +#ifdef CONFIG_CNS3XXX_JUMBO_FRAME
5721 +       printk("enable BCM53115 jumbo frame\n");
5722 +
5723 +       page=0x40;
5724 +       offset=0x01;
5725 +       u32_val=0x013f; // enable 0-5 port and IMP port jumbo frame. MAX frame: 9720 bytes.
5726 +       bcm53115M_reg_write(page, offset, (u8 *)&u32_val, 4);
5727 +       bcm53115M_reg_read(page, offset, (u8 *)&u32_val, 4);
5728 +       printk("bcm53115M page:%x addr:%x ## %x\n", page, offset, u32_val);
5729 +
5730 +#if 0
5731 +       page=0x40;
5732 +       offset=0x05;
5733 +       u16_val=0;
5734 +       bcm53115M_reg_write(page, offset, (u8 *)&u16_val, 2);
5735 +#endif
5736 +
5737 +#endif
5738 +
5739 +#else // !BCM53115M_DUMMY_SWITCH
5740 +       /* Loop detection disable */
5741 +       bcm53115M_reg_read(0x72, 0x00, (u8 *)&u16_val, 2);
5742 +       u16_val &= ~(0x3<<11);
5743 +       bcm53115M_reg_write(0x72, 0x00, (u8 *)&u16_val, 2);
5744 +
5745 +
5746 +       /* VLAN forwarding mask */
5747 +       // Bit8 IMP port, Bits[5:0] correspond to ports[5:0]
5748 +       // port 0 <-> port IMP
5749 +       u16_val = 0x103;
5750 +       bcm53115M_reg_write(0x31, 0x0, (u8 *)&u16_val, 2); // port 0
5751 +       u16_val = 0x103;
5752 +       bcm53115M_reg_write(0x31, 0x10, (u8 *)&u16_val, 2); // IMP
5753 +
5754 +
5755 +       // port 4 <-> port 5
5756 +       u16_val = 0x3c;
5757 +       bcm53115M_reg_write(0x31, 0x08, (u8 *)&u16_val, 2); // port 4
5758 +       u16_val = 0x3c;
5759 +       bcm53115M_reg_write(0x31, 0x0A, (u8 *)&u16_val, 2); // port 5
5760 +
5761 +
5762 +       // others <-> none
5763 +       u16_val = 0x00;
5764 +       bcm53115M_reg_write(0x31, 0x02, (u8 *)&u16_val, 2); // port 1
5765 +       bcm53115M_reg_write(0x31, 0x04, (u8 *)&u16_val, 2); // port 2
5766 +       bcm53115M_reg_write(0x31, 0x06, (u8 *)&u16_val, 2); // port 3
5767 +
5768 +       // port 1 <-> port IMP
5769 +       u16_val = 0x103;
5770 +       bcm53115M_reg_write(0x31, 0x2, (u8 *)&u16_val, 2); // port 1
5771 +
5772 +       // port 2 <-> port 5
5773 +       u16_val = 0x3c;
5774 +       bcm53115M_reg_write(0x31, 0x4, (u8 *)&u16_val, 2); // port 2
5775 +
5776 +       // port 3 <-> port 5
5777 +       u16_val = 0x3c;
5778 +       bcm53115M_reg_write(0x31, 0x6, (u8 *)&u16_val, 2); // port 3
5779 +
5780 +       /* Create VLAN1 for default port pvid */
5781 +#if 0  
5782 +       v_ent.vid = 1;
5783 +       v_ent.forward_map = 0x13F; // all ports
5784 +       robo_write_vlan(&v_ent);
5785 +#endif
5786 +       
5787 +       /* Unmanagement mode */
5788 +       // Switch Mode. Page 00h,Address 0Bh
5789 +       bval = 0x02; // forward enable, unmanaged mode
5790 +       bcm53115M_reg_write(0x0, 0xb, &bval, 1);
5791 +       
5792 +       /* Init port5 & IMP  (test giga mode first) */
5793 +       // IMP port control. Page 00h,Address 08h
5794 +       bval = 0x1C; // RX UCST/MCST/BCST enable
5795 +       bcm53115M_reg_write(0x0, 0x8, &bval, 1);
5796 +
5797 +       offset=0x5d; // port 5
5798 +       bval=0x7b;
5799 +       bcm53115M_reg_write(page, offset, (u8 *)&bval, 1);
5800 +       bcm53115M_reg_read(page, offset, (u8 *)&bval, 1);
5801 +
5802 +       // Speed, dulplex......etc
5803 +       // setting in Gsw_Configure_Gsw_Hardware()
5804 +       
5805 +       // Mgmt configuration, Page 02h, Address 00h
5806 +       bval = 0;
5807 +       bcm53115M_reg_write(0x02, 0x00, &bval, 1);
5808 +       // BRCM header, Page 02h, Address 03h
5809 +       bval = 0; // without additional header information
5810 +       bcm53115M_reg_write(0x02, 0x03, &bval, 1);
5811 +
5812 +       /* Init front ports, port0-4 */
5813 +       // MAC
5814 +       pc.speed = BCM_PORT_1G;
5815 +       pc.link = 0; // link detect by robo_port_update()
5816 +       pc.ow = 0;
5817 +       for (i=BCM_PORT_0; i<=BCM_PORT_4; i++)
5818 +               bcm53115M_mac_port_config(i, &pc);      
5819 +       // Internal Phy
5820 +       bcm53115M_init_internal_phy();
5821 +
5822 +       /* Enable all port, STP_STATE=No spanning tree, TX/RX enable */
5823 +       // Page 00h, Address 00h-05h
5824 +       bval = 0x0;
5825 +       for (i=0; i<=5; i++)
5826 +               bcm53115M_reg_write(0x0, i, &bval, 1);
5827 +
5828 +       // Disable broadcast storm control due to h/w strap pin BC_SUPP_EN
5829 +       // Page 41h, Address 10h-13h, bit28&22
5830 +
5831 +       // for port 0 ~ 5
5832 +       for (i=0 ; i <= 0x14; i+=4) {
5833 +               bcm53115M_reg_read(0x41, 0x10+i, (u8 *)&u32_val, 4);
5834 +               u32_val &= ~((1<<28) | (1<<22));
5835 +               bcm53115M_reg_write(0x41, 0x10+i, (u8 *)&u32_val, 4);
5836 +       }       
5837 +
5838 +       // for IMP port
5839 +       bcm53115M_reg_read(0x41, 0x30, (u8 *)&u32_val, 4);
5840 +       u32_val &= ~((1<<28) | (1<<22));
5841 +       bcm53115M_reg_write(0x41, 0x30, (u8 *)&u32_val, 4);
5842 +
5843 +       /* Misc */
5844 +       // led
5845 +       bcm53115M_led_init();
5846 +       // multicast fwd rule, Page 00h, Address 2Fh
5847 +       bval = 0;
5848 +       bcm53115M_reg_write(0x00, 0x2F, &bval, 1);
5849 +
5850 +#ifdef BCM53115M_DISABLE_LEARNING
5851 +       // disable learning
5852 +       page=0x00;
5853 +       offset=0x3c;
5854 +       u16_val=0x13f;
5855 +       bcm53115M_reg_write(page, offset, (u8 *)&u16_val, 2);
5856 +       bcm53115M_reg_read(page, offset, (u8 *)&u16_val, 2);
5857 +
5858 +       page=0x02;
5859 +       offset=0x06;
5860 +       u32_val=4;
5861 +       bcm53115M_reg_write(page, offset, (u8 *)&u32_val, 4);
5862 +#endif
5863 +#endif
5864 +       return CAVM_OK;
5865 +}
5866 +#endif // defined(LINUX_KERNEL)
5867 +
5868 +//#define MAC2_RGMII
5869 +#define CNS3XXX_MAC2_IP1001_GIGA_MODE
5870 +
5871 +void icp_ip1001_init_mac(u8 mac_port, u16 phy_addr)
5872 +{
5873 +       u32 mac_port_config = 0;
5874 +       u8 mac_addr[]={0x0c, 0x10, 0x18};
5875 +
5876 +       cns3xxx_enable_mac_clock(mac_port, 1);
5877 +
5878 +       mac_port_config = SWITCH_REG_VALUE(mac_addr[mac_port]);
5879 +
5880 +       //cns3xxx_txc_dly(mac_port, 2);
5881 +       //cns3xxx_rxc_dly(mac_port, 2);
5882 +       //SLK_SKEW_CTRL_REG 
5883 +#if 1
5884 +
5885 +       // enable GMII, MII, reverse MII
5886 +       mac_port_config &= (~(1 << 15));
5887 +
5888 +#ifdef MAC2_RGMII
5889 +       mac_port_config |= (1 << 15);
5890 +#endif
5891 +
5892 +       // TXC check disable
5893 +       //mac_port_config &= (~(1 << 13));
5894 +
5895 +        // disable GIGA mode
5896 +        mac_port_config &= (~(1<<16));
5897 +
5898 +#ifdef CNS3XXX_MAC2_IP1001_GIGA_MODE
5899 +        // enable GIGA mode
5900 +        mac_port_config |= (1<<16);
5901 +
5902 +        //mac_port_config |= (1<<19);
5903 +#endif
5904 +
5905 +        // disable PHY's AN
5906 +       mac_port_config &= (~(0x1 << 7));
5907 +
5908 +        // enable PHY's AN
5909 +       mac_port_config |= (0x1 << 7);
5910 +#else
5911 +        // disable PHY's AN
5912 +       mac_port_config &= (~(0x1 << 7));
5913 +        // disable GIGA mode
5914 +        mac_port_config &= (~(1<<16));
5915 +
5916 +       // force 100Mbps
5917 +       mac_port_config &= (~(0x3 << 8));
5918 +       mac_port_config |= (0x1 << 8);
5919 +       
5920 +       // force duplex
5921 +       mac_port_config |= (0x1 << 10);
5922 +
5923 +       // TX flow control off
5924 +       mac_port_config &= (~(0x1 << 12));
5925 +
5926 +       // RX flow control off
5927 +       mac_port_config &= (~(0x1 << 11));
5928 +
5929 +#if 0
5930 +       // TX flow control on
5931 +       mac_port_config |= (0x1 << 12);
5932 +
5933 +       // RX flow control on
5934 +       mac_port_config |= (0x1 << 11);
5935 +#endif
5936 +
5937 +       // enable GMII, MII, reverse MII
5938 +       mac_port_config &= (~(1 << 15));
5939 +#endif
5940 +       SWITCH_REG_VALUE(mac_addr[mac_port]) = mac_port_config;
5941 +
5942 +       // If mac port AN turns on, auto polling needs to turn on.
5943 +       cns3xxx_phy_auto_polling_conf(mac_port, phy_addr); 
5944 +
5945 +}
5946 +
5947 +int icp_ip1001_init(u8 mac_port, u8 phy_addr)
5948 +{
5949 +        u16 phy_data = 0;
5950 +
5951 +       printk("mac_port: %d ## phy_addr: %d\n", mac_port, phy_addr);
5952 +       cns3xxx_mdc_mdio_disable(0);
5953 +
5954 +#if 0
5955 +       // GMII2 high speed drive strength
5956 +       IOCDA_REG &= ((~3 << 10));
5957 +       IOCDA_REG |= (1 << 10);
5958 +#endif
5959 +       IOCDA_REG = 0x55555800;
5960 +
5961 +       phy_data = get_phy_id(phy_addr); // should be 0x243
5962 +
5963 +       printk("ICPLUS IP 1001 phy id : %x\n", phy_data);
5964 +
5965 +       if (phy_data != 0x0243) {
5966 +               printk("wrong phy id!!\n");
5967 +               return CAVM_ERR;
5968 +       } 
5969 +
5970 +
5971 +       cns3xxx_phy_reset(phy_addr);
5972 +
5973 +       icp_ip1001_init_mac(mac_port, phy_addr);
5974 +
5975 +       // read advertisement register
5976 +       cns3xxx_read_phy(phy_addr, 0x4, &phy_data);
5977 +
5978 +       // enable PAUSE frame capability
5979 +       phy_data |= (0x1 << 10);
5980 +
5981 +       phy_data &= (~(0x1 << 5));
5982 +       phy_data &= (~(0x1 << 6));
5983 +       phy_data &= (~(0x1 << 7));
5984 +       phy_data &= (~(0x1 << 8));
5985 +
5986 +#if 1
5987 +       phy_data |= (0x1 << 5);
5988 +       phy_data |= (0x1 << 6);
5989 +       phy_data |= (0x1 << 7);
5990 +       phy_data |= (0x1 << 8);
5991 +#endif
5992 +
5993 +       cns3xxx_write_phy(phy_addr, 0x4, phy_data);
5994 +
5995 +       cns3xxx_read_phy(phy_addr, 9, &phy_data);
5996 +
5997 +       phy_data &= (~(1<<8)); // remove advertise 1000 half duples
5998 +       phy_data &= (~(1<<9)); // remove advertise 1000 full duples
5999 +#ifdef CNS3XXX_MAC2_IP1001_GIGA_MODE
6000 +       //phy_data |= (1<<8); // add advertise 1000 half duples
6001 +       phy_data |= (1<<9); // add advertise 1000 full duples
6002 +#endif
6003 +       cns3xxx_write_phy(phy_addr, 9, phy_data);
6004 +
6005 +       cns3xxx_read_phy(phy_addr, 9, &phy_data);
6006 +
6007 +       cns3xxx_read_phy(phy_addr, 0, &phy_data);
6008 +       // AN enable
6009 +       phy_data |= (0x1 << 12); 
6010 +       cns3xxx_write_phy(phy_addr, 0, phy_data);
6011 +
6012 +       cns3xxx_read_phy(phy_addr, 0, &phy_data);
6013 +       // restart AN
6014 +       phy_data |= (0x1 << 9); 
6015 +       cns3xxx_write_phy(phy_addr, 0, phy_data);
6016 +        return 0;
6017 +}
6018 +
6019 +#define PHY_CONTROL_REG_ADDR 0x00
6020 +#define PHY_AN_ADVERTISEMENT_REG_ADDR 0x04
6021 +
6022 +int icp_101a_init_mac(u8 port, u8 phy_addr)
6023 +{
6024 +       u32 mac_port_config = 0;
6025 +
6026 +       cns3xxx_enable_mac_clock(port, 1);
6027 +
6028 +       switch (port)
6029 +       {
6030 +               case 0:
6031 +               {
6032 +                       mac_port_config = MAC0_CFG_REG;
6033 +                       break;
6034 +               }
6035 +               case 1:
6036 +               {
6037 +                       mac_port_config = MAC1_CFG_REG;
6038 +                       break;
6039 +               }
6040 +               case 2:
6041 +               {
6042 +                       mac_port_config = MAC2_CFG_REG;
6043 +                       break;
6044 +               }
6045 +       }
6046 +
6047 +       // enable GMII, MII, reverse MII
6048 +       mac_port_config &= (~(1 << 15));
6049 +
6050 +        // disable PHY's AN, use force mode
6051 +       mac_port_config &= (~(0x1 << 7));
6052 +#ifdef CONFIG_FPGA_FORCE
6053 +
6054 +       // force 100Mbps
6055 +       mac_port_config &= (~(0x3 << 8));
6056 +       mac_port_config |= (0x1 << 8);
6057 +       
6058 +       // force duplex
6059 +       mac_port_config |= (0x1 << 10);
6060 +
6061 +       // TX flow control on
6062 +       mac_port_config |= (0x1 << 12);
6063 +
6064 +       // RX flow control on
6065 +       mac_port_config |= (0x1 << 11);
6066 +
6067 +       // Turn off GSW_PORT_TX_CHECK_EN_BIT
6068 +       mac_port_config &= (~(0x1 << 13));
6069 +#else
6070 +        // enable PHY's AN
6071 +       mac_port_config |= (0x1 << 7);
6072 +       // If mac port AN turns on, auto polling needs to turn on.
6073 +       cns3xxx_phy_auto_polling_conf(port, phy_addr); 
6074 +#endif
6075 +       // normal MII
6076 +       mac_port_config &= (~(1 << 14));
6077 +
6078 +
6079 +       switch (port)
6080 +       {
6081 +               case 0:
6082 +               {
6083 +                       MAC0_CFG_REG = mac_port_config;
6084 +                       break;
6085 +               }
6086 +               case 1:
6087 +               {
6088 +                       MAC1_CFG_REG = mac_port_config;
6089 +                       break;
6090 +               }
6091 +               case 2:
6092 +               {
6093 +                       MAC2_CFG_REG = mac_port_config;
6094 +                       break;
6095 +               }
6096 +       }
6097 +
6098 +
6099 +       return CAVM_OK;
6100 +}
6101 +
6102 +int icp_101a_init(u8 mac_port, u8 phy_addr)
6103 +{
6104 +       u32 mac_port_config=0;
6105 +        u16 phy_data = 0;
6106 +
6107 +       cns3xxx_mdc_mdio_disable(0);
6108 +       cns3xxx_phy_reset(phy_addr);
6109 +
6110 +       phy_data = get_phy_id(mac_port);
6111 +       if (phy_data != 0x0243) {
6112 +               printk("ICPLUS 101A phy id should be 0x243, but the phy id is : %x\n", phy_data);
6113 +               return CAVM_ERR;
6114 +       }
6115 +       printk("phy id : %x\n", phy_data);
6116 +       printk("init IC+101A\n");
6117 +
6118 +       icp_101a_init_mac(mac_port, phy_addr);
6119 +
6120 +       // read advertisement register
6121 +       cns3xxx_read_phy(phy_addr, 0x4, &phy_data);
6122 +
6123 +       // enable PAUSE frame capability
6124 +       phy_data |= (0x1 << 10);
6125 +
6126 +       cns3xxx_write_phy(phy_addr, 0x4, phy_data);
6127 +
6128 +#ifndef CONFIG_FPGA_FORCE
6129 +
6130 +       switch (mac_port)
6131 +       {
6132 +               case 0:
6133 +               {
6134 +                       mac_port_config = MAC0_CFG_REG;
6135 +                       break;
6136 +               }
6137 +               case 1:
6138 +               {
6139 +                       mac_port_config = MAC1_CFG_REG;
6140 +                       break;
6141 +               }
6142 +               case 2:
6143 +               {
6144 +                       mac_port_config = MAC2_CFG_REG;
6145 +                       break;
6146 +               }
6147 +       }
6148 +
6149 +#if 0
6150 +       if (!(mac_port_config & (0x1 << 5))) {
6151 +               if (cns3xxx_read_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, &phy_data) == CAVM_ERR)
6152 +               {
6153 +                       //PDEBUG("\n PORT%d, enable local flow control capability Fail\n", port);
6154 +                       return CAVM_ERR;
6155 +               }
6156 +               else
6157 +               {
6158 +                       // enable PAUSE frame capability
6159 +                       phy_data |= (0x1 << 10);
6160 +
6161 +                       if (cns3xxx_write_phy (port, PHY_AN_ADVERTISEMENT_REG_ADDR, phy_data) == CAVM_ERR)
6162 +                       {
6163 +                               //PDEBUG("\nPORT%d, enable PAUSE frame capability Fail\n", port);
6164 +                               return CAVM_ERR;
6165 +                       }
6166 +               }
6167 +       }
6168 +#endif
6169 +
6170 +       cns3xxx_read_phy(phy_addr, 0, &phy_data);
6171 +       // an enable
6172 +       phy_data |= (0x1 << 12); 
6173 +
6174 +       // restart AN
6175 +       phy_data |= (0x1 << 9); 
6176 +       cns3xxx_write_phy(phy_addr, 0, phy_data);
6177 +
6178 +       while (1)
6179 +       {
6180 +               //PDEBUG ("\n Polling  PHY%d AN \n", port);
6181 +               cns3xxx_read_phy (phy_data, 0, &phy_data);
6182 +
6183 +               if (phy_data & (0x1 << 9)) {
6184 +                       continue;
6185 +               } else {
6186 +                       //PDEBUG ("\n PHY%d AN restart is complete \n", port);
6187 +                       break;
6188 +               }
6189 +       }
6190 +
6191 +#endif
6192 +
6193 +       return CAVM_OK;
6194 +}
6195 +
6196 +int cns3xxx_config_VSC8601_mac(u8 port)
6197 +{
6198 +       u32 mac_port_config = 0;
6199 +
6200 +       switch (port)
6201 +       {
6202 +               case 0:
6203 +               {
6204 +                       mac_port_config = MAC0_CFG_REG;
6205 +                       break;
6206 +               }
6207 +               case 1:
6208 +               {
6209 +                       mac_port_config = MAC1_CFG_REG;
6210 +                       break;
6211 +               }
6212 +               case 2:
6213 +               {
6214 +                       mac_port_config = MAC2_CFG_REG;
6215 +                       break;
6216 +               }
6217 +       }
6218 +
6219 +       switch (port)
6220 +       {
6221 +               case 0:
6222 +               {
6223 +                       MAC0_CFG_REG = mac_port_config;
6224 +                       break;
6225 +               }
6226 +               case 1:
6227 +               {
6228 +                       MAC1_CFG_REG = mac_port_config;
6229 +                       break;
6230 +               }
6231 +               case 2:
6232 +               {
6233 +                       MAC2_CFG_REG = mac_port_config;
6234 +                       break;
6235 +               }
6236 +       }
6237 +       return CAVM_OK;
6238 +}
6239 +
6240 +u16 get_phy_id(u8 phy_addr)
6241 +{
6242 +       u16 read_data;
6243 +
6244 +       cns3xxx_read_phy(phy_addr, 2, &read_data);
6245 +
6246 +       return read_data;
6247 +}
6248 +
6249 +u32 get_vsc8601_recv_err_counter(u8 phy_addr)
6250 +{
6251 +       u16 read_data=0;
6252 +       cns3xxx_read_phy(phy_addr, 19, &read_data);
6253 +       return read_data;
6254 +}
6255 +
6256 +u32 get_crc_good_counter(u8 phy_addr)
6257 +{
6258 +       u16 read_data=0;
6259 +
6260 +       // enter extended register mode
6261 +       cns3xxx_write_phy(phy_addr, 31, 0x0001);
6262 +
6263 +       cns3xxx_read_phy(phy_addr, 18, &read_data);
6264 +
6265 +       // back to normal register mode
6266 +       cns3xxx_write_phy(phy_addr, 31, 0x0000);
6267 +
6268 +       return read_data;
6269 +}
6270 +
6271 +int cns3xxx_config_VSC8601(u8 mac_port, u8 phy_addr)
6272 +{
6273 +        u16 phy_data=0;
6274 +       u32 mac_port_config=0;
6275 +       //u8 tx_skew=1, rx_skew=1;
6276 +       u16 phy_id=0;
6277 +       
6278 +       cns3xxx_mdc_mdio_disable(0);
6279 +
6280 +       cns3xxx_read_phy(phy_addr, 0, &phy_data);
6281 +       // software reset
6282 +       phy_data |= (0x1 << 15); 
6283 +       cns3xxx_write_phy(phy_addr, 0, phy_data);
6284 +       udelay(10);
6285 +
6286 +       phy_id = get_phy_id(phy_addr);
6287 +       if (phy_id != 0x143) {
6288 +               return CAVM_ERR;
6289 +       }
6290 +
6291 +       switch (mac_port)
6292 +       {
6293 +               case 0:
6294 +               {
6295 +                       mac_port_config = MAC0_CFG_REG;
6296 +                       break;
6297 +               }
6298 +               case 1:
6299 +               {
6300 +                       mac_port_config = MAC1_CFG_REG;
6301 +                       break;
6302 +               }
6303 +               case 2:
6304 +               {
6305 +                       mac_port_config = MAC2_CFG_REG;
6306 +                       break;
6307 +               }
6308 +       }
6309 +               
6310 +       cns3xxx_enable_mac_clock(mac_port, 1);
6311 +        //phy_auto_polling(mac_port, phy_addr);
6312 +        
6313 +       // enable RGMII-PHY mode
6314 +       mac_port_config |= (0x1 << 15);
6315 +
6316 +       // If mac AN turns on, auto polling needs to turn on.
6317 +        // enable PHY's AN
6318 +       mac_port_config |= (0x1 << 7);
6319 +       cns3xxx_phy_auto_polling_conf(mac_port, phy_addr); 
6320 +       
6321 +       // enable GSW MAC port 0
6322 +       mac_port_config &= ~(0x1 << 18);
6323 +
6324 +       // normal MII
6325 +       mac_port_config &= (~(1 << 14));
6326 +
6327 +       switch (mac_port)
6328 +       {
6329 +               case 0:
6330 +               {
6331 +                       MAC0_CFG_REG = mac_port_config;
6332 +                       printk("8601 MAC0_CFG_REG: %x\n", MAC0_CFG_REG);
6333 +                       break;
6334 +               }
6335 +               case 1:
6336 +               {
6337 +                       MAC1_CFG_REG = mac_port_config;
6338 +                       printk("8601 MAC1_CFG_REG: %x\n", MAC1_CFG_REG);
6339 +                       break;
6340 +               }
6341 +               case 2:
6342 +               {
6343 +                       MAC2_CFG_REG = mac_port_config;
6344 +                       break;
6345 +               }
6346 +       }
6347 +
6348 +       cns3xxx_write_phy(phy_addr, 0x18, 0xf1e7);
6349 +       cns3xxx_write_phy(phy_addr, 0x1c, 0x8e00);
6350 +       cns3xxx_write_phy(phy_addr, 0x10, 0x20);
6351 +       cns3xxx_write_phy(phy_addr, 0x1c, 0xa41f);
6352 +       cns3xxx_write_phy(phy_addr, 0x1c, 0xb41a);
6353 +       cns3xxx_write_phy(phy_addr, 0x1c, 0xb863);
6354 +       cns3xxx_write_phy(phy_addr, 0x17, 0xf04);
6355 +       cns3xxx_write_phy(phy_addr, 0x15, 0x1);
6356 +       cns3xxx_write_phy(phy_addr, 0x17, 0x0);
6357 +                            
6358 +       return CAVM_OK;
6359 +}
6360 +
6361 +
6362 +
6363 +#ifdef CONFIG_LIBRA
6364 +void icp_175c_all_phy_power_down(int y)
6365 +{
6366 +        int i=0;
6367 +
6368 +        for (i=0 ; i < 5 ; ++i)
6369 +                std_phy_power_down(i, y);
6370 +
6371 +}
6372 +
6373 +static int star_gsw_config_icplus_175c_phy4(void)
6374 +{
6375 +    u16                        phy_data = 0, phy_data2 = 0;
6376 +    u32 volatile       ii, jj;
6377 +    u8                 phy_speed_dup = 0, phy_flowctrl = 0;
6378 +    u32 volatile       reg;
6379 +       u8 gsw_mac_0_phy_addr = 0;
6380 +       u8 gsw_mac_1_phy_addr = 1;
6381 +
6382 +
6383 +       printk("config IC+175C\n");
6384 +    /*
6385 +     * Configure MAC port 0
6386 +     * For IP175C Switch setting
6387 +     * Force 100Mbps, and full-duplex, and flow control on
6388 +     */
6389 +    reg = GSW_MAC_PORT_0_CONFIG_REG;
6390 +
6391 +    // disable PHY's AN
6392 +    reg &= ~(0x1 << 7);
6393 +
6394 +    // disable RGMII-PHY mode
6395 +    reg &= ~(0x1 << 15);
6396 +
6397 +    // force speed = 100Mbps
6398 +    reg &= ~(0x3 << 8);
6399 +    reg |= (0x1 << 8);
6400 +    
6401 +    // force full-duplex
6402 +    reg |= (0x1 << 10);
6403 +
6404 +    // force Tx/Rx flow-control on
6405 +    reg |= (0x1 << 11) | (0x1 << 12);
6406 +
6407 +    GSW_MAC_PORT_0_CONFIG_REG = reg;
6408 +
6409 +
6410 +    for (ii = 0; ii < 0x2000; ii++)
6411 +    {
6412 +       reg = GSW_MAC_PORT_0_CONFIG_REG;
6413 +       
6414 +        if ((reg & 0x1) && !(reg & 0x2))
6415 +        {
6416 +            /*
6417 +             * enable MAC port 0
6418 +             */
6419 +            reg &= ~(0x1 << 18);
6420 +
6421 +           
6422 +            /*
6423 +             * enable the forwarding of unknown, multicast and broadcast packets to CPU
6424 +             */
6425 +            reg &= ~((0x1 << 25) | (0x1 << 26) | (0x1 << 27));
6426 +        
6427 +            /*
6428 +             * include unknown, multicast and broadcast packets into broadcast storm
6429 +             */
6430 +            reg |= ((0x1 << 29) | (0x1 << 30) | ((u32)0x1 << 31));
6431 +            
6432 +               GSW_MAC_PORT_0_CONFIG_REG = reg;
6433 +            
6434 +            break;
6435 +        }
6436 +        else
6437 +        {
6438 +            for (jj = 0; jj < 0x1000; jj++);
6439 +                       
6440 +                       
6441 +            if ((ii % 4) == 0)
6442 +                printk("\rCheck MAC/PHY 0 Link Status : |");
6443 +            else if ((ii % 4) == 1)
6444 +                printk("\rCheck MAC/PHY 0 Link Status : /");
6445 +            else if ((ii % 4) == 2)
6446 +                printk("\rCheck MAC/PHY 0 Link Status : -");
6447 +            else if ((ii % 4) == 3)
6448 +                printk("\rCheck MAC/PHY 0 Link Status : \\");
6449 +        }
6450 +    }
6451 +
6452 +
6453 +    if (!(reg & 0x1) || (reg & 0x2))
6454 +    {
6455 +        /*
6456 +         * Port 0 PHY link down or no TXC in Port 0
6457 +         */
6458 +        printk("\rCheck MAC/PHY 0 Link Status : DOWN!\n");
6459 +        
6460 +        return -1;
6461 +    }
6462 +    else
6463 +    {
6464 +        printk("\rCheck MAC/PHY 0 Link Status : UP!\n");
6465 +    }
6466 +
6467 +
6468 +
6469 +    /*
6470 +     * Configure MAC port 1
6471 +     */
6472 +       reg = GSW_MAC_PORT_0_CONFIG_REG;
6473 +    
6474 +    // disable MAC's AN
6475 +    reg &= ~(0x1 << 7);
6476 +
6477 +       GSW_MAC_PORT_0_CONFIG_REG = reg;
6478 +
6479 +
6480 +    /* enable flow control on (PAUSE frame) */
6481 +    star_gsw_read_phy(gsw_mac_1_phy_addr, 0x4, &phy_data);
6482 +               
6483 +    phy_data |= (0x1 << 10);           
6484 +
6485 +    star_gsw_write_phy(gsw_mac_1_phy_addr, 0x4, phy_data);
6486 +
6487 +#if 1
6488 +       /* 2007/12/18 Jerry
6489 +               The software reset of IC+ 175C won't reset MII register 29, 30, 31.
6490 +               Router Control Register: bit 7 (TAG_VLAN_EN) is a VLAN related filed which affect vlan setting.
6491 +               Router Control Register: bit 3 (ROUTER_EN) enable router function at MII port.
6492 +               We set them to default to let U-boot properly work.
6493 +       */
6494 +       phy_data = 0x1001;
6495 +    star_gsw_write_phy(30, 9, phy_data);
6496 +#endif
6497 +    /* restart PHY auto neg. */
6498 +    star_gsw_read_phy(gsw_mac_1_phy_addr, 0x0, &phy_data);
6499 +               
6500 +    phy_data |= (0x1 << 9) | (0x1 << 12);              
6501 +
6502 +    star_gsw_write_phy(gsw_mac_1_phy_addr, 0x0, phy_data);
6503 +
6504 +
6505 +
6506 +    /* wait for PHY auto neg. complete */
6507 +    for (ii = 0; ii < 0x20; ii++)
6508 +    {
6509 +        star_gsw_read_phy(gsw_mac_1_phy_addr, 0x1, &phy_data);
6510 +                       
6511 +        if ((phy_data & (0x1 << 2)) && (phy_data & (0x1 << 5)))
6512 +        {
6513 +            break;
6514 +        }
6515 +        else
6516 +        {                      
6517 +            if ((ii % 4) == 0)
6518 +                printk("\rCheck MAC/PHY 1 Link Status : |");
6519 +            else if ((ii % 4) == 1)
6520 +                printk("\rCheck MAC/PHY 1 Link Status : /");
6521 +            else if ((ii % 4) == 2)
6522 +                printk("\rCheck MAC/PHY 1 Link Status : -");
6523 +            else if ((ii % 4) == 3)
6524 +                printk("\rCheck MAC/PHY 1 Link Status : \\");
6525 +        }
6526 +    }          
6527 +
6528 +
6529 +    if (ii >= 0x20)
6530 +    {
6531 +        printk("\rCheck MAC/PHY 1 Link Status : DOWN!\n");
6532 +        
6533 +        return -1;
6534 +    }
6535 +    else
6536 +    {
6537 +        printk("\rCheck MAC/PHY 1 Link Status : UP!\n");
6538 +    }
6539 +
6540 +
6541 +    star_gsw_read_phy(gsw_mac_1_phy_addr, 0x4, &phy_data);
6542 +
6543 +    star_gsw_read_phy(gsw_mac_1_phy_addr, 0x5, &phy_data2);
6544 +
6545 +
6546 +    if (phy_data & 0x0400)     //FC on
6547 +    {
6548 +        //printk("<FC ON>");
6549 +        phy_flowctrl = 1;
6550 +    }
6551 +    else    
6552 +    {
6553 +        // printk("<FC OFF>");
6554 +        phy_flowctrl = 0;
6555 +    }    
6556 +    
6557 +    
6558 +    phy_speed_dup = 0;
6559 +    
6560 +    if ((phy_data & 0x0100) && (phy_data2 & 0x0100)) //100F
6561 +    {
6562 +        // printk("<100F>");
6563 +        phy_speed_dup |= (0x1 << 3); //set bit3 for 100F
6564 +    }
6565 +    else if ((phy_data & 0x0080) && (phy_data2 & 0x0080)) //100F
6566 +    {
6567 +        // printk("<100H>");
6568 +        phy_speed_dup |= (0x1 << 2);
6569 +    }
6570 +    else if ((phy_data & 0x0040) && (phy_data2 & 0x0040)) //100F
6571 +    {
6572 +        // printk("<10F>");
6573 +        phy_speed_dup |= (0x1 << 1);
6574 +    }
6575 +    else if ((phy_data & 0x0020) && (phy_data2 & 0x0020)) //100F
6576 +    {
6577 +        // printk("<10H>");
6578 +        phy_speed_dup |= 0x1;    
6579 +    }
6580 +
6581 +
6582 +    /*
6583 +     * Configure MAC port 1 in forced setting subject to the current PHY status
6584 +     */     
6585 +       reg = GSW_MAC_PORT_1_CONFIG_REG;
6586 +     
6587 +    reg &= ~(0x1 << 7);        //AN off
6588 +            
6589 +    reg &= ~(0x3 << 8);
6590 +            
6591 +    if (phy_speed_dup & 0x0C)     //100
6592 +    {          
6593 +        //printk("<set 100>");
6594 +        reg |= (0x01 << 8);              
6595 +    }
6596 +    else if (phy_speed_dup & 0x03)     //10          
6597 +    {
6598 +        //printk("<set 10>");
6599 +        reg |= (0x00 << 8);
6600 +    }
6601 +           
6602 +    reg &= ~(0x1 << 11);
6603 +            
6604 +    if (phy_flowctrl)  //FC on
6605 +    {
6606 +        //printk("<set FC on>");
6607 +        reg |= (0x1 << 11);
6608 +    }  
6609 +    else
6610 +    {
6611 +        //printk("<set FC off>");
6612 +        reg |= (0x0 << 11);                            
6613 +    }            
6614 +            
6615 +    reg &= ~(0x1 << 10);
6616 +            
6617 +    if ((phy_speed_dup & 0x2) || (phy_speed_dup & 0x8))        //FullDup
6618 +    {
6619 +        //printk("<set full>");
6620 +        reg |= (0x1 << 10);
6621 +    }
6622 +    else       //HalfDup
6623 +    {
6624 +        //printk("<set half>");
6625 +        reg |= (0x0 << 10); //Half                                             
6626 +    }
6627 +            
6628 +       GSW_MAC_PORT_1_CONFIG_REG = reg;
6629 +
6630 +
6631 +    /*
6632 +     * Check MAC port 1 link status
6633 +     */
6634 +    for (ii = 0; ii < 0x1000; ii++)
6635 +    {
6636 +       reg = GSW_MAC_PORT_1_CONFIG_REG;
6637 +       
6638 +        if ((reg & 0x1) && !(reg & 0x2))
6639 +        {
6640 +            /*
6641 +             * enable MAC port 1
6642 +             */
6643 +            reg &= ~(0x1 << 18);
6644 +
6645 +            /*
6646 +             * enable the forwarding of unknown, multicast and broadcast packets to CPU
6647 +             */
6648 +            reg &= ~((0x1 << 25) | (0x1 << 26) | (0x1 << 27));
6649 +        
6650 +            /*
6651 +             * include unknown, multicast and broadcast packets into broadcast storm
6652 +             */
6653 +            reg |= ((0x1 << 29) | (0x1 << 30) | ((u32)0x1 << 31));
6654 +            
6655 +       GSW_MAC_PORT_1_CONFIG_REG = reg;
6656 +            
6657 +            return 0;
6658 +        }
6659 +    }
6660 +
6661 +
6662 +    if (ii > 0x1000)
6663 +    {
6664 +        /*
6665 +         * Port 1 PHY link down or no TXC in Port 1
6666 +         */
6667 +        printk("\rCheck MAC/PHY 1 Link Status : DOWN!\n");
6668 +        
6669 +        return -1;
6670 +    }
6671 +       return 0;
6672 +}
6673 +#endif
6674 +
6675 +#if 0
6676 +static int star_gsw_config_VSC8201(u8 mac_port, u8 phy_addr)   // include cicada 8201
6677 +{
6678 +       //u32 mac_port_base = 0;
6679 +       u32 mac_port_config=0;
6680 +       u16 phy_reg;
6681 +       int i;
6682 +
6683 +       printk("\nconfigure VSC8201\n");
6684 +       //PDEBUG("mac port : %d phy addr : %d\n", mac_port, phy_addr);
6685 +       /*
6686 +        * Configure MAC port 0
6687 +        * For Cicada CIS8201 single PHY
6688 +        */
6689 +       if (mac_port == 0) {
6690 +               //PDEBUG("port 0\n");
6691 +               mac_port_config = GSW_MAC_PORT_0_CONFIG_REG;
6692 +       }
6693 +       if (mac_port == 1) {
6694 +               //PDEBUG("port 1\n");
6695 +               mac_port_config = GSW_MAC_PORT_1_CONFIG_REG;
6696 +       }
6697 +
6698 +       star_gsw_set_phy_addr(mac_port, phy_addr);
6699 +       //star_gsw_set_phy_addr(1, 1);
6700 +
6701 +       //mac_port_config = __REG(mac_port_base);
6702 +
6703 +       // enable PHY's AN
6704 +       mac_port_config |= (0x1 << 7);
6705 +
6706 +       // enable RGMII-PHY mode
6707 +       mac_port_config |= (0x1 << 15);
6708 +
6709 +       // enable GSW MAC port 0
6710 +       mac_port_config &= ~(0x1 << 18);
6711 +
6712 +       if (mac_port == 0) {
6713 +               //PDEBUG("port 0\n");
6714 +               GSW_MAC_PORT_0_CONFIG_REG = mac_port_config;
6715 +       }
6716 +       if (mac_port == 1) {
6717 +               //PDEBUG("port 1\n");
6718 +               GSW_MAC_PORT_1_CONFIG_REG = mac_port_config;
6719 +       }
6720 +
6721 +       /*
6722 +        * Configure Cicada's CIS8201 single PHY
6723 +        */
6724 +#ifdef CONFIG_STAR9100_SHNAT_PCI_FASTPATH
6725 +       /* near-end loopback mode */
6726 +       star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
6727 +       phy_reg |= (0x1 << 14);
6728 +       star_gsw_write_phy(phy_addr, 0x0, phy_reg);
6729 +#endif
6730 +
6731 +       star_gsw_read_phy(phy_addr, 0x1C, &phy_reg);
6732 +
6733 +       // configure SMI registers have higher priority over MODE/FRC_DPLX, and ANEG_DIS pins
6734 +       phy_reg |= (0x1 << 2);
6735 +
6736 +       star_gsw_write_phy(phy_addr, 0x1C, phy_reg);
6737 +
6738 +       star_gsw_read_phy(phy_addr, 0x17, &phy_reg);
6739 +
6740 +       // enable RGMII MAC interface mode
6741 +       phy_reg &= ~(0xF << 12);
6742 +       phy_reg |= (0x1 << 12);
6743 +
6744 +       // enable RGMII I/O pins operating from 2.5V supply
6745 +       phy_reg &= ~(0x7 << 9);
6746 +       phy_reg |= (0x1 << 9);
6747 +
6748 +       star_gsw_write_phy(phy_addr, 0x17, phy_reg);
6749 +
6750 +       star_gsw_read_phy(phy_addr, 0x4, &phy_reg);
6751 +
6752 +       // Enable symmetric Pause capable
6753 +       phy_reg |= (0x1 << 10);
6754 +
6755 +       star_gsw_write_phy(phy_addr, 0x4, phy_reg);
6756 +
6757 +
6758 +
6759 +       if (mac_port == 0) {
6760 +               //PDEBUG("port 0\n");
6761 +               mac_port_config = GSW_MAC_PORT_0_CONFIG_REG;
6762 +       }
6763 +       if (mac_port == 1) {
6764 +               //PDEBUG("port 1\n");
6765 +               mac_port_config = GSW_MAC_PORT_1_CONFIG_REG;
6766 +       }
6767 +
6768 +
6769 +
6770 +
6771 +
6772 +
6773 +
6774 +       // enable PHY's AN
6775 +       mac_port_config |= (0x1 << 7);
6776 +
6777 +       if (mac_port == 0) {
6778 +               //PDEBUG("port 0\n");
6779 +               GSW_MAC_PORT_0_CONFIG_REG = mac_port_config;
6780 +       }
6781 +       if (mac_port == 1) {
6782 +               //PDEBUG("port 1\n");
6783 +               GSW_MAC_PORT_1_CONFIG_REG = mac_port_config;
6784 +       }
6785 +
6786 +       /*
6787 +        * Enable PHY1 AN restart bit to restart PHY1 AN
6788 +        */
6789 +       star_gsw_read_phy(phy_addr, 0x0, &phy_reg);
6790 +
6791 +       phy_reg |= (0x1 << 9) | (0x1 << 12);
6792 +
6793 +       star_gsw_write_phy(phy_addr, 0x0, phy_reg);
6794 +
6795 +       /*
6796 +        * Polling until PHY0 AN restart is complete
6797 +        */
6798 +       for (i = 0; i < 0x1000; i++) {
6799 +               star_gsw_read_phy(phy_addr, 0x1, &phy_reg);
6800 +
6801 +               if ((phy_reg & (0x1 << 5)) && (phy_reg & (0x1 << 2))) {
6802 +                       printk("0x1 phy reg: %x\n", phy_reg);
6803 +                       break;
6804 +               } else {
6805 +                       udelay(100);
6806 +               }
6807 +       }
6808 +
6809 +       if (mac_port == 0) {
6810 +               //PDEBUG("port 0\n");
6811 +               mac_port_config = GSW_MAC_PORT_0_CONFIG_REG;
6812 +       }
6813 +       if (mac_port == 1) {
6814 +               //PDEBUG("port 1\n");
6815 +               mac_port_config = GSW_MAC_PORT_1_CONFIG_REG;
6816 +       }
6817 +
6818 +       if (((mac_port_config & 0x1) == 0) || (mac_port_config & 0x2)) {
6819 +               printk("Check MAC/PHY%s Link Status : DOWN!\n", (mac_port == 0 ? "0" : "1"));
6820 +       } else {
6821 +               printk("Check MAC/PHY%s Link Status : UP!\n", (mac_port == 0 ? "0" : "1"));
6822 +               /*
6823 +                * There is a bug for CIS8201 PHY operating at 10H mode, and we use the following
6824 +                * code segment to work-around
6825 +                */
6826 +               star_gsw_read_phy(phy_addr, 0x05, &phy_reg);
6827 +
6828 +               if ((phy_reg & (0x1 << 5)) && (!(phy_reg & (0x1 << 6))) && (!(phy_reg & (0x1 << 7))) && (!(phy_reg & (0x1 << 8)))) {    /* 10H,10F/100F/100H off */
6829 +                       star_gsw_read_phy(phy_addr, 0x0a, &phy_reg);
6830 +
6831 +                       if ((!(phy_reg & (0x1 << 10))) && (!(phy_reg & (0x1 << 11)))) { /* 1000F/1000H off */
6832 +                               star_gsw_read_phy(phy_addr, 0x16, &phy_reg);
6833 +
6834 +                               phy_reg |= (0x1 << 13) | (0x1 << 15);   // disable "Link integrity check(B13)" & "Echo mode(B15)"
6835 +
6836 +                               star_gsw_write_phy(phy_addr, 0x16, phy_reg);
6837 +                       }
6838 +               }
6839 +       }
6840 +
6841 +       if (mac_port == 0) {
6842 +               // adjust MAC port 0 RX/TX clock skew
6843 +               GSW_BIST_RESULT_TEST_0_REG &= ~((0x3 << 24) | (0x3 << 26));
6844 +               GSW_BIST_RESULT_TEST_0_REG |= ((0x2 << 24) | (0x2 << 26));
6845 +       }
6846 +
6847 +       if (mac_port == 1) {
6848 +               // adjust MAC port 1 RX/TX clock skew
6849 +               GSW_BIST_RESULT_TEST_0_REG &= ~((0x3 << 28) | (0x3 << 30));
6850 +               GSW_BIST_RESULT_TEST_0_REG |= ((0x2 << 28) | (0x2 << 30));
6851 +       }
6852 +
6853 +       return 0;
6854 +}
6855 +
6856 +
6857 +
6858 +
6859 +static void star_gsw_config_VSC8X01()
6860 +{
6861 +   u16 phy_id = 0;
6862 +   
6863 +#ifdef CONFIG_DORADO2
6864 +   star_gsw_set_phy_addr(1,1);
6865 +   star_gsw_read_phy(1, 0x02, &phy_id);
6866 + //  printk("phy id = %X\n", phy_id);
6867 +   if (phy_id == 0x000F) //VSC8201
6868 +       star_gsw_config_VSC8201(1,1);
6869 +   else
6870 +       star_gsw_config_VSC8601(1,1);
6871 +#else
6872 +#ifdef CONFIG_LEO
6873 +   star_gsw_set_phy_addr(0,0);
6874 +   star_gsw_read_phy(0, 0x02, &phy_id);
6875 + //  printk("phy id = %X\n", phy_id);
6876 +   if (phy_id == 0x000F) //VSC8201
6877 +       star_gsw_config_VSC8201(0,0);
6878 +   else
6879 +       star_gsw_config_VSC8601(0,0);
6880 +#endif
6881 +#endif
6882 +}
6883 +#endif
6884 +
6885 +#if defined(CONFIG_DORADO) || defined(CONFIG_DORADO2)
6886 +static int star_gsw_config_port0_VSC7385(void)
6887 +{
6888 +       u32 mac_port_config=0;
6889 +       int i;
6890 +
6891 +       printk("config VSC7385\n");
6892 +
6893 +       mac_port_config = GSW_MAC_PORT_0_CONFIG_REG;
6894 +
6895 +       // disable PHY's AN
6896 +       mac_port_config &= ~(0x1 << 7);
6897 +
6898 +       // enable RGMII-PHY mode
6899 +       mac_port_config |= (0x1 << 15);
6900 +
6901 +       // force speed = 1000Mbps
6902 +       mac_port_config &= ~(0x3 << 8);
6903 +       mac_port_config |= (0x2 << 8);
6904 +
6905 +       // force full-duplex
6906 +       mac_port_config |= (0x1 << 10);
6907 +
6908 +       // force Tx/Rx flow-control on
6909 +       mac_port_config |= (0x1 << 11) | (0x1 << 12);
6910 +
6911 +       GSW_MAC_PORT_0_CONFIG_REG = mac_port_config;
6912 +
6913 +       udelay(1000);
6914 +
6915 +       for (i = 0; i < 50000; i++) {
6916 +               mac_port_config = GSW_MAC_PORT_0_CONFIG_REG;
6917 +               if ((mac_port_config & 0x1) && !(mac_port_config & 0x2)) {
6918 +                       break;
6919 +               } else {
6920 +                       udelay(100);
6921 +               }
6922 +       }
6923 +
6924 +       if (!(mac_port_config & 0x1) || (mac_port_config & 0x2)) {
6925 +               printk("MAC0 PHY Link Status : DOWN!\n");
6926 +               return -1;
6927 +       } else {
6928 +               printk("MAC0 PHY Link Status : UP!\n");
6929 +       }
6930 +
6931 +       // enable MAC port 0
6932 +       mac_port_config &= ~(0x1 << 18);
6933 +
6934 +       // disable SA learning
6935 +       mac_port_config |= (0x1 << 19);
6936 +
6937 +       // forward unknown, multicast and broadcast packets to CPU
6938 +       mac_port_config &= ~((0x1 << 25) | (0x1 << 26) | (0x1 << 27));
6939 +
6940 +       // storm rate control for unknown, multicast and broadcast packets
6941 +       mac_port_config |= (0x1 << 29) | (0x1 << 30) | ((u32)0x1 << 31);
6942 +
6943 +       GSW_MAC_PORT_0_CONFIG_REG = mac_port_config;
6944 +
6945 +       // disable MAC port 1
6946 +       mac_port_config = GSW_MAC_PORT_1_CONFIG_REG;
6947 +       mac_port_config |= (0x1 << 18);
6948 +       GSW_MAC_PORT_1_CONFIG_REG = mac_port_config;
6949 +
6950 +       // adjust MAC port 0 /RX/TX clock skew
6951 +       GSW_BIST_RESULT_TEST_0_REG &= ~((0x3 << 24) | (0x3 << 26));
6952 +       GSW_BIST_RESULT_TEST_0_REG |= ((0x2 << 24) | (0x2 << 26));
6953 +
6954 +       return 0;
6955 +}
6956 +#endif
6957 --- /dev/null
6958 +++ b/drivers/net/cns3xxx/cns3xxx_phy.h
6959 @@ -0,0 +1,82 @@
6960 +/*******************************************************************************
6961 + *
6962 + *
6963 + *   Copyright (c) 2009 Cavium Networks 
6964 + *
6965 + *   This program is free software; you can redistribute it and/or modify it
6966 + *   under the terms of the GNU General Public License as published by the Free
6967 + *   Software Foundation; either version 2 of the License, or (at your option)
6968 + *   any later version.
6969 + *
6970 + *   This program is distributed in the hope that it will be useful, but WITHOUT
6971 +1*   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6972 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
6973 + *   more details.
6974 + *
6975 + *   You should have received a copy of the GNU General Public License along with
6976 + *   this program; if not, write to the Free Software Foundation, Inc., 59
6977 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
6978 + *
6979 + *   The full GNU General Public License is included in this distribution in the
6980 + *   file called LICENSE.
6981 + *
6982 + ********************************************************************************/
6983 +
6984 +#ifndef CNS3XXX_PHY_H
6985 +#define CNS3XXX_PHY_H
6986 +
6987 +#define LINUX_KERNEL // if don't define LINUX_KERNEL, mean u-boot
6988 +
6989 +#if defined(LINUX_KERNEL)
6990 +#include <linux/version.h>
6991 +#include <linux/types.h>
6992 +#else // u-boot
6993 +#define __init_or_module
6994 +#include "cns3xxx_symbol.h"
6995 +#endif
6996 +
6997 +void disable_AN(int port, int y);
6998 +
6999 +u16 get_phy_id(u8 phy_addr);
7000 +int cns3xxx_std_phy_power_down(int phy_addr, int y);
7001 +u32 get_vsc8601_recv_err_counter(u8 phy_addr);
7002 +u32 get_crc_good_counter(u8 phy_addr);
7003 +int cns3xxx_config_VSC8601(u8 mac_port, u8 phy_addr);
7004 +int vsc8601_power_down(int phy_addr, int y);
7005 +int icp_101a_init(u8 mac_port, u8 phy_addr);
7006 +int bcm53115M_init(u8 mac_port, u16 phy_addr);
7007 +int icp_ip1001_init(u8 mac_port, u8 phy_addr);
7008 +
7009 +int cns3xxx_phy_auto_polling_enable(u8 port, u8 en);
7010 +
7011 +int cns3xxx_read_phy(u8 phy_addr, u8 phy_reg, u16 *read_data);
7012 +int cns3xxx_write_phy(u8 phy_addr, u8 phy_reg, u16 write_data);
7013 +
7014 +// wrap cns3xxx_spi_tx_rx() for argument order
7015 +int cns3xxx_spi_tx_rx_n(u32 tx_data, u32 *rx_data, u32 tx_channel, u32 tx_eof_flag);
7016 +
7017 +// for bcm53115M
7018 +#define ROBO_SPIF_BIT 7
7019 +#define BCM53115_SPI_CHANNEL 1
7020 +#define ROBO_RACK_BIT 5
7021 +
7022 +#define VLAN_START_BIT 7
7023 +#define VLAN_WRITE_CMD 0
7024 +
7025 +//#define BCM_PORT_1G 2
7026 +typedef enum
7027 +{
7028 +   BCM_PORT_10M = 0,
7029 +   BCM_PORT_100M,
7030 +   BCM_PORT_1G,
7031 +}BCM_PORT_SPEED;
7032 +
7033 +#define BCM_PORT_0 0
7034 +#define BCM_PORT_1 1
7035 +#define BCM_PORT_2 2
7036 +#define BCM_PORT_3 3
7037 +#define BCM_PORT_4 4
7038 +#define BCM_PORT_5 5
7039 +#define BCM_PORT_IMP 6
7040 +
7041 +#endif // end #ifndef CNS3XXX_PHY_H
7042 --- /dev/null
7043 +++ b/drivers/net/cns3xxx/cns3xxx_sppe_hook.c
7044 @@ -0,0 +1,39 @@
7045 +/******************************************************************************
7046 + *
7047 + *  Copyright (c) 2008 Cavium Networks
7048 + *
7049 + *  This file is free software; you can redistribute it and/or modify
7050 + *  it under the terms of the GNU General Public License, Version 2, as
7051 + *  published by the Free Software Foundation.
7052 + *
7053 + *  This file is distributed in the hope that it will be useful,
7054 + *  but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
7055 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
7056 + *  NONINFRINGEMENT.  See the GNU General Public License for more details.
7057 + *
7058 + *  You should have received a copy of the GNU General Public License
7059 + *  along with this file; if not, write to the Free Software
7060 + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or
7061 + *  visit http://www.gnu.org/licenses/.
7062 + *
7063 + *  This file may also be available under a different license from Cavium.
7064 + *  Contact Cavium Networks for more information
7065 + *
7066 + ******************************************************************************/
7067 +
7068 +#if defined(CONFIG_CNS3XXX_SPPE)
7069 +#include <linux/module.h>
7070 +#include <linux/cns3xxx/sppe.h>
7071 +
7072 +int sppe_hook_ready = 0;
7073 +int (*sppe_func_hook)(SPPE_PARAM *param) = NULL;
7074 +int sppe_pci_fp_ready = 0;
7075 +int (*sppe_pci_fp_hook)(SPPE_PARAM *param) = NULL;
7076 +
7077 +EXPORT_SYMBOL(sppe_hook_ready);
7078 +EXPORT_SYMBOL(sppe_func_hook);
7079 +EXPORT_SYMBOL(sppe_pci_fp_ready);
7080 +EXPORT_SYMBOL(sppe_pci_fp_hook);
7081 +
7082 +#endif //#if defined(CONFIG_CNS3XXX_SPPE)
7083 +
7084 --- /dev/null
7085 +++ b/drivers/net/cns3xxx/cns3xxx_symbol.h
7086 @@ -0,0 +1,317 @@
7087 +/*******************************************************************************
7088 + *
7089 + *   Copyright (c) 2009 Cavium Networks 
7090 + *
7091 + *   This program is free software; you can redistribute it and/or modify it
7092 + *   under the terms of the GNU General Public License as published by the Free
7093 + *   Software Foundation; either version 2 of the License, or (at your option)
7094 + *   any later version.
7095 + *
7096 + *   This program is distributed in the hope that it will be useful, but WITHOUT
7097 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7098 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7099 + *   more details.
7100 + *
7101 + *   You should have received a copy of the GNU General Public License along with
7102 + *   this program; if not, write to the Free Software Foundation, Inc., 59
7103 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
7104 + *
7105 + *   The full GNU General Public License is included in this distribution in the
7106 + *   file called LICENSE.
7107 + *
7108 + ********************************************************************************/
7109 +
7110 +// the symbol define memory map register.
7111 +
7112 +#ifndef CNS3XXX_SYMBOL_H
7113 +#define CNS3XXX_SYMBOL_H
7114 +
7115 +#define DRV_VERSION "Cavium CNS3XXX Switch Driver-0.0.1"
7116 +
7117 +
7118 +#define LINUX_KERNEL // if don't define LINUX_KERNEL, mean u-boot
7119 +
7120 +#if defined(LINUX_KERNEL)
7121 +// linux kernel
7122 +#include <mach/board.h>
7123 +
7124 +#define SWITCH_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_SWITCH_BASE_VIRT+offset)))
7125 +#define PMU_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_PM_BASE_VIRT+offset)))
7126 +#define MISC_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_MISC_BASE_VIRT+offset)))
7127 +
7128 +
7129 +#define NETDEV_SIZE 4097+3
7130 +
7131 +#define PORT0_NETDEV_INDEX NETDEV_SIZE-3
7132 +#define PORT1_NETDEV_INDEX NETDEV_SIZE-2
7133 +#define PORT2_NETDEV_INDEX NETDEV_SIZE-1
7134 +
7135 +#if defined (CONFIG_CNS3XXX_SPPE)
7136 +#define FP_NETDEV_INDEX NETDEV_SIZE-4
7137 +#endif
7138 +
7139 +#define PORT0_NETDEV net_dev_array[PORT0_NETDEV_INDEX]
7140 +#define PORT1_NETDEV net_dev_array[PORT1_NETDEV_INDEX]
7141 +#define PORT2_NETDEV net_dev_array[PORT2_NETDEV_INDEX]
7142 +
7143 +#if defined (CONFIG_CNS3XXX_SPPE)
7144 +#define FP_NETDEV net_dev_array[FP_NETDEV_INDEX]
7145 +#endif
7146 +
7147 +#else // u-boot
7148 +#include <malloc.h> // for u8, u32
7149 +
7150 +#include "cns3000.h"
7151 +#define CAVM_OK 0
7152 +#define CAVM_ERR 1
7153 +#define CAVM_NOT_FOUND 2
7154 +#define CAVM_FOUND 3
7155 +#define CAVM_FAIL -1 // use minus 
7156 +
7157 +#define SWITCH_REG_VALUE(addr) (*((volatile unsigned int *)(CNS3000_VEGA_SWITCH_BASE+addr)))
7158 +#define PMU_REG_VALUE(addr) (*((volatile unsigned int *)(CNS3000_VEGA_PM_BASE+addr)))
7159 +#define MISC_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3000_VEGA_MISC_BASE+offset)))
7160 +
7161 +#endif
7162 +
7163 +// for VLAN and ARL table MB_PMAP
7164 +#define MAC_PORT0_PMAP 1
7165 +#define MAC_PORT1_PMAP (1 << 1)
7166 +#define MAC_PORT2_PMAP (1 << 4)
7167 +#define CPU_PORT_PMAP (1 << 2)
7168 +
7169 +
7170 +
7171 +// memory map register definition
7172 +
7173 +//#define PHY_CTRL_REG (*(u32 volatile*(0xff)))
7174 +#define PHY_CTRL_REG SWITCH_REG_VALUE(0x0)
7175 +#define PHY_AUTO_ADDR_REG SWITCH_REG_VALUE(0x04)
7176 +
7177 +#define MAC_GLOB_CFG_REG SWITCH_REG_VALUE(0x08)
7178 +#define MAC_GLOB_CFG_EXT_REG SWITCH_REG_VALUE(0xf4)
7179 +#define MAC0_CFG_REG SWITCH_REG_VALUE(0x0c)
7180 +#define MAC1_CFG_REG SWITCH_REG_VALUE(0x10)
7181 +#define MAC2_CFG_REG SWITCH_REG_VALUE(0x18)
7182 +#define CPU_CFG_REG SWITCH_REG_VALUE(0x14)
7183 +
7184 +#define MAC0_PRI_CTRL_REG SWITCH_REG_VALUE(0x1c)
7185 +#define MAC1_PRI_CTRL_REG SWITCH_REG_VALUE(0x20)
7186 +#define CPU_PRI_CTRL_REG SWITCH_REG_VALUE(0x24)
7187 +#define HNAT_PRI_CTRL_REG SWITCH_REG_VALUE(0x28)
7188 +#define MAC2_PRI_CTRL_REG SWITCH_REG_VALUE(0x2c)
7189 +
7190 +#define MAC0_PRI_CTRL_EXT_REG SWITCH_REG_VALUE(0x30)
7191 +
7192 +#define ETYPE1_ETYPE0_REG SWITCH_REG_VALUE(0x34)
7193 +#define ETYPE3_ETYPE2_REG SWITCH_REG_VALUE(0x38)
7194 +
7195 +#define UDP_RANGE0_REG SWITCH_REG_VALUE(0x3c)
7196 +#define UDP_RANGE1_REG SWITCH_REG_VALUE(0x40)
7197 +#define UDP_RANGE2_REG SWITCH_REG_VALUE(0x44)
7198 +#define UDP_RANGE3_REG SWITCH_REG_VALUE(0x48)
7199 +
7200 +
7201 +#define PRIO_ETYPE_UDP_REG SWITCH_REG_VALUE(0x4c)
7202 +
7203 +#define PRIO_IPDSCP_7_0_REG SWITCH_REG_VALUE(0x50)
7204 +#define PRIO_IPDSCP_15_8_REG SWITCH_REG_VALUE(0x54)
7205 +#define PRIO_IPDSCP_23_16_REG SWITCH_REG_VALUE(0x58)
7206 +#define PRIO_IPDSCP_31_24_REG SWITCH_REG_VALUE(0x5c)
7207 +#define PRIO_IPDSCP_39_32_REG SWITCH_REG_VALUE(0x60)
7208 +#define PRIO_IPDSCP_47_40_REG SWITCH_REG_VALUE(0x64)
7209 +#define PRIO_IPDSCP_55_48_REG SWITCH_REG_VALUE(0x68)
7210 +#define PRIO_IPDSCP_63_56_REG SWITCH_REG_VALUE(0x6c)
7211 +
7212 +#define TC_CTRL_REG SWITCH_REG_VALUE(0x70)
7213 +#define RATE_CTRL_REG SWITCH_REG_VALUE(0x74)
7214 +
7215 +#define FC_GLOB_THRS_REG SWITCH_REG_VALUE(0x78)
7216 +#define FC_PORT_THRS_REG SWITCH_REG_VALUE(0x7c)
7217 +#define MC_GLOB_THRS_REG SWITCH_REG_VALUE(0x80)
7218 +#define DC_GLOB_THRS_REG SWITCH_REG_VALUE(0x84)
7219 +
7220 +#define ARL_VLAN_CMD_REG SWITCH_REG_VALUE(0x88)
7221 +
7222 +#define ARL_CTRL0_REG SWITCH_REG_VALUE(0x8c)
7223 +#define ARL_CTRL1_REG SWITCH_REG_VALUE(0x90)
7224 +#define ARL_CTRL2_REG SWITCH_REG_VALUE(0x94)
7225 +
7226 +#define VLAN_CFG SWITCH_REG_VALUE(0x098)
7227 +
7228 +#define MAC1_MAC0_PVID_REG SWITCH_REG_VALUE(0x9c)
7229 +#define MAC2_CPU_PVID_REG SWITCH_REG_VALUE(0xa0)
7230 +
7231 +#define VLAN_CTRL0_REG SWITCH_REG_VALUE(0xa4)
7232 +#define VLAN_CTRL1_REG SWITCH_REG_VALUE(0xa8)
7233 +#define VLAN_CTRL2_REG SWITCH_REG_VALUE(0xac)
7234 +
7235 +#define SESSION_ID_1_0_REG SWITCH_REG_VALUE(0xb0)
7236 +#define SESSION_ID_3_2_REG SWITCH_REG_VALUE(0xb4)
7237 +#define SESSION_ID_5_4_REG SWITCH_REG_VALUE(0xb8)
7238 +#define SESSION_ID_7_6_REG SWITCH_REG_VALUE(0xbc)
7239 +#define SESSION_ID_9_8_REG SWITCH_REG_VALUE(0xc0)
7240 +#define SESSION_ID_11_10_REG SWITCH_REG_VALUE(0xc4)
7241 +#define SESSION_ID_13_12_REG SWITCH_REG_VALUE(0xc8)
7242 +#define SESSION_ID_15_14_REG SWITCH_REG_VALUE(0xcc)
7243 +
7244 +#define INTR_STAT_REG SWITCH_REG_VALUE(0xd0)
7245 +#define INTR_MASK_REG SWITCH_REG_VALUE(0xd4)
7246 +
7247 +#define SRAM_TEST_REG SWITCH_REG_VALUE(0xd8)
7248 +
7249 +#define MEM_QUEUE_REG SWITCH_REG_VALUE(0xdc)
7250 +
7251 +#define SARL_CTRL_REG SWITCH_REG_VALUE(0xe0)
7252 +#define SARL_OQ_GTH_REG SWITCH_REG_VALUE(0xe4)
7253 +#define SARL_OQ_YTH_REG SWITCH_REG_VALUE(0xe8)
7254 +#define SARL_OQ_RTH_REG SWITCH_REG_VALUE(0xec)
7255 +
7256 +#define SLK_SKEW_CTRL_REG SWITCH_REG_VALUE(0xf0)
7257 +
7258 +#define DMA_RING_CTRL_REG SWITCH_REG_VALUE(0x100)
7259 +
7260 +#define DMA_AUTO_POLL_CFG_REG SWITCH_REG_VALUE(0x104)
7261 +
7262 +#define DELAY_INTR_CFG_REG SWITCH_REG_VALUE(0x108)
7263 +
7264 +#define TS_DMA_CTRL0_REG SWITCH_REG_VALUE(0x110)
7265 +#define TS_DESC_PTR0_REG  SWITCH_REG_VALUE(0x114)
7266 +#define TS_DESC_BASE_ADDR0_REG SWITCH_REG_VALUE(0x118)
7267 +
7268 +#define FS_DMA_CTRL0_REG  SWITCH_REG_VALUE(0x120)
7269 +#define FS_DESC_PTR0_REG  SWITCH_REG_VALUE(0x124)
7270 +#define FS_DESC_BASE_ADDR0_REG SWITCH_REG_VALUE(0x128)
7271 +
7272 +#define TS_DMA_CTRL1_REG  SWITCH_REG_VALUE(0x130)
7273 +#define TS_DESC_PTR1_REG  SWITCH_REG_VALUE(0x134)
7274 +#define TS_DESC_BASE_ADDR1_REG SWITCH_REG_VALUE(0x138)
7275 +
7276 +#define FS_DMA_CTRL1_REG  SWITCH_REG_VALUE(0x140)
7277 +#define FS_DESC_PTR1_REG  SWITCH_REG_VALUE(0x144)
7278 +#define FS_DESC_BASE_ADDR1_REG SWITCH_REG_VALUE(0x148)
7279 +
7280 +#define TS_DMA_STA_REG  SWITCH_REG_VALUE(0x150)
7281 +#define FS_DMA_STA_REG  SWITCH_REG_VALUE(0x154)
7282 +
7283 +#define TS_MRD_CMD_CNT_REG  SWITCH_REG_VALUE(0x158)
7284 +#define TS_MWT_CMD_CNT_REG  SWITCH_REG_VALUE(0x15c)
7285 +
7286 +#define FS_MRD_CMD_CNT_REG  SWITCH_REG_VALUE(0x160)
7287 +#define FS_MWT_CMD_CNT_REG  SWITCH_REG_VALUE(0x164)
7288 +
7289 +#define C_RXOKPKT_MAC0_REG  SWITCH_REG_VALUE(0x300)
7290 +#define C_RXOKBYTE_MAC0_REG  SWITCH_REG_VALUE(0x304)
7291 +#define C_RXRUNT_MAC0_REG  SWITCH_REG_VALUE(0x308)
7292 +#define C_RXLONG_MAC0_REG  SWITCH_REG_VALUE(0x30c)
7293 +#define C_RXDROP_MAC0_REG  SWITCH_REG_VALUE(0x310)
7294 +#define C_RXCRC_MAC0_REG  SWITCH_REG_VALUE(0x314)
7295 +#define C_RXARLDROP_MAC0_REG  SWITCH_REG_VALUE(0x318)
7296 +#define C_VIDROP_MAC0_REG  SWITCH_REG_VALUE(0x31c)
7297 +#define C_VEDROP_MAC0_REG  SWITCH_REG_VALUE(0x320)
7298 +#define C_RXRL_MAC0_REG  SWITCH_REG_VALUE(0x324)
7299 +#define C_RXPAUSE_MAC0_REG  SWITCH_REG_VALUE(0x328)
7300 +
7301 +#define C_TXOKPKT_MAC0_REG  SWITCH_REG_VALUE(0x32c)
7302 +#define C_TXOKBYTE_MAC0_REG  SWITCH_REG_VALUE(0x330)
7303 +#define C_TXPAUSECOL_MAC0_REG  SWITCH_REG_VALUE(0x334)
7304 +
7305 +#define C_RXOKPKT_MAC1_REG  SWITCH_REG_VALUE(0x400)
7306 +#define C_RXOKBYTE_MAC1_REG  SWITCH_REG_VALUE(0x404)
7307 +#define C_RXRUNT_MAC1_REG  SWITCH_REG_VALUE(0x408)
7308 +#define C_RXLONG_MAC1_REG  SWITCH_REG_VALUE(0x40c)
7309 +#define C_RXDROP_MAC1_REG  SWITCH_REG_VALUE(0x410)
7310 +#define C_RXCRC_MAC1_REG  SWITCH_REG_VALUE(0x414)
7311 +#define C_RXARLDROP_MAC1_REG  SWITCH_REG_VALUE(0x418)
7312 +#define C_VIDROP_MAC1_REG  SWITCH_REG_VALUE(0x41c)
7313 +#define C_VEDROP_MAC1_REG  SWITCH_REG_VALUE(0x420)
7314 +#define C_RXRL_MAC1_REG  SWITCH_REG_VALUE(0x424)
7315 +#define C_RXPAUSE_MAC1_REG  SWITCH_REG_VALUE(0x428)
7316 +
7317 +#define C_TXOKPKT_MAC1_REG  SWITCH_REG_VALUE(0x42c)
7318 +#define C_TXOKBYTE_MAC1_REG  SWITCH_REG_VALUE(0x430)
7319 +#define C_TXPAUSECOL_MAC1_REG  SWITCH_REG_VALUE(0x434)
7320 +
7321 +#define C_TSOKPKT_CPU_REG  SWITCH_REG_VALUE(0x500)
7322 +#define C_TSOKBYTE_CPU_REG  SWITCH_REG_VALUE(0x504)
7323 +#define C_TSRUNT_CPU_REG  SWITCH_REG_VALUE(0x508)
7324 +#define C_TSLONG_CPU_REG  SWITCH_REG_VALUE(0x50c)
7325 +#define C_TSNODSTDROP_CPU_REG  SWITCH_REG_VALUE(0x510)
7326 +#define C_TSARLDROP_CPU_REG  SWITCH_REG_VALUE(0x514)
7327 +#define C_TSVIDROP_CPU_REG  SWITCH_REG_VALUE(0x518)
7328 +#define C_TSVEDROP_CPU_REG  SWITCH_REG_VALUE(0x51c)
7329 +#define C_TSRL_CPU_REG  SWITCH_REG_VALUE(0x520)
7330 +
7331 +#define C_FSOKPKT_CPU_REG  SWITCH_REG_VALUE(0x524)
7332 +#define C_FSOKBYTE_CPU_REG  SWITCH_REG_VALUE(0x528)
7333 +
7334 +#define C_RXOKPKT_MAC2_REG  SWITCH_REG_VALUE(0x600)
7335 +#define C_RXOKBYTE_MAC2_REG  SWITCH_REG_VALUE(0x604)
7336 +#define C_RXRUNT_MAC2_REG  SWITCH_REG_VALUE(0x608)
7337 +#define C_RXLONG_MAC2_REG  SWITCH_REG_VALUE(0x60c)
7338 +#define C_RXDROP_MAC2_REG  SWITCH_REG_VALUE(0x610)
7339 +#define C_RXCRC_MAC2_REG  SWITCH_REG_VALUE(0x614)
7340 +#define C_RXARLDROP_MAC2_REG  SWITCH_REG_VALUE(0x618)
7341 +#define C_VIDROP_MAC2_REG  SWITCH_REG_VALUE(0x61c)
7342 +#define C_VEDROP_MAC2_REG  SWITCH_REG_VALUE(0x620)
7343 +#define C_RXRL_MAC2_REG  SWITCH_REG_VALUE(0x624)
7344 +#define C_RXPAUSE_MAC2_REG  SWITCH_REG_VALUE(0x628)
7345 +
7346 +#define C_TXOKPKT_MAC2_REG  SWITCH_REG_VALUE(0x62c)
7347 +#define C_TXOKBYTE_MAC2_REG  SWITCH_REG_VALUE(0x630)
7348 +#define C_TXPAUSECOL_MAC2_REG  SWITCH_REG_VALUE(0x634)
7349 +
7350 +#define C_TXOKPKT_MAC0_EXT_REG  SWITCH_REG_VALUE(0x72c)
7351 +#define C_TXOKBYTE_MAC0_EXT_REG  SWITCH_REG_VALUE(0x730)
7352 +
7353 +#define CLK_GATE_REG PMU_REG_VALUE(0x0) 
7354 +#define SOFT_RST_REG PMU_REG_VALUE(0x4)
7355 +#define PLL_HM_PD_CTRL_REG PMU_REG_VALUE(0x1c)
7356 +
7357 +#define GPIOB_PIN_EN_REG MISC_REG_VALUE(0x18)
7358 +#define IOCDA_REG MISC_REG_VALUE(0x1c)
7359 +
7360 +#define LEVEL_HIGH 0
7361 +#define RISING_EDGE 1
7362 +
7363 +#ifdef CONFIG_SILICON
7364 +
7365 +#define STATUS_INTERRUPT_ID 49
7366 +
7367 +#define FSRC_RING0_INTERRUPT_ID 51
7368 +#define FSQF_RING0_INTERRUPT_ID 53
7369 +
7370 +#define FSRC_RING1_INTERRUPT_ID 55
7371 +#define FSQF_RING1_INTERRUPT_ID 57
7372 +
7373 +#define TSTC_RING0_INTERRUPT_ID 50
7374 +
7375 +#define TSTC_RING1_INTERRUPT_ID 54
7376 +
7377 +#define HNAT_INTERRUPT_ID 58
7378 +
7379 +#else
7380 +
7381 +//#define STATUS_INTERRUPT_ID 49
7382 +#define STATUS_INTERRUPT_ID 38
7383 +//#define FSRC_RING0_INTERRUPT_ID 51
7384 +#define FSRC_RING0_INTERRUPT_ID  40
7385 +
7386 +#define TSQE_RING0_INTERRUPT_ID 52
7387 +
7388 +//#define FSQF_RING0_INTERRUPT_ID 53
7389 +#define FSQF_RING0_INTERRUPT_ID 42
7390 +
7391 +#define FSQF_RING1_INTERRUPT_ID 46
7392 +#define FSRC_RING1_INTERRUPT_ID 44
7393 +
7394 +//#define FSRC_RING1_INTERRUPT_ID 55
7395 +
7396 +#define TSTC_RING0_INTERRUPT_ID 39
7397 +#define TSTC_RING1_INTERRUPT_ID 43
7398 +
7399 +#define TSQE_RING1_INTERRUPT_ID 56
7400 +#define HNAT_INTERRUPT_ID 58
7401 +#endif // #ifdef CONFIG_SILICON
7402 +
7403 +#endif
7404 --- /dev/null
7405 +++ b/drivers/net/cns3xxx/cns3xxx_tool.h
7406 @@ -0,0 +1,898 @@
7407 +/*******************************************************************************
7408 + *
7409 + *
7410 + *   Copyright (c) 2009 Cavium Networks 
7411 + *
7412 + *   This program is free software; you can redistribute it and/or modify it
7413 + *   under the terms of the GNU General Public License as published by the Free
7414 + *   Software Foundation; either version 2 of the License, or (at your option)
7415 + *   any later version.
7416 + *
7417 + *   This program is distributed in the hope that it will be useful, but WITHOUT
7418 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7419 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7420 + *   more details.
7421 + *
7422 + *   You should have received a copy of the GNU General Public License along with
7423 + *   this program; if not, write to the Free Software Foundation, Inc., 59
7424 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
7425 + *
7426 + *   The full GNU General Public License is included in this distribution in the
7427 + *   file called LICENSE.
7428 + *
7429 + ********************************************************************************/
7430 +
7431 +#ifndef CNS3XXX_TOOL_H
7432 +#define CNS3XXX_TOOL_H
7433 +
7434 +#define PRINT_INFO printk
7435 +
7436 +#if defined(__KERNEL__)
7437 +
7438 +#include "cns3xxx.h"
7439 +#include <linux/kernel.h> // for printk
7440 +
7441 +#else // u-boot
7442 +
7443 +#endif
7444 +
7445 +#define SHOW_DEBUG_MESSAGE
7446 +#ifdef SHOW_DEBUG_MESSAGE
7447 +
7448 +extern int MSG_LEVEL;
7449 +
7450 +#define NO_MSG 0
7451 +#define NORMAL_MSG 1
7452 +#define WARNING_MSG (1 << 1)
7453 +#define CRITICAL_MSG (1 << 2)
7454 +#define DUMP_RX_PKT_INFO (1 << 3)
7455 +#define DUMP_TX_PKT_INFO (1 << 4)
7456 +
7457 +#define DEBUG_MSG(msg_level, fmt, args...)\
7458 +{ \
7459 +        int i=0; \
7460 +\
7461 +        for(i=0 ; i < 3 ; ++i) { \
7462 +                if ((MSG_LEVEL & msg_level) >> i) \
7463 +                        printk(KERN_INFO "*cns3xxx gsw debug* " fmt, ## args); \
7464 +        } \
7465 +}
7466 +
7467 +#endif
7468 +
7469 +#define GET_MAC_PORT_CFG(port, cfg) \
7470 +{ \
7471 +       switch (port) \
7472 +       { \
7473 +               case MAC_PORT0: \
7474 +               { \
7475 +                       cfg = MAC0_CFG_REG; \
7476 +                       break; \
7477 +               } \
7478 +               case MAC_PORT1: \
7479 +               { \
7480 +                       cfg = MAC1_CFG_REG; \
7481 +                       break; \
7482 +               } \
7483 +               case MAC_PORT2: \
7484 +               { \
7485 +                       cfg = MAC2_CFG_REG; \
7486 +                       break; \
7487 +               } \
7488 +       } \
7489 +}
7490 +
7491 +#define SET_MAC_PORT_CFG(port, cfg) \
7492 +{ \
7493 +       switch (port) \
7494 +       { \
7495 +               case MAC_PORT0: \
7496 +               { \
7497 +                       MAC0_CFG_REG = cfg; \
7498 +                       break; \
7499 +               } \
7500 +               case MAC_PORT1: \
7501 +               { \
7502 +                       MAC1_CFG_REG = cfg; \
7503 +                       break; \
7504 +               } \
7505 +               case MAC_PORT2: \
7506 +               { \
7507 +                       MAC2_CFG_REG = cfg; \
7508 +                       break; \
7509 +               } \
7510 +       } \
7511 +}
7512 +
7513 +#define between(x, start, end) ((x)>=(start) && (x)<=(end))
7514 +static inline void print_packet(unsigned char *data, int len) 
7515 +{
7516 +    int i,j;
7517 +
7518 +    printk("packet length: %d%s:\n", len, len>128?"(only show the first 128 bytes)":"");
7519 +#if 0
7520 +    if(len > 128) {
7521 +        len = 128;
7522 +    }
7523 +#endif
7524 +    for(i=0;len;) {
7525 +        if(len >=16 ) {
7526 +            for(j=0;j<16;j++) {
7527 +                printk("%02x ", data[i++]);
7528 +            }
7529 +            printk("| ");
7530 +
7531 +            i -= 16;
7532 +            for(j=0;j<16;j++) {
7533 +                if( between(data[i], 0x21, 0x7e) ) {
7534 +                    printk("%c", data[i++]);
7535 +                }
7536 +                else {
7537 +                    printk(".");
7538 +                    i++;
7539 +                }
7540 +            }
7541 +            printk("\n");
7542 +
7543 +            len -= 16;
7544 +        }
7545 +        else {
7546 +            /* last line */
7547 +
7548 +            for(j=0; j<len; j++) {
7549 +                printk("%02x ", data[i++]);
7550 +            }
7551 +            for(;j<16;j++) {
7552 +                printk("   ");
7553 +            }
7554 +            printk("| ");
7555 +
7556 +            i -= len;
7557 +            for(j=0;j<len;j++) {
7558 +                if( between(data[i], 0x21, 0x7e) ) {
7559 +                    printk("%c", data[i++]);
7560 +                }
7561 +                else {
7562 +                    printk(".");
7563 +                    i++;
7564 +                }
7565 +            }
7566 +            for(;j<16;j++) {
7567 +                printk(" ");
7568 +            }
7569 +            printk("\n");
7570 +
7571 +            len = 0;
7572 +        }
7573 +    }
7574 +    return;
7575 +
7576 +}
7577 +
7578 +static inline void cns3xxx_gsw_power_enable(void)
7579 +{
7580 +        PLL_HM_PD_CTRL_REG &= (~(1 << 2)); // power up PLL_RGMII (for MAC)
7581 +        CLK_GATE_REG |= (1 << 11); // enable switch clock
7582 +}       
7583 +
7584 +static inline void cns3xxx_gsw_software_reset(void)
7585 +{
7586 +        SOFT_RST_REG &= (~(1 << 11));
7587 +        SOFT_RST_REG |= (1 << 11); 
7588 +}
7589 +
7590 +
7591 +
7592 +
7593 +// port:
7594 +// 0 : mac port0
7595 +// 1 : mac port1
7596 +// 2 : mac port2
7597 +// 3 : cpu port
7598 +static inline void enable_port(u8 port, u8 enable)
7599 +{
7600 +       switch (port)
7601 +       {
7602 +               case 0:
7603 +               {
7604 +                       (enable==1) ? (MAC0_CFG_REG &= (~(1 << 18)) ) : (MAC0_CFG_REG |= (1 << 18)) ;
7605 +
7606 +                       break;
7607 +               }
7608 +               case 1:
7609 +               {
7610 +                       (enable==1) ? (MAC1_CFG_REG &= (~(1 << 18)) ) : (MAC1_CFG_REG |= (1 << 18)) ;
7611 +                       break;
7612 +               }
7613 +               case 2:
7614 +               {
7615 +                       (enable==1) ? (MAC2_CFG_REG &= (~(1 << 18)) ) : (MAC2_CFG_REG |= (1 << 18)) ;
7616 +                       break;
7617 +               }
7618 +               case 3:
7619 +               {
7620 +                       (enable==1) ? (CPU_CFG_REG &= (~(1 << 18)) ) : (CPU_CFG_REG |= (1 << 18)) ;
7621 +                       break;
7622 +               }
7623 +       }
7624 +}
7625 +
7626 +static inline int cns3xxx_vlan_table_lookup(VLANTableEntry *entry)
7627 +{
7628 +       VLAN_CTRL2_REG |= entry->vid;
7629 +       ARL_VLAN_CMD_REG |= (1 << 8); // look up vlan table command
7630 +
7631 +       // wait for vlan command complete
7632 +       while(( (ARL_VLAN_CMD_REG >> 9) & 1) == 0) ;
7633 +       
7634 +       if (!((ARL_VLAN_CMD_REG >> 10) & 1)) {
7635 +               // not found any entry
7636 +               return CAVM_NOT_FOUND;
7637 +       }
7638 +
7639 +        entry->valid = ((VLAN_CTRL0_REG >> 31) & 0x1);
7640 +        entry->vid = ((VLAN_CTRL2_REG >> 31) & 0xfff);
7641 +        entry->wan_side = ((VLAN_CTRL0_REG >> 30) & 0x1);
7642 +        entry->etag_pmap = ((VLAN_CTRL0_REG >> 25) & 0x1f);
7643 +        entry->mb_pmap = ((VLAN_CTRL0_REG >> 9) & 0x1f);
7644 +
7645 +        entry->my_mac[0] = ((VLAN_CTRL1_REG >> 24) & 0xff);
7646 +        entry->my_mac[1] = ((VLAN_CTRL1_REG >> 16) & 0xff);
7647 +        entry->my_mac[2] = ((VLAN_CTRL1_REG >> 8) & 0xff);
7648 +        entry->my_mac[3] = (VLAN_CTRL1_REG & 0xff);
7649 +
7650 +        entry->my_mac[4] = ((VLAN_CTRL2_REG >> 24) & 0xff);
7651 +        entry->my_mac[5] = ((VLAN_CTRL2_REG >> 16) & 0xff);
7652 +
7653 +       return CAVM_FOUND;
7654 +}
7655 +
7656 +static inline int cns3xxx_vlan_table_read(VLANTableEntry *entry)
7657 +{
7658 +        //printf("VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7659 +       ARL_VLAN_CMD_REG &= (~0x3f);
7660 +       ARL_VLAN_CMD_REG |= (entry->vlan_index);
7661 +       ARL_VLAN_CMD_REG |= (1 << 7); // read vlan table command
7662 +        //printf("after read ARL_VLAN_CMD_REG: %x\n", ARL_VLAN_CMD_REG);
7663 +
7664 +       // wait for vlan command complete
7665 +       while(( (ARL_VLAN_CMD_REG >> 9) & 1) == 0) ;
7666 +
7667 +        //printf("ARL_VLAN_CMD_REG: %x\n", ARL_VLAN_CMD_REG);
7668 +        //printf("VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7669 +
7670 +        entry->valid = ((VLAN_CTRL0_REG >> 31) & 0x1);
7671 +        entry->vid = ((VLAN_CTRL2_REG) & 0xfff);
7672 +        entry->wan_side = ((VLAN_CTRL0_REG >> 30) & 0x1);
7673 +        entry->etag_pmap = ((VLAN_CTRL0_REG >> 25) & 0x1f);
7674 +        entry->mb_pmap = ((VLAN_CTRL0_REG >> 9) & 0x1f);
7675 +
7676 +        entry->my_mac[0] = ((VLAN_CTRL1_REG >> 24) & 0xff);
7677 +        entry->my_mac[1] = ((VLAN_CTRL1_REG >> 16) & 0xff);
7678 +        entry->my_mac[2] = ((VLAN_CTRL1_REG >> 8) & 0xff);
7679 +        entry->my_mac[3] = (VLAN_CTRL1_REG & 0xff);
7680 +
7681 +        entry->my_mac[4] = ((VLAN_CTRL2_REG >> 24) & 0xff);
7682 +        entry->my_mac[5] = ((VLAN_CTRL2_REG >> 16) & 0xff);
7683 +
7684 +       return CAVM_OK;
7685 +
7686 +}
7687 +
7688 +
7689 +// add a entry in the vlan table
7690 +static inline int cns3xxx_vlan_table_add(VLANTableEntry *entry)
7691 +{
7692 +       VLAN_CTRL0_REG = 0;
7693 +       VLAN_CTRL1_REG = 0;
7694 +       VLAN_CTRL2_REG = 0;
7695 +
7696 +#if 0
7697 +       printk("a [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7698 +       printk("a [kernel mode] VLAN_CTRL1_REG: %x\n", VLAN_CTRL1_REG);
7699 +       printk("a [kernel mode] VLAN_CTRL2_REG: %x\n", VLAN_CTRL2_REG);
7700 +#endif
7701 +
7702 +       //printk("vlan_index: %x\n", entry->vlan_index);
7703 +       VLAN_CTRL0_REG |= (entry->valid << 31);
7704 +       //DEBUG_MSG(NORMAL_MSG, "1 [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7705 +       VLAN_CTRL0_REG |= (entry->wan_side << 30);
7706 +       //DEBUG_MSG(NORMAL_MSG, "2 [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7707 +       //printk("entry->etag_pmap: %x\n", entry->etag_pmap);
7708 +       VLAN_CTRL0_REG |= (entry->etag_pmap << 25);
7709 +       //DEBUG_MSG(NORMAL_MSG, "3 [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7710 +       //printk("entry->mb_pmap: %x\n", entry->mb_pmap);
7711 +       VLAN_CTRL0_REG |= (entry->mb_pmap << 9);
7712 +       //DEBUG_MSG(NORMAL_MSG, "4 [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7713 +       //printk("bb [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7714 +
7715 +        //printf("vlan index: %d ## add VLAN_CTRL0_REG: %x\n", entry->vlan_index, VLAN_CTRL0_REG);
7716 +
7717 +
7718 +       VLAN_CTRL1_REG |= (entry->my_mac[0] << 24);
7719 +       VLAN_CTRL1_REG |= (entry->my_mac[1] << 16);
7720 +       VLAN_CTRL1_REG |= (entry->my_mac[2] << 8);
7721 +       VLAN_CTRL1_REG |= (entry->my_mac[3]);
7722 +
7723 +       VLAN_CTRL2_REG |= (entry->my_mac[4] << 24);
7724 +       VLAN_CTRL2_REG |= (entry->my_mac[5] << 16);
7725 +       VLAN_CTRL2_REG |= entry->vid;
7726 +
7727 +#if 0
7728 +       printk("b [kernel mode] VLAN_CTRL0_REG: %x\n", VLAN_CTRL0_REG);
7729 +       printk("b [kernel mode] VLAN_CTRL1_REG: %x\n", VLAN_CTRL1_REG);
7730 +       printk("b [kernel mode] VLAN_CTRL2_REG: %x\n", VLAN_CTRL2_REG);
7731 +#endif
7732 +
7733 +       ARL_VLAN_CMD_REG &= (~0x3f);
7734 +       ARL_VLAN_CMD_REG |= (entry->vlan_index);
7735 +       ARL_VLAN_CMD_REG |= (1 << 6); // write vlan table command
7736 +
7737 +
7738 +        //printf("after write ARL_VLAN_CMD_REG: %x\n", ARL_VLAN_CMD_REG);
7739 +
7740 +       // wait for vlan command complete
7741 +       while(( (ARL_VLAN_CMD_REG >> 9) & 1) == 0) ;
7742 +
7743 +       return CAVM_OK;
7744 +}
7745 +
7746 +static inline void print_arl_table_entry(ARLTableEntry *entry)
7747 +{
7748 +        printk("vid: %d\n", entry->vid);
7749 +        printk("pmap: %#x\n", entry->pmap);
7750 +        printk("age_field: %d\n", entry->age_field);
7751 +        printk("vlan_mac: %d\n", entry->vlan_mac);
7752 +        printk("filter: %d\n", entry->filter);
7753 +        printk("mac addr: %x:%x:%x:%x:%x:%x\n", entry->mac[0], entry->mac[1],entry->mac[2],entry->mac[3],entry->mac[4],entry->mac[5]);
7754 +
7755 +}
7756 +
7757 +
7758 +static inline int cns3xxx_arl_table_lookup(ARLTableEntry *entry)
7759 +{
7760 +       ARL_CTRL0_REG = 0;
7761 +       ARL_CTRL1_REG = 0;
7762 +       ARL_CTRL2_REG = 0;
7763 +
7764 +       ARL_CTRL0_REG |= (entry->vid << 16);
7765 +
7766 +       ARL_CTRL1_REG |= (entry->mac[0] << 24);
7767 +       ARL_CTRL1_REG |= (entry->mac[1] << 16);
7768 +       ARL_CTRL1_REG |= (entry->mac[2] << 8);
7769 +       ARL_CTRL1_REG |= entry->mac[3];
7770 +
7771 +       ARL_CTRL2_REG |= (entry->mac[4] << 24);
7772 +       ARL_CTRL2_REG |= (entry->mac[5] << 16);
7773 +
7774 +       ARL_VLAN_CMD_REG |= (1 << 18); // arl table lookup command
7775 +
7776 +       // wait arl command complete
7777 +       while(( (ARL_VLAN_CMD_REG >> 21) & 1) == 0);
7778 +
7779 +       if (( (ARL_VLAN_CMD_REG >> 23) & 1)) {
7780 +               // found
7781 +
7782 +               entry->vid = ((ARL_CTRL0_REG >> 16) & 0xfff);
7783 +               entry->pmap = ((ARL_CTRL0_REG >> 9) & 0x1f);
7784 +
7785 +               entry->age_field = ((ARL_CTRL2_REG >> 4 ) & 0x7);
7786 +               entry->vlan_mac = ((ARL_CTRL2_REG >> 1 ) & 0x1);
7787 +               entry->filter = (ARL_CTRL2_REG & 0x1);
7788 +       } else {
7789 +               // not found
7790 +               return CAVM_NOT_FOUND;
7791 +       }
7792 +#if 0
7793 +       printk("[kernel mode] ARL_VLAN_CMD_REG : %#x\n", ARL_VLAN_CMD_REG);
7794 +       printk("[kernel mode] ARL_CTRL0_REG : %#x\n", ARL_CTRL0_REG);
7795 +       printk("[kernel mode] ARL_CTRL1_REG : %#x\n", ARL_CTRL1_REG);
7796 +       printk("[kernel mode] ARL_CTRL2_REG : %#x\n", ARL_CTRL2_REG);
7797 +#endif
7798 +
7799 +       return CAVM_FOUND;
7800 +}
7801 +
7802 +static inline int cns3xxx_arl_table_search_again(ARLTableEntry *entry)
7803 +{
7804 +       ARL_CTRL0_REG = 0;
7805 +       ARL_CTRL1_REG = 0;
7806 +       ARL_CTRL2_REG = 0;
7807 +
7808 +       ARL_VLAN_CMD_REG |= (1 << 17); // arl table search again command
7809 +
7810 +       // wait arl command complete
7811 +       while(( (ARL_VLAN_CMD_REG >> 21) & 1) == 0);
7812 +
7813 +       if ((ARL_VLAN_CMD_REG >> 23) & 1) {
7814 +
7815 +               // found
7816 +       #if 0
7817 +       printk("[kernel mode] ARL_VLAN_CMD_REG : %#x\n", ARL_VLAN_CMD_REG);
7818 +       printk("[kernel mode] ARL_CTRL0_REG : %#x\n", ARL_CTRL0_REG);
7819 +       printk("[kernel mode] ARL_CTRL1_REG : %#x\n", ARL_CTRL1_REG);
7820 +       printk("[kernel mode] ARL_CTRL2_REG : %#x\n", ARL_CTRL2_REG);
7821 +       #endif
7822 +               entry->vid = ((ARL_CTRL0_REG >> 16) & 0xfff);
7823 +               entry->pmap = ((ARL_CTRL0_REG >> 9) & 0x1f);
7824 +
7825 +               entry->age_field = ((ARL_CTRL2_REG >> 4 ) & 0x7);
7826 +               entry->vlan_mac = ((ARL_CTRL2_REG >> 1 ) & 0x1);
7827 +               entry->filter = (ARL_CTRL2_REG & 0x1);
7828 +
7829 +               entry->mac[0] = (ARL_CTRL1_REG >> 24);
7830 +               entry->mac[1] = (ARL_CTRL1_REG >> 16);
7831 +               entry->mac[2] = (ARL_CTRL1_REG >> 8);
7832 +               entry->mac[3] = ARL_CTRL1_REG;
7833 +
7834 +               entry->mac[4] = (ARL_CTRL2_REG >> 24);
7835 +               entry->mac[5] = (ARL_CTRL2_REG >> 16);
7836 +
7837 +               return CAVM_FOUND;
7838 +       } else {
7839 +               // not found
7840 +               return CAVM_NOT_FOUND;
7841 +       }
7842 +}
7843 +
7844 +static inline int cns3xxx_is_arl_table_end(void)
7845 +{
7846 +       ARL_CTRL0_REG = 0;
7847 +       ARL_CTRL1_REG = 0;
7848 +       ARL_CTRL2_REG = 0;
7849 +
7850 +       if (( (ARL_VLAN_CMD_REG >> 22) & 1)) { // search to table end
7851 +               return CAVM_OK;
7852 +       } else {
7853 +               return CAVM_ERR;
7854 +       }
7855 +}
7856 +
7857 +static inline int cns3xxx_arl_table_search(ARLTableEntry *entry)
7858 +{
7859 +       ARL_CTRL0_REG = 0;
7860 +       ARL_CTRL1_REG = 0;
7861 +       ARL_CTRL2_REG = 0;
7862 +
7863 +#if 0
7864 +       ARL_CTRL0_REG |= (entry->vid << 16);
7865 +
7866 +       ARL_CTRL1_REG |= (entry->mac[0] << 24);
7867 +       ARL_CTRL1_REG |= (entry->mac[1] << 16);
7868 +       ARL_CTRL1_REG |= (entry->mac[2] << 8);
7869 +       ARL_CTRL1_REG |= entry->mac[3];
7870 +
7871 +       ARL_CTRL2_REG |= (entry->mac[4] << 24);
7872 +       ARL_CTRL2_REG |= (entry->mac[5] << 16);
7873 +#endif
7874 +       ARL_VLAN_CMD_REG |= (1 << 16); // arl table search start command
7875 +
7876 +       // wait arl command complete
7877 +       while(( (ARL_VLAN_CMD_REG >> 21) & 1) == 0);
7878 +
7879 +       if (((ARL_VLAN_CMD_REG >> 23) & 1)) {
7880 +               // found
7881 +       #if 0
7882 +       printk("[kernel mode] ARL_VLAN_CMD_REG : %#x\n", ARL_VLAN_CMD_REG);
7883 +       printk("[kernel mode] ARL_CTRL0_REG : %#x\n", ARL_CTRL0_REG);
7884 +       printk("[kernel mode] ARL_CTRL1_REG : %#x\n", ARL_CTRL1_REG);
7885 +       printk("[kernel mode] ARL_CTRL2_REG : %#x\n", ARL_CTRL2_REG);
7886 +       #endif
7887 +               entry->vid = ((ARL_CTRL0_REG >> 16) & 0xfff);
7888 +               entry->pmap = ((ARL_CTRL0_REG >> 9) & 0x1f);
7889 +
7890 +               entry->age_field = ((ARL_CTRL2_REG >> 4 ) & 0x7);
7891 +               entry->vlan_mac = ((ARL_CTRL2_REG >> 1 ) & 0x1);
7892 +               entry->filter = (ARL_CTRL2_REG & 0x1);
7893 +
7894 +               entry->mac[0] = (ARL_CTRL1_REG >> 24);
7895 +               entry->mac[1] = (ARL_CTRL1_REG >> 16);
7896 +               entry->mac[2] = (ARL_CTRL1_REG >> 8);
7897 +               entry->mac[3] = ARL_CTRL1_REG;
7898 +
7899 +               entry->mac[4] = (ARL_CTRL2_REG >> 24);
7900 +               entry->mac[5] = (ARL_CTRL2_REG >> 16);
7901 +
7902 +               return CAVM_FOUND;
7903 +       } else {
7904 +               // not found
7905 +               return CAVM_NOT_FOUND;
7906 +       }
7907 +}
7908 +
7909 +
7910 +// flush all age out entries except static entries
7911 +static inline int cns3xxx_arl_table_flush(void)
7912 +{
7913 +       ARL_VLAN_CMD_REG |= (1 << 20); // flush arl table command
7914 +
7915 +       // wait arl command complete
7916 +       while(( (ARL_VLAN_CMD_REG >> 21) & 1) == 0);
7917 +
7918 +
7919 +       return CAVM_OK;
7920 +}
7921 +
7922 +
7923 +// add a entry in the arl table
7924 +static inline int cns3xxx_arl_table_add(ARLTableEntry *entry)
7925 +{
7926 +       ARL_CTRL0_REG = 0;
7927 +       ARL_CTRL1_REG = 0;
7928 +       ARL_CTRL2_REG = 0;
7929 +
7930 +       entry->age_field = 7; // static entry
7931 +       ARL_CTRL0_REG |= (entry->vid << 16);
7932 +       ARL_CTRL0_REG |= (entry->pmap << 9);
7933 +
7934 +       ARL_CTRL1_REG |= (entry->mac[0] << 24);
7935 +       ARL_CTRL1_REG |= (entry->mac[1] << 16);
7936 +       ARL_CTRL1_REG |= (entry->mac[2] << 8);
7937 +       ARL_CTRL1_REG |= entry->mac[3];
7938 +
7939 +       ARL_CTRL2_REG |= (entry->mac[4] << 24);
7940 +       ARL_CTRL2_REG |= (entry->mac[5] << 16);
7941 +
7942 +       ARL_CTRL2_REG |= (entry->age_field << 4);
7943 +       ARL_CTRL2_REG |= (entry->vlan_mac << 1);
7944 +       ARL_CTRL2_REG |= (entry->filter);
7945 +
7946 +       //printk("entry->age_field: %d\n", entry->age_field);
7947 +       //printk("ARL_CTRL2_REG: %x\n", ARL_CTRL2_REG);
7948 +
7949 +       ARL_VLAN_CMD_REG |= (1 << 19); // arl table write command
7950 +
7951 +       // wait arl command complete
7952 +       while(( (ARL_VLAN_CMD_REG >> 21) & 1) == 0);
7953 +
7954 +       return CAVM_OK;
7955 +}
7956 +
7957 +// invalid a entry in the arl table
7958 +static inline int cns3xxx_arl_table_invalid(ARLTableEntry *entry)
7959 +{
7960 +       entry->age_field = 0; // invalid
7961 +       return cns3xxx_arl_table_add(entry);
7962 +}
7963 +
7964 +// port:
7965 +// 0 : mac port0
7966 +// 1 : mac port1
7967 +// 2 : mac port2
7968 +// 3 : cpu port
7969 +static inline void cns3xxx_set_pvid(u8 port, u16 pvid)
7970 +{
7971 +       switch (port)
7972 +       {
7973 +               case 0:
7974 +               {
7975 +                       MAC1_MAC0_PVID_REG &= (~0x0fff);
7976 +                       MAC1_MAC0_PVID_REG |= pvid;
7977 +                       break;
7978 +               }
7979 +               case 1:
7980 +               {
7981 +                       MAC1_MAC0_PVID_REG &= (~(0x0fff << 16));
7982 +                       MAC1_MAC0_PVID_REG |= (pvid << 16);
7983 +                       break;
7984 +               }
7985 +               case 2:
7986 +               {
7987 +                       MAC2_CPU_PVID_REG &= (~(0x0fff << 16));
7988 +                       MAC2_CPU_PVID_REG |= (pvid << 16);
7989 +                       break;
7990 +               }
7991 +               case 3: // cpu port
7992 +               {
7993 +                       MAC2_CPU_PVID_REG &= (~0x0fff);
7994 +                       MAC2_CPU_PVID_REG |= pvid;
7995 +                       break;
7996 +               }
7997 +       }
7998 +
7999 +
8000 +}
8001 +
8002 +static inline u16 cns3xxx_get_pvid(u8 port)
8003 +{
8004 +                       // 0,     1,   2,    cpu port
8005 +       u16 port_offset[]={0x9c, 0x9c, 0xa0, 0xa0};
8006 +                     // 0, 1,   2,  cpu port
8007 +       u16 port_shift[]={0, 16, 16, 0};
8008 +
8009 +       return ((SWITCH_REG_VALUE(port_offset[port]) >> port_shift[port]) & 0xfff);
8010 +}
8011 +
8012 +// which : 0 or 1
8013 +// enable: 0 or 1
8014 +static inline int enable_rx_dma(u8 which, u8 enable)
8015 +{
8016 +       if (which == 0 ) {
8017 +               FS_DMA_CTRL0_REG = enable;
8018 +       } else if (which == 1 ) {
8019 +               FS_DMA_CTRL1_REG = enable;
8020 +       } else {
8021 +               return CAVM_ERR;
8022 +       }
8023 +       return CAVM_OK;
8024 +}
8025 +
8026 +
8027 +// which : 0 or 1
8028 +// enable: 0 or 1
8029 +static inline int enable_tx_dma(u8 which, u8 enable)
8030 +{
8031 +       if (which == 0 ) {
8032 +               TS_DMA_CTRL0_REG = enable;
8033 +       } else if (which == 1 ) {
8034 +               TS_DMA_CTRL1_REG = enable;
8035 +       } else {
8036 +               return CAVM_ERR;
8037 +       }
8038 +       return CAVM_OK;
8039 +}
8040 +
8041 +#define DUMP_TX_DESC_PROC(tx_desc, page, num) \
8042 +{ \
8043 +       num += sprintf(page + num,"sdp: %x\n", tx_desc->sdp); \
8044 +       num += sprintf(page + num,"sdl: %d\n", tx_desc->sdl); \
8045 +       num += sprintf(page + num,"tco: %d\n", tx_desc->tco); \
8046 +       num += sprintf(page + num,"uco: %d\n", tx_desc->uco); \
8047 +       num += sprintf(page + num,"ico: %d\n", tx_desc->ico); \
8048 +       num += sprintf(page + num,"pri: %d\n", tx_desc->pri); \
8049 +       num += sprintf(page + num,"fp: %d\n", tx_desc->fp); \
8050 +       num += sprintf(page + num,"fr: %d\n", tx_desc->fr); \
8051 +       num += sprintf(page + num,"interrupt: %d\n", tx_desc->interrupt); \
8052 +       num += sprintf(page + num,"lsd: %d\n", tx_desc->lsd); \
8053 +       num += sprintf(page + num,"fsd: %d\n", tx_desc->fsd); \
8054 +       num += sprintf(page + num,"eor: %d\n", tx_desc->eor); \
8055 +       num += sprintf(page + num,"cown: %d\n", tx_desc->cown); \
8056 + \
8057 +       num += sprintf(page + num,"ctv: %d\n", tx_desc->ctv); \
8058 +       num += sprintf(page + num,"stv: %d\n", tx_desc->stv); \
8059 +       num += sprintf(page + num,"sid: %d\n", tx_desc->sid); \
8060 +       num += sprintf(page + num,"inss: %d\n", tx_desc->inss); \
8061 +       num += sprintf(page + num,"dels: %d\n", tx_desc->dels); \
8062 +       num += sprintf(page + num,"pmap: %d\n", tx_desc->pmap); \
8063 +       num += sprintf(page + num,"mark: %d\n", tx_desc->mark); \
8064 +       num += sprintf(page + num,"ewan: %d\n", tx_desc->ewan); \
8065 +       num += sprintf(page + num,"fewan: %d\n", tx_desc->fewan); \
8066 + \
8067 +       num += sprintf(page + num,"c_vid: %d\n", tx_desc->c_vid); \
8068 +       num += sprintf(page + num,"c_cfs: %d\n", tx_desc->c_cfs); \
8069 +       num += sprintf(page + num,"c_pri: %d\n", tx_desc->c_pri); \
8070 +       num += sprintf(page + num,"s_vid: %d\n", tx_desc->s_vid); \
8071 +       num += sprintf(page + num,"s_dei: %d\n", tx_desc->s_dei); \
8072 +       num += sprintf(page + num,"s_pri: %d\n", tx_desc->s_pri); \
8073 +}
8074 +
8075 +static inline void dump_tx_desc(TXDesc volatile *tx_desc)
8076 +{
8077 +       printk("sdp: %x\n", tx_desc->sdp);
8078 +       printk("sdl: %d\n", tx_desc->sdl);
8079 +       printk("tco: %d\n", tx_desc->tco);
8080 +       printk("uco: %d\n", tx_desc->uco);
8081 +       printk("ico: %d\n", tx_desc->ico);
8082 +       printk("pri: %d\n", tx_desc->pri);
8083 +       printk("fp: %d\n", tx_desc->fp);
8084 +       printk("fr: %d\n", tx_desc->fr);
8085 +       printk("interrupt: %d\n", tx_desc->interrupt);
8086 +       printk("lsd: %d\n", tx_desc->lsd);
8087 +       printk("fsd: %d\n", tx_desc->fsd);
8088 +       printk("eor: %d\n", tx_desc->eor);
8089 +       printk("cown: %d\n", tx_desc->cown);
8090 +
8091 +       printk("ctv: %d\n", tx_desc->ctv);
8092 +       printk("stv: %d\n", tx_desc->stv);
8093 +       printk("sid: %d\n", tx_desc->sid);
8094 +       printk("inss: %d\n", tx_desc->inss);
8095 +       printk("dels: %d\n", tx_desc->dels);
8096 +       printk("pmap: %d\n", tx_desc->pmap);
8097 +       printk("mark: %d\n", tx_desc->mark);
8098 +       printk("ewan: %d\n", tx_desc->ewan);
8099 +       printk("fewan: %d\n", tx_desc->fewan);
8100 +
8101 +       printk("c_vid: %d\n", tx_desc->c_vid);
8102 +       printk("c_cfs: %d\n", tx_desc->c_cfs);
8103 +       printk("c_pri: %d\n", tx_desc->c_pri);
8104 +       printk("s_vid: %d\n", tx_desc->s_vid);
8105 +       printk("s_dei: %d\n", tx_desc->s_dei);
8106 +       printk("s_pri: %d\n", tx_desc->s_pri);
8107 +}
8108 +
8109 +static inline void dump_rx_desc(RXDesc volatile *rx_desc)
8110 +{
8111 +
8112 +       printk("rx_desc: %p\n", rx_desc);
8113 +       //printk("rx_desc: %p ## cown: %d\n", rx_desc, rx_desc->cown);
8114 +       //printk("rx_desc phy addr : %x\n", (u32)page_to_dma(NULL, rx_desc) );
8115 +#if 0
8116 +       int i=0;
8117 +       for (i=0; i < 8 ; ++4) {
8118 +               u32 rx_desc_data = *((u32 *)(rx_desc+i));
8119 +               printk("%d: %#x\n", i, rx_desc_data);
8120 +       }
8121 +#endif
8122 +
8123 +       printk("sdp: %x\n", rx_desc->sdp);
8124 +
8125 +       printk("sdl: %d\n", rx_desc->sdl);
8126 +#if 1
8127 +       printk("l4f: %d\n", rx_desc->l4f);
8128 +       printk("ipf: %d\n", rx_desc->ipf);
8129 +       printk("prot: %d\n", rx_desc->prot);
8130 +       printk("hr: %d\n", rx_desc->hr);
8131 +       printk("lsd: %d\n", rx_desc->lsd);
8132 +       printk("fsd: %d\n", rx_desc->fsd);
8133 +       printk("eor: %d\n", rx_desc->eor);
8134 +#endif
8135 +       printk("cown: %d\n", rx_desc->cown);
8136 +
8137 +#if 1
8138 +       printk("ctv: %d\n", rx_desc->ctv);
8139 +       printk("stv: %d\n", rx_desc->stv);
8140 +       printk("unv: %d\n", rx_desc->unv);
8141 +       printk("iwan: %d\n", rx_desc->iwan);
8142 +       printk("exdv: %d\n", rx_desc->exdv);
8143 +       printk("sp: %d\n", rx_desc->sp);
8144 +       printk("crc_err: %d\n", rx_desc->crc_err);
8145 +       printk("un_eth: %d\n", rx_desc->un_eth);
8146 +       printk("tc: %d\n", rx_desc->tc);
8147 +       printk("ip_offset: %d\n", rx_desc->ip_offset);
8148 +
8149 +       printk("c_vid: %d\n", rx_desc->c_vid);
8150 +       printk("c_cfs: %d\n", rx_desc->c_cfs);
8151 +       printk("c_pri: %d\n", rx_desc->c_pri);
8152 +       printk("s_vid: %d\n", rx_desc->s_vid);
8153 +       printk("s_dei: %d\n", rx_desc->s_dei);
8154 +       printk("s_pri: %d\n", rx_desc->s_pri);
8155 +#endif
8156 +}
8157 +
8158 +static inline void dump_all_rx_ring(const RXRing *rx_ring, u8 r_index)
8159 +{
8160 +       int i=0;
8161 +
8162 +       RXBuffer volatile *rx_buf = get_rx_ring_head(rx_ring);
8163 +
8164 +       printk("all rx ring: %d\n", r_index);
8165 +       for (i=0 ; i < get_rx_ring_size(rx_ring) ; ++i) {
8166 +               printk("%d ## rx_buf: %p ##  rx_buf->rx_desc: %p\n", i, rx_buf, rx_buf->rx_desc);
8167 +               dump_rx_desc(rx_buf->rx_desc);
8168 +               ++rx_buf;
8169 +       }
8170 +}
8171 +
8172 +static inline void rx_dma_suspend(u8 enable)
8173 +{
8174 +#if 1
8175 +       DMA_AUTO_POLL_CFG_REG &= (~0x00000001);
8176 +       if (enable == 1)
8177 +               DMA_AUTO_POLL_CFG_REG |= 1;
8178 +#endif
8179 +}
8180 +
8181 +
8182 +// clear: 0 normal
8183 +// clear: 1 clear
8184 +static inline void clear_fs_dma_state(u8 clear)
8185 +{
8186 +       DMA_RING_CTRL_REG &= (~(1 << 31));
8187 +       if (clear==1) {
8188 +               DMA_RING_CTRL_REG |= (1 << 31);
8189 +       }
8190 +}
8191 +
8192 +// enable: 1 -> IVL
8193 +// enable: 0 -> SVL
8194 +static inline void cns3xxx_ivl(u8 enable)
8195 +{
8196 +       // SVL
8197 +       MAC_GLOB_CFG_REG &= (~(0x1 << 7));
8198 +       if (enable == 1)
8199 +               MAC_GLOB_CFG_REG |= (0x1 << 7);
8200 +}
8201 +
8202 +static inline void cns3xxx_nic_mode(u8 enable)
8203 +{
8204 +       VLAN_CFG &= (~(1<<15));
8205 +       if (enable == 1) 
8206 +               VLAN_CFG |= (1<<15);
8207 +}
8208 +
8209 +
8210 +void gic_mask_irq(unsigned int irq);
8211 +void gic_unmask_irq(unsigned int irq);
8212 +extern void __iomem *gic_cpu_base_addr;
8213 +
8214 +
8215 +static inline void cns3xxx_disable_irq(u32 irq)
8216 +{
8217 +#ifdef CONFIG_SMP
8218 +       disable_irq_nosync(irq);
8219 +#else
8220 +       disable_irq(irq);
8221 +#endif
8222 +       //gic_mask_irq(irq);
8223 +}
8224 +
8225 +static inline void cns3xxx_enable_irq(u32 irq)
8226 +{
8227 +       enable_irq(irq);
8228 +       //gic_unmask_irq(irq);
8229 +}
8230 +
8231 +static inline int cns3xxx_get_tx_hw_index(u8 ring_index)
8232 +{
8233 +       if (ring_index == 0) {
8234 +               return (TS_DESC_PTR0_REG - TS_DESC_BASE_ADDR0_REG) / sizeof (TXDesc);
8235 +       } else if (ring_index == 1) {
8236 +               return (TS_DESC_PTR1_REG - TS_DESC_BASE_ADDR1_REG) / sizeof (TXDesc);
8237 +       } else {
8238 +               return CAVM_ERR;
8239 +       }
8240 +}
8241 +
8242 +static inline TXBuffer* get_tx_buffer_by_index(TXRing *tx_ring, int i)
8243 +{ 
8244 +       int index = i;  
8245 +
8246 +       index = ((index + get_tx_ring_size(tx_ring) )% get_tx_ring_size(tx_ring)); 
8247 +
8248 +       return tx_ring->head + index;
8249 +}
8250 +
8251 +static inline int cns3xxx_is_untag_packet(const RXDesc *rx_desc)
8252 +{
8253 +       return rx_desc->crc_err;
8254 +}
8255 +
8256 +
8257 +#ifdef CONFIG_SWITCH_BIG_ENDIAN
8258 +static inline void swap_rx_desc(RXDesc *org_desc, RXDesc *new_desc)
8259 +{
8260 +         int i=0;
8261 +         void *org_p = org_desc;
8262 +         void *new_p = new_desc;
8263 +
8264 +        for (i=0; i < 16 ; i+=4) { 
8265 +                u32 rx_desc_data = 0; 
8266 +                u32 swab_rx_desc_data = 0;
8267 +
8268 +                rx_desc_data = *((volatile u32 *)(org_p+i));
8269 +                swab_rx_desc_data = ___swab32(rx_desc_data);
8270 +
8271 +                *((volatile u32 *)(new_p+i)) = swab_rx_desc_data;
8272 +        }
8273 +}
8274 +
8275 +static inline void swap_tx_desc(TXDesc *org_desc, TXDesc *new_desc)
8276 +{
8277 +        int i=0;
8278 +        void *org_p = org_desc;
8279 +        void *new_p = new_desc;
8280 +
8281 +        for (i=0; i < 16 ; i+=4) {
8282 +                u32 desc_data = *((volatile u32 *)(org_p+i));
8283 +                u32 swab_desc_data = ___swab32(desc_data);
8284 +
8285 +                *((volatile u32 *)(new_p+i)) = swab_desc_data;
8286 +        }
8287 +}
8288 +
8289 +#endif
8290 +
8291 +
8292 +static inline int cns3xxx_min_mtu(void)
8293 +{
8294 +       return 64;
8295 +}
8296 +
8297 +static inline int cns3xxx_max_mtu(void)
8298 +{
8299 +       int max_len[]={1518, 1522, 1536, 9600};
8300 +
8301 +        return max_len[((PHY_AUTO_ADDR_REG >> 30) & 0x3)];
8302 +}
8303 +
8304 +#endif // CNS3XXX_TOOL_H
8305 --- /dev/null
8306 +++ b/drivers/net/cns3xxx/fpga.h
8307 @@ -0,0 +1,306 @@
8308 +/*******************************************************************************
8309 + *
8310 + *   Copyright (c) 2009 Cavium Networks 
8311 + *
8312 + *   This program is free software; you can redistribute it and/or modify it
8313 + *   under the terms of the GNU General Public License as published by the Free
8314 + *   Software Foundation; either version 2 of the License, or (at your option)
8315 + *   any later version.
8316 + *
8317 + *   This program is distributed in the hope that it will be useful, but WITHOUT
8318 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8319 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
8320 + *   more details.
8321 + *
8322 + *   You should have received a copy of the GNU General Public License along with
8323 + *   this program; if not, write to the Free Software Foundation, Inc., 59
8324 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
8325 + *
8326 + *   The full GNU General Public License is included in this distribution in the
8327 + *   file called LICENSE.
8328 + *
8329 + ********************************************************************************/
8330 +
8331 +// This macro or function divide two part, 
8332 +// one is initial state, another is in netdev open (ifconfig up) function.
8333 +
8334 +#ifndef  FPGA_H
8335 +#define  FPGA_H
8336 +
8337 +#include <linux/types.h>
8338 +
8339 +#include "cns3xxx_config.h"
8340 +#include "cns3xxx_phy.h"
8341 +
8342 +//#define FGPA
8343 +
8344 +
8345 +#ifdef CONFIG_FPGA
8346 +// init phy or switch chip
8347 +#define INIT_PORT0_PHY cns3xxx_config_VSC8601(0,0);
8348 +#define INIT_PORT1_PHY cns3xxx_config_VSC8601(1,1);
8349 +#define INIT_PORT2_PHY icp_101a_init(2, 2);
8350 +//#define INIT_PORT1_PHY 
8351 +
8352 +// configure mac0/mac1 register
8353 +#define INIT_PORT0_MAC 
8354 +#define INIT_PORT1_MAC
8355 +#define INIT_PORT2_MAC 
8356 +//#define INIT_PORT1_MAC 
8357 +
8358 +#define PORT0_LINK_DOWN vsc8601_power_down(0, 1);
8359 +#define PORT0_LINK_UP vsc8601_power_down(0, 0);
8360 +
8361 +#define PORT1_LINK_DOWN vsc8601_power_down(1, 1);
8362 +#define PORT1_LINK_UP vsc8601_power_down(1, 0);
8363 +
8364 +#define PORT2_LINK_DOWN cns3xxx_std_phy_power_down(2, 1);
8365 +#define PORT2_LINK_UP cns3xxx_std_phy_power_down(2, 0);
8366 +
8367 +
8368 +
8369 +#define MODEL "VEGA FPGA"
8370 +
8371 +static int rc_port0 = 0; // rc means reference counting, determine port open/close.
8372 +
8373 +
8374 +// enable port
8375 +// link down
8376 +static inline void open_port0(void)
8377 +{
8378 +        if (rc_port0 == 0) {
8379 +               enable_port(0, 1);
8380 +               PRINT_INFO("open mac port 0\n");
8381 +               // link up
8382 +               PORT0_LINK_UP
8383 +       } else {
8384 +               PRINT_INFO("port 0 already open\n");\
8385 +       }
8386 +       ++rc_port0;
8387 +}
8388 +
8389 +static inline void close_port0(void)
8390 +{
8391 +       --rc_port0;
8392 +        if (rc_port0 == 0) {
8393 +               // link down
8394 +               PORT0_LINK_DOWN
8395 +               enable_port(0, 0);
8396 +                       PRINT_INFO("close mac port 0\n");\
8397 +       }
8398 +}
8399 +
8400 +static inline void open_port1(void)
8401 +{
8402 +
8403 +       enable_port(1, 1);
8404 +       PRINT_INFO("open mac port 1\n");
8405 +       // link up
8406 +       PORT1_LINK_UP
8407 +}
8408 +
8409 +static inline void close_port1(void)
8410 +{
8411 +       enable_port(1, 0);
8412 +       PRINT_INFO("close mac port 1\n");
8413 +       // link down
8414 +       PORT1_LINK_DOWN
8415 +}
8416 +
8417 +static inline void open_port2(void)
8418 +{
8419 +
8420 +       enable_port(2, 1);
8421 +       PRINT_INFO("open mac port 2\n");
8422 +       // link up
8423 +       PORT2_LINK_UP
8424 +}
8425 +
8426 +static inline void close_port2(void)
8427 +{
8428 +       enable_port(2, 0);
8429 +       PRINT_INFO("close mac port 2\n");
8430 +       // link down
8431 +       PORT2_LINK_DOWN
8432 +}
8433 +
8434 +static u8 my_vlan0_mac[] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x00};
8435 +static u8 my_vlan1_mac[] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x11};
8436 +static u8 my_vlan2_mac[] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x70};
8437 +static u8 my_vlan3_mac[] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x80};
8438 +
8439 +
8440 +
8441 +
8442 +// CNS3XXX_NIC_MODE_8021Q, CNS3XXX_NON_NIC_MODE_8021Q, CNS3XXX_VLAN_BASE_MODE and
8443 +// CNS3XXX_PORT_BASE_MODE, only one macro can be defined
8444 +
8445 +#ifdef CNS3XXX_VLAN_8021Q
8446 +       #ifndef CNS3XXX_NIC_MODE_8021Q
8447 +               #define CNS3XXX_NON_NIC_MODE_8021Q
8448 +       #endif
8449 +#else
8450 +       //#define CNS3XXX_VLAN_BASE_MODE
8451 +       #define CNS3XXX_PORT_BASE_MODE
8452 +#endif
8453 +
8454 +#ifdef CNS3XXX_PORT_BASE_MODE
8455 +
8456 +#define PORT0_PVID 0x1
8457 +#define PORT1_PVID 0x2
8458 +#define PORT2_PVID 3
8459 +#define CPU_PVID 5
8460 +
8461 +#define CONFIG_CNS3XXX_PORT_BASE
8462 +
8463 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; 
8464 +
8465 +static VLANTableEntry vlan_table_entry[] = 
8466 +{
8467 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;
8468 +       //{0, 1, 1, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8469 +       {1, 1, PORT0_PVID, 0, 0, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8470 +       {2, 1, PORT1_PVID, 0, 0, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8471 +       {3, 1, PORT2_PVID, 1, 0, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8472 +       //{2, 1, 4, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}, // for cpu
8473 +};
8474 +
8475 +static ARLTableEntry arl_table_entry[] = 
8476 +{
8477 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8478 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8479 +       //{CPU_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8480 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8481 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8482 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan8_mac, 7, 0, 0},
8483 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan9_mac, 7, 0, 0},
8484 +       //{CPU_PVID, 0x4, my_vlan2_mac, 7, 1, 0},
8485 +       //{CPU_PVID, MAC_PORT2_PMAP, my_vlan2_mac, 7, 1, 0},
8486 +};
8487 +
8488 +static NetDevicePriv net_device_prive[]= {
8489 +       /*  pmap, is_wan, s-tag, vlan_tag or pvid, rx_func_ptr, tx_func_ptr, open_ptr, close_ptr, which port, mac, VLANTableEntry, ARLTableEntry, NICSetting, netdev s-tag, name */
8490 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8491 +       {MAC_PORT1_PMAP, 0, 2, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8492 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
8493 +                                        };
8494 +
8495 +#endif
8496 +
8497 +#ifdef CNS3XXX_NON_NIC_MODE_8021Q
8498 +//#error  "8021Q"
8499 +#define PORT0_PVID 50
8500 +#define PORT1_PVID 60
8501 +#define PORT2_PVID 70
8502 +#define CPU_PVID 80
8503 +
8504 +#define CONFIG_CNS3XXX_PORT_BASE
8505 +//#define CONFIG_CNS3XXX_VLAN_BASE
8506 +//#define CONFIG_HAVE_VLAN_TAG
8507 +
8508 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; // for cpu
8509 +
8510 +static VLANTableEntry vlan_table_entry[] = 
8511 +{
8512 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;C_PORT2_PMAP
8513 +       {1, 1, PORT0_PVID, 0, CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8514 +       {2, 1, PORT1_PVID, 0, CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8515 +       {3, 1, PORT2_PVID, 0, CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8516 +};
8517 +
8518 +static ARLTableEntry arl_table_entry[] = 
8519 +{
8520 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8521 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8522 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8523 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8524 +};
8525 +
8526 +
8527 +// if used 8021Q, use PORT0_NETDEV_INDEX, don't use VID
8528 +static NetDevicePriv net_device_prive[]= {
8529 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8530 +       {MAC_PORT1_PMAP, 0, 0, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8531 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
8532 +                                         };
8533 +#endif
8534 +
8535 +
8536 +
8537 +#ifdef CNS3XXX_NIC_MODE_8021Q
8538 +//#error  "8021Q"
8539 +#define PORT0_PVID 1
8540 +#define PORT1_PVID 2
8541 +#define PORT2_PVID 9
8542 +#define CPU_PVID 5
8543 +
8544 +#define CONFIG_CNS3XXX_PORT_BASE
8545 +//#define CONFIG_CNS3XXX_VLAN_BASE
8546 +//#define CONFIG_HAVE_VLAN_TAG
8547 +
8548 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; // for cpu
8549 +
8550 +static VLANTableEntry vlan_table_entry[] = 
8551 +{
8552 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;C_PORT2_PMAP
8553 +       {1, 1, PORT0_PVID, 1, MAC_PORT0_PMAP|CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8554 +       {2, 1, PORT1_PVID, 0, MAC_PORT1_PMAP|CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8555 +       {3, 1, PORT2_PVID, 1, MAC_PORT2_PMAP|CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8556 +};
8557 +
8558 +static ARLTableEntry arl_table_entry[] = 
8559 +{
8560 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8561 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8562 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8563 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8564 +};
8565 +
8566 +
8567 +// if used 8021Q, use PORT0_NETDEV_INDEX, don't use VID
8568 +static NetDevicePriv net_device_prive[]= {
8569 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8570 +       {MAC_PORT1_PMAP, 0, 0, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8571 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
8572 +                                         };
8573 +#endif
8574 +
8575 +#ifdef CNS3XXX_VLAN_BASE_MODE
8576 +//#error  "vlan_base"
8577 +// vlan configuration
8578 +
8579 +#define PORT0_PVID 1
8580 +#define PORT1_PVID 2
8581 +#define PORT2_PVID 3
8582 +#define CPU_PVID 5
8583 +#define CONFIG_CNS3XXX_VLAN_BASE
8584 +#define CONFIG_HAVE_VLAN_TAG
8585 +
8586 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; // for cpu
8587 +
8588 +static VLANTableEntry vlan_table_entry[] = 
8589 +{
8590 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;
8591 +       {1, 1, PORT0_PVID, 0, MAC_PORT0_PMAP | CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8592 +       {2, 1, PORT1_PVID, 0, MAC_PORT1_PMAP | CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8593 +       {3, 1, PORT2_PVID, 1, MAC_PORT2_PMAP | CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8594 +};
8595 +
8596 +static ARLTableEntry arl_table_entry[] = 
8597 +{
8598 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8599 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8600 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8601 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8602 +};
8603 +
8604 +static NetDevicePriv net_device_prive[]= {
8605 +       /*  pmap, is_wan, gid, vlan_tag or pvid, rx_func_ptr, tx_func_ptr, open_ptr, close_ptr, which port, mac, VLANTableEntry, ARLTableEntry, NICSetting, netdev name */
8606 +       {MAC_PORT0_PMAP, 0, 1, PORT0_PVID, rx_port_base, tx_vlan_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8607 +       {MAC_PORT1_PMAP, 0, 0, PORT1_PVID, rx_port_base, tx_vlan_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8608 +       {MAC_PORT2_PMAP, 1, 3, PORT2_PVID, rx_port_base, tx_vlan_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
8609 +                                        };
8610 +#endif 
8611 +
8612 +#endif // CONFIG_FPGA
8613 +#endif // FPGA_H
8614 --- /dev/null
8615 +++ b/drivers/net/cns3xxx/Kconfig
8616 @@ -0,0 +1,58 @@
8617 +menu "CNS3XXX Gigabit Switch Support"
8618 +       depends on ARCH_CNS3XXX
8619 +
8620 +config CNS3XXX_GSW
8621 +       tristate "CNS3XXX Gigabit Switch Driver Support"
8622 +       help
8623 +         CNS3XXX Gigabit Switch.
8624 +
8625 +config CNS3XXX_SPPE
8626 +       bool "CNS3XXX Smart PPE(Packet Processing Engine) Support"
8627 +       depends on CNS3XXX_GSW
8628 +       help
8629 +         PPE(Packet Processing Engine) is a hardware accelerator hook on a port of 
8630 +         CNS3XXX Gigabit Switch.
8631 +         
8632 +         This option is used for Smart PPE hook. 
8633 +
8634 +         Say Y if you want to enable Smart PPE function.
8635 +
8636 +config CNS3XXX_HCIE_TEST
8637 +       bool "CNS3XXX HCIE(Hardware Content Inspection Engine) Support"
8638 +#      depends on CNS3XXX_GSW
8639 +       help
8640 +         HCIE is patent-protected layer-7 packet processing engine.
8641 +         
8642 +         This option is used for fundamental HCIE functional test . 
8643 +         Say Y if you want to do HCIE functional test.
8644 +               
8645 +
8646 +#config CNS3XXX_SHNAT_PCI_FASTPATH
8647 +#      bool "FastPath(From PCI to WAN) Support"
8648 +#      depends on CNS3XXX_SHNAT
8649 +#      help
8650 +#        Add FastPath Support for Smart HNAT.
8651 +
8652 +comment "NOTE: 'Validation Board' depends on"
8653 +comment "GPIO_CNS3XXX and SPI_CNS3XXX"
8654 +choice
8655 +       prompt "CNS3XXX Board"
8656 +       depends on CNS3XXX_GSW
8657 +       default FPGA
8658 +
8659 +config FPGA
8660 +       bool "Fpga"
8661 +
8662 +config VB
8663 +       bool "Validation Board"
8664 +       help
8665 +         MAC0 and MAC1 connect to BCM53115M. It need enable CNS3XXX SPI and CNS3XXX GPIO option.
8666 +         MAC2 use ICPLUS IP1001 phy.
8667 +
8668 +#config LEO
8669 +#      bool "Leo"
8670 +
8671 +endchoice
8672 +
8673 +endmenu
8674 +
8675 --- /dev/null
8676 +++ b/drivers/net/cns3xxx/Makefile
8677 @@ -0,0 +1,41 @@
8678 +################################################################################
8679 +#
8680 +# 
8681 +#   Copyright (c) 2008 Cavium Networks 
8682 +# 
8683 +# This program is free software; you can redistribute it and/or modify it 
8684 +# under the terms of the GNU General Public License as published by the Free 
8685 +# Software Foundation; either version 2 of the License, or (at your option) 
8686 +# any later version.
8687 +# 
8688 +# This program is distributed in the hope that it will be useful, but WITHOUT 
8689 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
8690 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
8691 +# more details.
8692 +# 
8693 +# You should have received a copy of the GNU General Public License along with
8694 +# this program; if not, write to the Free Software Foundation, Inc., 59 
8695 +# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
8696 +# 
8697 +# The full GNU General Public License is included in this distribution in the
8698 +# file called LICENSE.
8699 +# 
8700 +# Contact Information:
8701 +# Star semiconduction Linux Support <support@starsemi.com>
8702 +#
8703 +################################################################################
8704 +
8705 +#
8706 +# Makefile for the Star GSW ethernet driver
8707 +#
8708 +
8709 +#obj-y :=
8710 +#obj-m :=
8711 +
8712 +obj-$(CONFIG_CNS3XXX_GSW) += cns3xxx.o
8713 +cns3xxx-objs := cns3xxx_phy.o cns3xxx_main.o cns3xxx_ethtool.o
8714 +obj-$(CONFIG_CNS3XXX_SPPE) += cns3xxx_sppe_hook.o
8715 +#endif
8716 +#vega_main.o
8717 +
8718 +#include $(TOPDIR)/Rules.make
8719 --- /dev/null
8720 +++ b/drivers/net/cns3xxx/vb.h
8721 @@ -0,0 +1,328 @@
8722 +/*******************************************************************************
8723 + *
8724 + *   Copyright (c) 2009 Cavium Networks 
8725 + *
8726 + *   This program is free software; you can redistribute it and/or modify it
8727 + *   under the terms of the GNU General Public License as published by the Free
8728 + *   Software Foundation; either version 2 of the License, or (at your option)
8729 + *   any later version.
8730 + *
8731 + *   This program is distributed in the hope that it will be useful, but WITHOUT
8732 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8733 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
8734 + *   more details.
8735 + *
8736 + *   You should have received a copy of the GNU General Public License along with
8737 + *   this program; if not, write to the Free Software Foundation, Inc., 59
8738 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
8739 + *
8740 + *   The full GNU General Public License is included in this distribution in the
8741 + *   file called LICENSE.
8742 + *
8743 + ********************************************************************************/
8744 +
8745 +// This macro or function divide two part, 
8746 +// one is initial state, another is in netdev open (ifconfig up) function.
8747 +
8748 +#ifndef  VB_H
8749 +#define  VB_H
8750 +
8751 +#include <linux/types.h>
8752 +
8753 +#include "cns3xxx_config.h"
8754 +#include "cns3xxx_phy.h"
8755 +
8756 +#ifdef CONFIG_VB
8757 +// init phy or switch chip
8758 +#define INIT_PORT0_PHY cns3xxx_config_VSC8601(0, 0);
8759 +#define INIT_PORT1_PHY cns3xxx_config_VSC8601(1, 1);
8760 +#define INIT_PORT2_PHY
8761 +//#define INIT_PORT1_PHY 
8762 +
8763 +// configure mac0/mac1 register
8764 +#define INIT_PORT0_MAC 
8765 +#define INIT_PORT1_MAC
8766 +#define INIT_PORT2_MAC 
8767 +//#define INIT_PORT1_MAC 
8768 +
8769 +#define PORT0_LINK_DOWN cns3xxx_std_phy_power_down(0, 1);
8770 +#define PORT0_LINK_UP cns3xxx_std_phy_power_down(0, 0);
8771 +
8772 +#define PORT1_LINK_DOWN cns3xxx_std_phy_power_down(1, 1);
8773 +#define PORT1_LINK_UP cns3xxx_std_phy_power_down(1, 0);
8774 +
8775 +#define PORT2_LINK_DOWN
8776 +#define PORT2_LINK_UP
8777 +
8778 +#define MODEL "CNS3XXX validation board"
8779 +
8780 +static int rc_port0 = 0; // rc means reference counting, determine port open/close.
8781 +
8782 +#define PRINT_INFO printk
8783 +
8784 +// enable port
8785 +// link down
8786 +static inline void open_port0(void)
8787 +{
8788 +        if (rc_port0 == 0) {
8789 +               enable_port(0, 1);
8790 +               // link up
8791 +               PORT0_LINK_UP
8792 +       } 
8793 +       ++rc_port0;
8794 +}
8795 +
8796 +static inline void close_port0(void)
8797 +{
8798 +       --rc_port0;
8799 +        if (rc_port0 == 0) {
8800 +               // link down
8801 +               PORT0_LINK_DOWN
8802 +               enable_port(0, 0);
8803 +       }
8804 +}
8805 +
8806 +static inline void open_port1(void)
8807 +{
8808 +
8809 +       enable_port(1, 1);
8810 +       // link up
8811 +       PORT1_LINK_UP
8812 +}
8813 +
8814 +static inline void close_port1(void)
8815 +{
8816 +       enable_port(1, 0);
8817 +       // link down
8818 +       PORT1_LINK_DOWN
8819 +}
8820 +
8821 +static inline void open_port2(void)
8822 +{
8823 +
8824 +       enable_port(2, 1);
8825 +       // link up
8826 +       PORT2_LINK_UP
8827 +}
8828 +
8829 +static inline void close_port2(void)
8830 +{
8831 +       enable_port(2, 0);
8832 +       // link down
8833 +       PORT2_LINK_DOWN
8834 +}
8835 +
8836 +#if defined (CONFIG_CNS3XXX_SPPE)
8837 +/* only for PPE PCI-to-WAN fast path */
8838 +static int fp_ref_cnt = 0;
8839 +static inline void open_fp(void)
8840 +{
8841 +       if (!fp_ref_cnt) {
8842 +               fp_ref_cnt++;
8843 +       }
8844 +}
8845 +
8846 +static inline void close_fp(void)
8847 +{
8848 +       if (fp_ref_cnt) {
8849 +               fp_ref_cnt--;
8850 +       }
8851 +}
8852 +#endif
8853 +
8854 +static u8 my_vlan0_mac[] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x00};
8855 +static u8 my_vlan1_mac[] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x11};
8856 +static u8 my_vlan2_mac[] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x70};
8857 +static u8 my_vlan3_mac[] = {0x00, 0x11, 0xbb, 0xcc, 0xdd, 0x80};
8858 +
8859 +
8860 +
8861 +
8862 +// CNS3XXX_NIC_MODE_8021Q, CNS3XXX_NON_NIC_MODE_8021Q, CNS3XXX_VLAN_BASE_MODE and
8863 +// CNS3XXX_PORT_BASE_MODE, only one macro can be defined
8864 +
8865 +#ifdef CNS3XXX_VLAN_8021Q
8866 +       #define CNS3XXX_NIC_MODE_8021Q
8867 +       #ifndef CNS3XXX_NIC_MODE_8021Q
8868 +               #define CNS3XXX_NON_NIC_MODE_8021Q
8869 +       #endif
8870 +#else
8871 +       //#define CNS3XXX_VLAN_BASE_MODE
8872 +       #define CNS3XXX_PORT_BASE_MODE
8873 +#endif
8874 +
8875 +//#define CNS3XXX_PORT_BASE_MODE
8876 +//
8877 +#ifdef CNS3XXX_NON_NIC_MODE_8021Q
8878 +
8879 +#define PORT0_PVID 50
8880 +#define PORT1_PVID 60
8881 +#define PORT2_PVID 70
8882 +#define CPU_PVID 80
8883 +
8884 +#define CONFIG_CNS3XXX_PORT_BASE
8885 +
8886 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; 
8887 +
8888 +static VLANTableEntry vlan_table_entry[] = 
8889 +{
8890 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;
8891 +       #if 0
8892 +       {1, 1, PORT0_PVID, 0, 0, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8893 +       {2, 1, PORT1_PVID, 0, 0, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8894 +       {3, 1, PORT2_PVID, 1, 0, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8895 +       #endif
8896 +
8897 +       {1, 1, PORT0_PVID, 0, CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8898 +       {2, 1, PORT1_PVID, 0, CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8899 +       {3, 1, PORT2_PVID, 0, CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8900 +       //{2, 1, 4, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}, // for cpu
8901 +};
8902 +
8903 +static ARLTableEntry arl_table_entry[] = 
8904 +{
8905 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8906 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8907 +       //{CPU_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8908 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8909 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8910 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan8_mac, 7, 0, 0},
8911 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan9_mac, 7, 0, 0},
8912 +       //{CPU_PVID, 0x4, my_vlan2_mac, 7, 1, 0},
8913 +       //{CPU_PVID, MAC_PORT2_PMAP, my_vlan2_mac, 7, 1, 0},
8914 +};
8915 +
8916 +static NetDevicePriv net_device_prive[]= {
8917 +       /*  pmap, is_wan, s-tag, vlan_tag or pvid, rx_func_ptr, tx_func_ptr, open_ptr, close_ptr, which port, mac, VLANTableEntry, ARLTableEntry, NICSetting, netdev s-tag, name */
8918 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8919 +       {MAC_PORT1_PMAP, 0, 2, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8920 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2
8921 +#if defined (CONFIG_CNS3XXX_SPPE)
8922 +       ,{CPU_PORT_PMAP, 0, 1, FP_NETDEV_INDEX, NULL, fp_port_base,
8923 +               open_fp, close_fp, CPU_PORT, my_vlan3_mac, &cpu_vlan_table_entry,
8924 +               0, 0, "fp"}
8925 +#endif 
8926 +                                        };
8927 +
8928 +#endif // CNS3XXX_PORT_BASE_MODE
8929 +
8930 +#ifdef CNS3XXX_PORT_BASE_MODE
8931 +
8932 +#define PORT0_PVID 0x1
8933 +#define PORT1_PVID 0x2
8934 +#define PORT2_PVID 3
8935 +#define CPU_PVID 5
8936 +
8937 +#define CONFIG_CNS3XXX_PORT_BASE
8938 +
8939 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; 
8940 +
8941 +static VLANTableEntry vlan_table_entry[] = 
8942 +{
8943 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;
8944 +       //{0, 1, 1, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8945 +       {1, 1, PORT0_PVID, 0, 0, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8946 +       {2, 1, PORT1_PVID, 0, 0, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8947 +       {3, 1, PORT2_PVID, 1, 0, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8948 +       //{2, 1, 4, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}, // for cpu
8949 +};
8950 +
8951 +static ARLTableEntry arl_table_entry[] = 
8952 +{
8953 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8954 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8955 +       //{CPU_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8956 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8957 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
8958 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan8_mac, 7, 0, 0},
8959 +       //{PORT0_PVID, MAC_PORT0_PMAP, my_vlan9_mac, 7, 0, 0},
8960 +       //{CPU_PVID, 0x4, my_vlan2_mac, 7, 1, 0},
8961 +       //{CPU_PVID, MAC_PORT2_PMAP, my_vlan2_mac, 7, 1, 0},
8962 +};
8963 +
8964 +static NetDevicePriv net_device_prive[]= {
8965 +       /*  pmap, is_wan, s-tag, vlan_tag or pvid, rx_func_ptr, tx_func_ptr, open_ptr, close_ptr, which port, mac, VLANTableEntry, ARLTableEntry, NICSetting, netdev s-tag, name */
8966 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
8967 +       {MAC_PORT1_PMAP, 0, 2, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
8968 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
8969 +                                        };
8970 +
8971 +#endif // CNS3XXX_PORT_BASE_MODE
8972 +
8973 +#ifdef CNS3XXX_NIC_MODE_8021Q
8974 +//#error  "8021Q"
8975 +#define PORT0_PVID 1
8976 +#define PORT1_PVID 2
8977 +#define PORT2_PVID 9
8978 +#define CPU_PVID 5
8979 +
8980 +#define CONFIG_CNS3XXX_PORT_BASE
8981 +//#define CONFIG_CNS3XXX_VLAN_BASE
8982 +//#define CONFIG_HAVE_VLAN_TAG
8983 +
8984 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; // for cpu
8985 +
8986 +static VLANTableEntry vlan_table_entry[] = 
8987 +{
8988 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;C_PORT2_PMAP
8989 +       {1, 1, PORT0_PVID, 1, MAC_PORT0_PMAP|CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
8990 +       {2, 1, PORT1_PVID, 0, MAC_PORT1_PMAP|CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
8991 +       {3, 1, PORT2_PVID, 1, MAC_PORT2_PMAP|CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
8992 +};
8993 +
8994 +static ARLTableEntry arl_table_entry[] = 
8995 +{
8996 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
8997 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
8998 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
8999 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
9000 +};
9001 +
9002 +
9003 +// if used 8021Q, use PORT0_NETDEV_INDEX, don't use VID
9004 +static NetDevicePriv net_device_prive[]= {
9005 +       {MAC_PORT0_PMAP, 0, 1, PORT0_NETDEV_INDEX, rx_port_base, tx_port_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
9006 +       {MAC_PORT1_PMAP, 0, 0, PORT1_NETDEV_INDEX, rx_port_base, tx_port_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
9007 +       {MAC_PORT2_PMAP, 1, 3, PORT2_NETDEV_INDEX, rx_port_base, tx_port_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
9008 +                                         };
9009 +#endif // CNS3XXX_NIC_MODE_8021Q
9010 +
9011 +#ifdef CNS3XXX_VLAN_BASE_MODE
9012 +//#error  "vlan_base"
9013 +// vlan configuration
9014 +
9015 +#define PORT0_PVID 1
9016 +#define PORT1_PVID 2
9017 +#define PORT2_PVID 3
9018 +#define CPU_PVID 5
9019 +#define CONFIG_CNS3XXX_VLAN_BASE
9020 +#define CONFIG_HAVE_VLAN_TAG
9021 +
9022 +static VLANTableEntry cpu_vlan_table_entry = {0, 1, CPU_PVID, 0, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, MAC_PORT0_PMAP | MAC_PORT1_PMAP | MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan3_mac}; // for cpu
9023 +
9024 +static VLANTableEntry vlan_table_entry[] = 
9025 +{
9026 +       // vlan_index; valid; vid; wan_side; etag_pmap; mb_pmap; *my_mac;
9027 +       {1, 1, PORT0_PVID, 0, MAC_PORT0_PMAP | CPU_PORT_PMAP, MAC_PORT0_PMAP | CPU_PORT_PMAP, my_vlan0_mac},
9028 +       {2, 1, PORT1_PVID, 0, MAC_PORT1_PMAP | CPU_PORT_PMAP, MAC_PORT1_PMAP | CPU_PORT_PMAP, my_vlan1_mac},
9029 +       {3, 1, PORT2_PVID, 1, MAC_PORT2_PMAP | CPU_PORT_PMAP, MAC_PORT2_PMAP | CPU_PORT_PMAP, my_vlan2_mac},
9030 +};
9031 +
9032 +static ARLTableEntry arl_table_entry[] = 
9033 +{
9034 +       // vid; pmap; *mac; age_field; vlan_mac ; filter
9035 +       {PORT0_PVID, CPU_PORT_PMAP, my_vlan0_mac, 7, 1, 0},
9036 +       {PORT1_PVID, CPU_PORT_PMAP, my_vlan1_mac, 7, 1, 0},
9037 +       {PORT2_PVID, CPU_PORT_PMAP, my_vlan2_mac, 7, 1, 0},
9038 +};
9039 +
9040 +static NetDevicePriv net_device_prive[]= {
9041 +       /*  pmap, is_wan, gid, vlan_tag or pvid, rx_func_ptr, tx_func_ptr, open_ptr, close_ptr, which port, mac, VLANTableEntry, ARLTableEntry, NICSetting, netdev name */
9042 +       {MAC_PORT0_PMAP, 0, 1, PORT0_PVID, rx_port_base, tx_vlan_base, open_port0, close_port0, MAC_PORT0, my_vlan0_mac, &vlan_table_entry[0], &arl_table_entry[0], 0, 0},   // eth0 
9043 +       {MAC_PORT1_PMAP, 0, 0, PORT1_PVID, rx_port_base, tx_vlan_base, open_port1, close_port1, MAC_PORT1, my_vlan1_mac, &vlan_table_entry[1], &arl_table_entry[1], 0, 0},   // eth1 
9044 +       {MAC_PORT2_PMAP, 1, 3, PORT2_PVID, rx_port_base, tx_vlan_base, open_port2, close_port2, MAC_PORT2, my_vlan2_mac,  &vlan_table_entry[2], &arl_table_entry[2], 0, 0}   // eth2 
9045 +                                        };
9046 +#endif // CNS3XXX_VLAN_BASE_MODE
9047 +
9048 +#endif // CONFIG_VB
9049 +#endif // VB_H
9050 --- a/drivers/net/Kconfig
9051 +++ b/drivers/net/Kconfig
9052 @@ -2076,6 +2076,8 @@ menuconfig NETDEV_1000
9053  
9054  if NETDEV_1000
9055  
9056 +source "drivers/net/cns3xxx/Kconfig"
9057 +
9058  config ACENIC
9059         tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
9060         depends on PCI
9061 --- a/drivers/net/Makefile
9062 +++ b/drivers/net/Makefile
9063 @@ -6,6 +6,11 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci
9064  
9065  obj-$(CONFIG_E1000) += e1000/
9066  obj-$(CONFIG_E1000E) += e1000e/
9067 +obj-$(CONFIG_CNS3XXX_GSW) += cns3xxx/
9068 +ifeq ($(CONFIG_CNS3XXX_GSW),m)
9069 +       obj-y += cns3xxx/cns3xxx_sppe_hook.o
9070 +endif
9071 +
9072  obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
9073  obj-$(CONFIG_IGB) += igb/
9074  obj-$(CONFIG_IGBVF) += igbvf/
9075 --- /dev/null
9076 +++ b/include/linux/cns3xxx/sppe.h
9077 @@ -0,0 +1,1579 @@
9078 +/*
9079 + * PROJECT CODE:       CNS3XXX Smart Packet Processing Engine
9080 + * MODULE NAME:                sppe.h
9081 + * DESCRIPTION:                
9082 + *
9083 + * Change Log
9084 + *
9085 + * 1.0.0    25-Dec-2008
9086 + * o  
9087 + *
9088 + */
9089 +
9090 +#ifndef _SPPE_H_
9091 +#define _SPPE_H_
9092 +
9093 +#if defined(CONFIG_CNS3XXX_SPPE)
9094 +
9095 +
9096 +/* PPE Table Size Def. */
9097 +#define PPE_TABLE_SIZE_2K      (0x0)
9098 +#define PPE_TABLE_SIZE_4K      (0x1)
9099 +#define PPE_TABLE_SIZE_8K      (0x2)
9100 +#define PPE_TABLE_SIZE_16K     (0x3)
9101 +#define PPE_TABLE_SIZE_32K     (0x4)
9102 +#define PPE_TABLE_SIZE_64K     (0x5)
9103 +#define PPE_TABLE_SIZE_128K    (0x6)
9104 +#define PPE_TABLE_SIZE_256K    (0x7)
9105 +
9106 +typedef enum _sppe_cmd {
9107 +       SPPE_CMD_INIT = 0,
9108 +       SPPE_CMD_VERSION,
9109 +
9110 +       SPPE_CMD_ENABLE,
9111 +       SPPE_CMD_FIREWALL,
9112 +       SPPE_CMD_RULE_CHECK,
9113 +       SPPE_CMD_GRL_CHECK,
9114 +       SPPE_CMD_FLOW_CHECK,
9115 +       SPPE_CMD_RATE_LIMIT_EN,
9116 +       SPPE_CMD_POLICE_EN,
9117 +       SPPE_CMD_RLCFG,
9118 +       SPPE_CMD_FC,                    /* flow control */
9119 +       SPPE_CMD_MIRROR_TO_CPU, 
9120 +       
9121 +       SPPE_CMD_TCP_SNA_TH,
9122 +       SPPE_CMD_PRDA,
9123 +       SPPE_CMD_AGING,
9124 +       SPPE_CMD_MAX_LENGTH,
9125 +
9126 +       SPPE_CMD_LANIPV4,
9127 +       SPPE_CMD_WANIPV4,
9128 +
9129 +       SPPE_CMD_RULE_PPPOE_RELAY,
9130 +       SPPE_CMD_RULE_BRIDGE,
9131 +       SPPE_CMD_RULE_ACL,
9132 +       SPPE_CMD_RULE_ROUTE,
9133 +#if 0
9134 +       SPPE_CMD_RULE_VSERVER,
9135 +#else
9136 +       SPPE_CMD_RULE_SNAT,
9137 +       SPPE_CMD_RULE_DNAT,
9138 +#endif
9139 +       SPPE_CMD_RULE_GRL,
9140 +
9141 +       SPPE_CMD_ARP,
9142 +       SPPE_CMD_ARL,
9143 +       SPPE_CMD_PPPOE_SID,
9144 +
9145 +       SPPE_CMD_FLOW_BRIDGE_IPV4,
9146 +       SPPE_CMD_FLOW_BRIDGE_IPV6,
9147 +       SPPE_CMD_FLOW_ROUTE_IPV4,
9148 +       SPPE_CMD_FLOW_ROUTE_IPV6,
9149 +       SPPE_CMD_FLOW_NAT_IPV4,
9150 +       SPPE_CMD_FLOW_NAT_IPV6,
9151 +       //SPPE_CMD_FLOW_TWICE_NAT,
9152 +       SPPE_CMD_FLOW_MCAST_IPV4,
9153 +       SPPE_CMD_FLOW_MCAST_IPV6,
9154 +       SPPE_CMD_FLOW_BRIDGE_L2,
9155 +
9156 +       SPPE_CMD_CHGDSCP,
9157 +       SPPE_CMD_CHGPRI,
9158 +       SPPE_CMD_RL_FLOW,
9159 +       SPPE_CMD_RL_RULE,
9160 +
9161 +       SPPE_CMD_DEBUG,
9162 +       SPPE_CMD_REG,
9163 +       SPPE_CMD_SRAM,
9164 +       SPPE_CMD_DUMP,
9165 +
9166 +       /* accounting group and drop packet count */
9167 +       SPPE_CMD_ACCOUNTING_GROUP,
9168 +       SPPE_CMD_DROP_IPCS_ERR,
9169 +       SPPE_CMD_DROP_RATE_LIMIT,
9170 +       SPPE_CMD_DROP_OTHERS,
9171 +
9172 +       SPPE_CMD_PCI_FP_DEV,
9173 +
9174 +} SPPE_CMD;
9175 +
9176 +typedef enum _sppe_op {
9177 +       SPPE_OP_GET = 0,
9178 +       SPPE_OP_SET,
9179 +       SPPE_OP_DELETE,
9180 +       SPPE_OP_DELETE_OUTDATED, /* flow only */
9181 +       SPPE_OP_UPDATE_COUNTER, /* ACL rule only */
9182 +       SPPE_OP_CLEAN,
9183 +       SPPE_OP_UNKNOWN
9184 +} SPPE_OP;
9185 +
9186 +typedef enum _sppe_boolean {
9187 +    SPPE_BOOL_FALSE = 0,
9188 +    SPPE_BOOL_TRUE = 1
9189 +} SPPE_BOOL;
9190 +
9191 +
9192 +typedef enum _sppe_result {
9193 +       SPPE_RESULT_SUCCESS = 0,
9194 +       SPPE_RESULT_FAIL,
9195 +       SPPE_RESULT_UNSUPPORT_CMD,
9196 +       SPPE_RESULT_UNSUPPORT_OP,
9197 +       SPPE_RESULT_INVALID_INDEX,
9198 +       SPPE_RESULT_INVALID_TYPE,
9199 +       SPPE_RESULT_FLOW_NOT_FOUND,
9200 +} SPPE_RESULT;
9201 +
9202 +typedef enum _sppe_prot {
9203 +       SPPE_PROT_UDP = 0,
9204 +       SPPE_PROT_TCP = 1,
9205 +       SPPE_PROT_PPTP_GRE = 2,
9206 +       SPPE_PROT_OTHERS = 3,
9207 +} SPPE_PROT;
9208 +
9209 +
9210 +typedef enum _sppe_l2_select {
9211 +       SPPE_L2S_ARP_TABLE = 0,
9212 +       SPPE_L2S_POLICY_ROUTE = 1,
9213 +       SPPE_L2S_IN_FLOW = 2,
9214 +       SPPE_L2S_RESERVED = 3,
9215 +} SPPE_L2_SELECT;
9216 +
9217 +typedef enum _sppe_dump_type {
9218 +       SPPE_DUMP_TYPE_FLOW = 0,
9219 +       SPPE_DUMP_TYPE_ARP,
9220 +       SPPE_DUMP_TYPE_RULE
9221 +} SPPE_DUMP_TYPE;
9222 +
9223 +/* Data Structure */
9224 +typedef struct _sppe_pppoe_relay {
9225 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9226 +       unsigned int valid:1;
9227 +       unsigned int unused:31;
9228 +#else
9229 +       unsigned int unused:31;
9230 +       unsigned int valid:1;
9231 +#endif
9232 +       unsigned short lsid; /* PPPoE session ID in LAN side */
9233 +       unsigned short wsid; /* PPPoE session ID in WAN side */
9234 +       unsigned char lmac[6]; /* MAC address of PPPoE client */
9235 +       unsigned char wmac[6]; /* MAC address of PPPoE server */
9236 +} SPPE_PPPOE_RELAY;
9237 +
9238 +typedef struct _sppe_bridge {
9239 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9240 +       unsigned int valid:1;
9241 +       unsigned int wan:1;
9242 +       unsigned int ppp:1; /* enable PPPoE sessoion ID comparison*/
9243 +       unsigned int psidx:4; /* PPPoE session ID index */
9244 +       unsigned int kv:1;
9245 +       unsigned int sws:1;
9246 +       unsigned int max_len:2; /* Max. length select */
9247 +       unsigned int fp:1;      /* force VLAN priority */
9248 +       unsigned int pri:3;
9249 +       unsigned int ag:2;
9250 +       unsigned int unused:15;
9251 +#else
9252 +       unsigned int unused:15;
9253 +       unsigned int ag:2;
9254 +       unsigned int pri:3;
9255 +       unsigned int fp:1;      /* force VLAN priority */
9256 +       unsigned int max_len:2; /* Max. length select */
9257 +       unsigned int sws:1;
9258 +       unsigned int kv:1;
9259 +       unsigned int psidx:4; /* PPPoE session ID index */
9260 +       unsigned int ppp:1; /* enable PPPoE sessoion ID comparison*/
9261 +       unsigned int wan:1;
9262 +       unsigned int valid:1;
9263 +#endif
9264 +
9265 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9266 +       unsigned int svid:12;
9267 +       unsigned int cvid:12;
9268 +       unsigned int loc:8;
9269 +#else
9270 +       unsigned int loc:8;
9271 +       unsigned int cvid:12;
9272 +       unsigned int svid:12;
9273 +#endif
9274 +                       
9275 +       unsigned char smac[6]; /* source MAC address  */
9276 +       unsigned char dmac[6]; /* destination MAC address */
9277 +       unsigned int pkt_cnt;
9278 +} SPPE_BRIDGE;
9279 +
9280 +typedef struct _sppe_acl {
9281 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9282 +       unsigned int valid:1;
9283 +       unsigned int ipv6:1;
9284 +       unsigned int wan:1;
9285 +       unsigned int tcp:1;
9286 +       unsigned int udp:1;
9287 +       unsigned int to:4;
9288 +       unsigned int from:4;
9289 +       unsigned int rr:4;
9290 +       unsigned int kv:1;
9291 +       unsigned int sws:1;
9292 +       unsigned int loc:8;
9293 +       unsigned int max_len:2; /* Max. length select */
9294 +       unsigned int unused:3;
9295 +#else
9296 +       unsigned int unused:3;
9297 +       unsigned int max_len:2; /* Max. length select */
9298 +       unsigned int loc:8;
9299 +       unsigned int sws:1;
9300 +       unsigned int kv:1;
9301 +       unsigned int rr:4;
9302 +       unsigned int from:4;
9303 +       unsigned int to:4;
9304 +       unsigned int udp:1;
9305 +       unsigned int tcp:1;
9306 +       unsigned int wan:1;
9307 +       unsigned int ipv6:1;
9308 +       unsigned int valid:1;
9309 +#endif
9310 +
9311 +       unsigned int sip[4];
9312 +       unsigned int dip[4];
9313 +       unsigned short sip_mask;
9314 +       unsigned short dip_mask;
9315 +
9316 +       unsigned short sport_start;
9317 +       unsigned short sport_end;
9318 +       unsigned short dport_start;
9319 +       unsigned short dport_end;
9320 +       unsigned int pkt_cnt;
9321 +} SPPE_ACL;
9322 +
9323 +typedef struct _sppe_route {
9324 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9325 +       unsigned int valid:1;
9326 +       unsigned int ipv6:1;
9327 +       unsigned int wan:1;
9328 +       unsigned int rd:1; /* replace dscp */
9329 +       unsigned int dscp:6;
9330 +       unsigned int pr:1;      /* policy route */
9331 +       unsigned int prs:2;     /* policy route select */
9332 +       unsigned int kv:1;
9333 +       unsigned int sws:1;
9334 +       unsigned int max_len:2; /* Max. length select */
9335 +       unsigned int fp:1;      /* force VLAN priority */
9336 +       unsigned int pri:3;
9337 +       unsigned int pd:1;
9338 +       unsigned int pi:1;
9339 +       unsigned int psidx:4;
9340 +       unsigned int ag:2;
9341 +       unsigned int unused:3;
9342 +#else
9343 +       unsigned int unused:3;
9344 +       unsigned int ag:2;
9345 +       unsigned int psidx:4;
9346 +       unsigned int pi:1;
9347 +       unsigned int pd:1;
9348 +       unsigned int pri:3;
9349 +       unsigned int fp:1;      /* force VLAN priority */
9350 +       unsigned int max_len:2; /* Max. length select */
9351 +       unsigned int sws:1;
9352 +       unsigned int kv:1;
9353 +       unsigned int prs:2;     /* policy route select */
9354 +       unsigned int pr:1;      /* policy route */
9355 +       unsigned int dscp:6;
9356 +       unsigned int rd:1; /* replace dscp */
9357 +       unsigned int wan:1;
9358 +       unsigned int ipv6:1;
9359 +       unsigned int valid:1;
9360 +#endif 
9361 +
9362 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9363 +       unsigned int unused_1:24;
9364 +       unsigned int loc:8;
9365 +#else
9366 +       unsigned int loc:8;
9367 +       unsigned int unused_1:24;
9368 +#endif
9369 +
9370 +       unsigned int dip[4];
9371 +       unsigned int sip[4];
9372 +       unsigned short dip_mask;
9373 +       unsigned short sip_mask;
9374 +       unsigned int pkt_cnt;
9375 +} SPPE_ROUTE;
9376 +
9377 +#if 0
9378 +typedef struct _sppe_vserver {
9379 +       unsigned int valid:1;
9380 +       unsigned int tcp:1;
9381 +       unsigned int udp:1;
9382 +       unsigned int dscp_lan:6;
9383 +       unsigned int dscp_wan:6;
9384 +       unsigned int pri_lan:3;
9385 +       unsigned int pri_wan:3;
9386 +       unsigned int unused:11;
9387 +
9388 +       unsigned int wanip;
9389 +       unsigned int lanip;
9390 +       unsigned short port_start;
9391 +       unsigned short port_end;
9392 +       unsigned int pkt_cnt;
9393 +} SPPE_VSERVER;
9394 +#else
9395 +typedef struct _sppe_snat {
9396 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9397 +       unsigned int valid:1;
9398 +       unsigned int tcp:1;
9399 +       unsigned int udp:1;
9400 +       unsigned int rd:1;
9401 +       unsigned int dscp:6;
9402 +       unsigned int fp:1;
9403 +       unsigned int pri:3;
9404 +       unsigned int kv:1;
9405 +       unsigned int sws:1;
9406 +       unsigned int max_len:2;
9407 +       unsigned int pd:1;
9408 +       unsigned int pi:1;
9409 +       unsigned int psidx:4;
9410 +       unsigned int pr:1;      /* policy route */
9411 +       unsigned int prs:2;     /* policy route select */
9412 +       unsigned int ag:2;
9413 +       unsigned int unused:3;
9414 +#else
9415 +       unsigned int unused:3;
9416 +       unsigned int ag:2;
9417 +       unsigned int prs:2;     /* policy route select */
9418 +       unsigned int pr:1;      /* policy route */
9419 +       unsigned int psidx:4;
9420 +       unsigned int pi:1;
9421 +       unsigned int pd:1;
9422 +       unsigned int max_len:2;
9423 +       unsigned int sws:1;
9424 +       unsigned int kv:1;
9425 +       unsigned int pri:3;
9426 +       unsigned int fp:1;
9427 +       unsigned int dscp:6;
9428 +       unsigned int rd:1;
9429 +       unsigned int udp:1;
9430 +       unsigned int tcp:1;
9431 +       unsigned int valid:1;
9432 +#endif
9433 +
9434 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9435 +       unsigned int unused_1:24;
9436 +       unsigned int loc:8;
9437 +#else
9438 +       unsigned int loc:8;
9439 +       unsigned int unused_1:24;
9440 +#endif
9441 +
9442 +       unsigned int wanip;
9443 +       unsigned int lanip;
9444 +       unsigned short port_start;
9445 +       unsigned short port_end;
9446 +       unsigned int pkt_cnt;
9447 +} SPPE_SNAT;
9448 +
9449 +typedef struct _sppe_dnat {
9450 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9451 +       unsigned int valid:1;
9452 +       unsigned int tcp:1;
9453 +       unsigned int udp:1;
9454 +       unsigned int rd:1;
9455 +       unsigned int dscp:6;
9456 +       unsigned int fp:1;
9457 +       unsigned int pri:3;
9458 +       unsigned int kv:1;
9459 +       unsigned int sws:1;
9460 +       unsigned int max_len:2;
9461 +       unsigned int pd:1;
9462 +       unsigned int pi:1;
9463 +       unsigned int psidx:4;
9464 +       unsigned int pr:1;      /* policy route */
9465 +       unsigned int prs:2;     /* policy route select */
9466 +       unsigned int ag:2;
9467 +       unsigned int unused:3;
9468 +#else
9469 +       unsigned int unused:3;
9470 +       unsigned int ag:2;
9471 +       unsigned int prs:2;     /* policy route select */
9472 +       unsigned int pr:1;      /* policy route */
9473 +       unsigned int psidx:4;
9474 +       unsigned int pi:1;
9475 +       unsigned int pd:1;
9476 +       unsigned int max_len:2;
9477 +       unsigned int sws:1;
9478 +       unsigned int kv:1;
9479 +       unsigned int pri:3;
9480 +       unsigned int fp:1;
9481 +       unsigned int dscp:6;
9482 +       unsigned int rd:1;
9483 +       unsigned int udp:1;
9484 +       unsigned int tcp:1;
9485 +       unsigned int valid:1;
9486 +#endif
9487 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9488 +       unsigned int unused_1:24;
9489 +       unsigned int loc:8;
9490 +#else
9491 +       unsigned int loc:8;
9492 +       unsigned int unused_1:24;
9493 +#endif
9494 +
9495 +       unsigned int wanip;
9496 +       unsigned int lanip;
9497 +       unsigned short port_start;
9498 +       unsigned short port_end;
9499 +       unsigned int pkt_cnt;
9500 +} SPPE_DNAT;
9501 +#endif
9502 +typedef struct _sppe_limit {
9503 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9504 +       unsigned int drop_red:1;
9505 +       unsigned int pass_green:1;
9506 +       unsigned int force_color:1;
9507 +       unsigned int color_select:2;
9508 +       unsigned int time_stamp:21;
9509 +       unsigned int reserved:6;
9510 +#else
9511 +       unsigned int reserved:6;
9512 +       unsigned int time_stamp:21;
9513 +       unsigned int color_select:2;
9514 +       unsigned int force_color:1;
9515 +       unsigned int pass_green:1;
9516 +       unsigned int drop_red:1;
9517 +#endif
9518 +       unsigned short min_rate;
9519 +       unsigned short max_rate;
9520 +} SPPE_LIMIT;
9521 +
9522 +typedef struct _sppe_global_rate_limit {
9523 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9524 +       unsigned int valid:1;
9525 +       unsigned int wan:1;
9526 +       unsigned int ipv6:1;
9527 +       unsigned int tcp:1;
9528 +       unsigned int udp:1;
9529 +       unsigned int unused:17;
9530 +#else
9531 +       unsigned int unused:17;
9532 +       unsigned int udp:1;
9533 +       unsigned int tcp:1;
9534 +       unsigned int ipv6:1;
9535 +       unsigned int wan:1;
9536 +       unsigned int valid:1;
9537 +#endif
9538 +       
9539 +       unsigned int sip[4];
9540 +       unsigned int dip[4];
9541 +       unsigned short sip_mask;
9542 +       unsigned short dip_mask;
9543 +       unsigned short sport_start;
9544 +       unsigned short sport_end;
9545 +       unsigned short dport_start;
9546 +       unsigned short dport_end;
9547 +       SPPE_LIMIT limit;
9548 +} SPPE_GLOBAL_RATE_LIMIT;
9549 +
9550 +/* 
9551 + * SPPE_CMD_FLOW_BRIDGE_IPV4 
9552 + * type = 1 , as = 3
9553 + */
9554 +typedef struct _sppe_flow_bridge_ipv4 {
9555 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9556 +       unsigned int fw:1;
9557 +       unsigned int s:1;
9558 +       unsigned int sws:1;
9559 +       unsigned int ag:2;
9560 +       unsigned int rl:1;
9561 +       unsigned int l4_prot:2;
9562 +       unsigned int l2s:2; /* L2 select */
9563 +       unsigned int prs:2;
9564 +       unsigned int kv:1;
9565 +       unsigned int fp:1;
9566 +       unsigned int pri:3;
9567 +       unsigned int max_len:2; /* Max. length select */
9568 +       unsigned int reserved:13;
9569 +#else
9570 +       unsigned int reserved:13;
9571 +       unsigned int max_len:2; /* Max. length select */
9572 +       unsigned int pri:3;
9573 +       unsigned int fp:1;
9574 +       unsigned int kv:1;
9575 +       unsigned int prs:2;
9576 +       unsigned int l2s:2; /* L2 select */
9577 +       unsigned int l4_prot:2;
9578 +       unsigned int rl:1;
9579 +       unsigned int ag:2;
9580 +       unsigned int sws:1;
9581 +       unsigned int s:1;
9582 +       unsigned int fw:1;
9583 +#endif
9584 +       
9585 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9586 +       unsigned int unused:16;
9587 +       unsigned int mac4732:16;
9588 +#else
9589 +       unsigned int mac4732:16;
9590 +       unsigned int unused:16;
9591 +#endif
9592 +       
9593 +       unsigned int mac3100;
9594 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9595 +       unsigned int lp:1;      
9596 +       unsigned int fr:1;
9597 +       unsigned int pm:4;
9598 +       unsigned int sv:1;
9599 +       unsigned int svid:12;
9600 +       unsigned int cv:1;      
9601 +       unsigned int cvid:12;
9602 +#else
9603 +       unsigned int cvid:12;
9604 +       unsigned int cv:1;      
9605 +       unsigned int svid:12;
9606 +       unsigned int sv:1;
9607 +       unsigned int pm:4;
9608 +       unsigned int fr:1;
9609 +       unsigned int lp:1;      
9610 +#endif
9611 +       unsigned int sip;
9612 +       unsigned int dip;
9613 +
9614 +       union {
9615 +               struct {
9616 +                       unsigned short src;
9617 +                       unsigned short dst;
9618 +               } port;
9619 +               struct {
9620 +                       unsigned short call_id;
9621 +               } gre;
9622 +               struct {
9623 +                       unsigned char protocol;
9624 +               } others;
9625 +       } l4;
9626 +
9627 +       SPPE_LIMIT limit;
9628 +       unsigned int pkt_cnt;
9629 +} SPPE_FLOW_BRIDGE_IPV4;
9630 +
9631 +/* 
9632 + * SPPE_CMD_FLOW_BRIDGE_IPV6 
9633 + * type = 2 , as = 3
9634 + */
9635 +typedef struct _sppe_flow_bridge_ipv6 {
9636 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9637 +       unsigned int fw:1;
9638 +       unsigned int s:1;
9639 +       unsigned int sws:1;
9640 +       unsigned int ag:2;
9641 +       unsigned int rl:1;
9642 +       unsigned int l4_prot:2;
9643 +       unsigned int l2s:2; /* L2 select */
9644 +       unsigned int prs:2;
9645 +       unsigned int kv:1;
9646 +       unsigned int fp:1;
9647 +       unsigned int pri:3;
9648 +       unsigned int max_len:2; /* Max. length select */
9649 +       unsigned int reserved:13;
9650 +#else
9651 +       unsigned int reserved:13;
9652 +       unsigned int max_len:2; /* Max. length select */
9653 +       unsigned int pri:3;
9654 +       unsigned int fp:1;
9655 +       unsigned int kv:1;
9656 +       unsigned int prs:2;
9657 +       unsigned int l2s:2; /* L2 select */
9658 +       unsigned int l4_prot:2;
9659 +       unsigned int rl:1;
9660 +       unsigned int ag:2;
9661 +       unsigned int sws:1;
9662 +       unsigned int s:1;
9663 +       unsigned int fw:1;
9664 +#endif
9665 +       
9666 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9667 +       unsigned int unused:16;
9668 +       unsigned int mac4732:16;
9669 +#else
9670 +       unsigned int mac4732:16;
9671 +       unsigned int unused:16;
9672 +#endif
9673 +       
9674 +       unsigned int mac3100;
9675 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9676 +       unsigned int lp:1;      
9677 +       unsigned int fr:1;
9678 +       unsigned int pm:4;
9679 +       unsigned int sv:1;
9680 +       unsigned int svid:12;
9681 +       unsigned int cv:1;      
9682 +       unsigned int cvid:12;
9683 +#else
9684 +       unsigned int cvid:12;
9685 +       unsigned int cv:1;      
9686 +       unsigned int svid:12;
9687 +       unsigned int sv:1;
9688 +       unsigned int pm:4;
9689 +       unsigned int fr:1;
9690 +       unsigned int lp:1;      
9691 +#endif
9692 +       unsigned int sip[4];
9693 +       unsigned int dip[4];
9694 +       union {
9695 +               struct {
9696 +                       unsigned short src;
9697 +                       unsigned short dst;
9698 +               } port;
9699 +               struct {
9700 +                       unsigned short call_id;
9701 +               } gre;
9702 +               struct {
9703 +                       unsigned char protocol;
9704 +               } others;
9705 +       } l4;
9706 +       SPPE_LIMIT limit;
9707 +       unsigned int pkt_cnt;
9708 +} SPPE_FLOW_BRIDGE_IPV6;
9709 +
9710 +/* 
9711 + * SPPE_CMD_FLOW_ROUTE_IPV4
9712 + * type = 1, as = 0
9713 + */
9714 +typedef struct _sppe_flow_route_ipv4 {
9715 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9716 +       unsigned int fw:1;
9717 +       unsigned int s:1;
9718 +       unsigned int sws:1;
9719 +       unsigned int ag:2;
9720 +       unsigned int rl:1;
9721 +       unsigned int l4_prot:2;
9722 +       unsigned int l2s:2; /* L2 select */
9723 +       unsigned int prs:2;
9724 +       unsigned int kv:1;
9725 +       unsigned int rd:1;
9726 +       unsigned int dscp:6;
9727 +       unsigned int fp:1;
9728 +       unsigned int pri:3;
9729 +       unsigned int max_len:2; /* Max. length select */
9730 +       unsigned int pd:1;
9731 +       unsigned int pi:1;
9732 +       unsigned int psidx:4;
9733 +#else
9734 +       unsigned int psidx:4;
9735 +       unsigned int pi:1;
9736 +       unsigned int pd:1;
9737 +       unsigned int max_len:2; /* Max. length select */
9738 +       unsigned int pri:3;
9739 +       unsigned int fp:1;
9740 +       unsigned int dscp:6;
9741 +       unsigned int rd:1;
9742 +       unsigned int kv:1;
9743 +       unsigned int prs:2;
9744 +       unsigned int l2s:2; /* L2 select */
9745 +       unsigned int l4_prot:2;
9746 +       unsigned int rl:1;
9747 +       unsigned int ag:2;
9748 +       unsigned int sws:1;
9749 +       unsigned int s:1;
9750 +       unsigned int fw:1;
9751 +#endif
9752 +       
9753 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9754 +       unsigned int unused:16;
9755 +       unsigned int mac4732:16;
9756 +#else
9757 +       unsigned int mac4732:16;
9758 +       unsigned int unused:16;
9759 +#endif
9760 +       unsigned int mac3100;
9761 +
9762 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9763 +       unsigned int lp:1;      
9764 +       unsigned int fr:1;
9765 +       unsigned int pm:4;
9766 +       unsigned int sv:1;
9767 +       unsigned int svid:12;
9768 +       unsigned int cv:1;      
9769 +       unsigned int cvid:12;
9770 +#else
9771 +       unsigned int cvid:12;
9772 +       unsigned int cv:1;      
9773 +       unsigned int svid:12;
9774 +       unsigned int sv:1;
9775 +       unsigned int pm:4;
9776 +       unsigned int fr:1;
9777 +       unsigned int lp:1;      
9778 +#endif
9779 +
9780 +       unsigned int sip;
9781 +       unsigned int dip;
9782 +       union {
9783 +               struct {
9784 +                       unsigned short src;
9785 +                       unsigned short dst;
9786 +               } port;
9787 +               struct {
9788 +                       unsigned short call_id;
9789 +               } gre;
9790 +               struct {
9791 +                       unsigned char protocol;
9792 +               } others;
9793 +       } l4;
9794 +       SPPE_LIMIT limit;
9795 +       unsigned int pkt_cnt;
9796 +} SPPE_FLOW_ROUTE_IPV4;
9797 +
9798 +/* 
9799 + * SPPE_CMD_FLOW_ROUTE_IPV6
9800 + * type = 2, as = 0
9801 + */
9802 +typedef struct _sppe_flow_route_ipv6 {
9803 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9804 +       unsigned int fw:1;
9805 +       unsigned int s:1;
9806 +       unsigned int sws:1;
9807 +       unsigned int ag:2;
9808 +       unsigned int rl:1;
9809 +       unsigned int l4_prot:2;
9810 +       unsigned int l2s:2; /* L2 select */
9811 +       unsigned int prs:2;
9812 +       unsigned int kv:1;
9813 +       unsigned int rd:1;
9814 +       unsigned int dscp:6;
9815 +       unsigned int fp:1;
9816 +       unsigned int pri:3;
9817 +       unsigned int max_len:2; /* Max. length select */
9818 +       unsigned int pd:1;
9819 +       unsigned int pi:1;
9820 +       unsigned int psidx:4;
9821 +#else
9822 +       unsigned int psidx:4;
9823 +       unsigned int pi:1;
9824 +       unsigned int pd:1;
9825 +       unsigned int max_len:2; /* Max. length select */
9826 +       unsigned int pri:3;
9827 +       unsigned int fp:1;
9828 +       unsigned int dscp:6;
9829 +       unsigned int rd:1;
9830 +       unsigned int kv:1;
9831 +       unsigned int prs:2;
9832 +       unsigned int l2s:2; /* L2 select */
9833 +       unsigned int l4_prot:2;
9834 +       unsigned int rl:1;
9835 +       unsigned int ag:2;
9836 +       unsigned int sws:1;
9837 +       unsigned int s:1;
9838 +       unsigned int fw:1;
9839 +#endif
9840 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9841 +       unsigned int unused:16;
9842 +       unsigned int mac4732:16;
9843 +#else
9844 +       unsigned int mac4732:16;
9845 +       unsigned int unused:16;
9846 +#endif 
9847 +       unsigned int mac3100;
9848 +
9849 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9850 +       unsigned int lp:1;      
9851 +       unsigned int fr:1;
9852 +       unsigned int pm:4;
9853 +       unsigned int sv:1;
9854 +       unsigned int svid:12;
9855 +       unsigned int cv:1;      
9856 +       unsigned int cvid:12;
9857 +#else
9858 +       unsigned int cvid:12;
9859 +       unsigned int cv:1;      
9860 +       unsigned int svid:12;
9861 +       unsigned int sv:1;
9862 +       unsigned int pm:4;
9863 +       unsigned int fr:1;
9864 +       unsigned int lp:1;      
9865 +#endif
9866 +       unsigned int sip[4];
9867 +       unsigned int dip[4];
9868 +       union {
9869 +               struct {
9870 +                       unsigned short src;
9871 +                       unsigned short dst;
9872 +               } port;
9873 +               struct {
9874 +                       unsigned short call_id;
9875 +               } gre;
9876 +               struct {
9877 +                       unsigned char protocol;
9878 +               } others;
9879 +       } l4;
9880 +       SPPE_LIMIT limit;
9881 +       unsigned int pkt_cnt;
9882 +} SPPE_FLOW_ROUTE_IPV6;
9883 +
9884 +/*
9885 + * SPPE_CMD_FLOW_NAT_IPV4 
9886 + * type = 0, as = 1
9887 + */
9888 +typedef struct _sppe_flow_nat_ipv4 {
9889 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9890 +       unsigned int fw:1;
9891 +       unsigned int s:1;
9892 +       unsigned int sws:1;
9893 +       unsigned int ag:2;
9894 +       unsigned int rl:1;
9895 +       unsigned int l4_prot:2;
9896 +       unsigned int l2s:2; /* L2 select */
9897 +       unsigned int prs:2;
9898 +       unsigned int kv:1;
9899 +       unsigned int rd:1;
9900 +       unsigned int dscp:6;
9901 +       unsigned int fp:1;
9902 +       unsigned int pri:3;
9903 +       unsigned int max_len:2; /* Max. length select */
9904 +       unsigned int pd:1;
9905 +       unsigned int pi:1;
9906 +       unsigned int psidx:4;
9907 +#else
9908 +       unsigned int psidx:4;
9909 +       unsigned int pi:1;
9910 +       unsigned int pd:1;
9911 +       unsigned int max_len:2; /* Max. length select */
9912 +       unsigned int pri:3;
9913 +       unsigned int fp:1;
9914 +       unsigned int dscp:6;
9915 +       unsigned int rd:1;
9916 +       unsigned int kv:1;
9917 +       unsigned int prs:2;
9918 +       unsigned int l2s:2; /* L2 select */
9919 +       unsigned int l4_prot:2;
9920 +       unsigned int rl:1;
9921 +       unsigned int ag:2;
9922 +       unsigned int sws:1;
9923 +       unsigned int s:1;
9924 +       unsigned int fw:1;
9925 +#endif
9926 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9927 +       unsigned int unused:16;
9928 +       unsigned int mac4732:16;
9929 +#else
9930 +       unsigned int mac4732:16;
9931 +       unsigned int unused:16;
9932 +#endif
9933 +
9934 +       unsigned int mac3100;
9935 +
9936 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9937 +       unsigned int lp:1;      
9938 +       unsigned int fr:1;
9939 +       unsigned int pm:4;
9940 +       unsigned int sv:1;
9941 +       unsigned int svid:12;
9942 +       unsigned int cv:1;      
9943 +       unsigned int cvid:12;
9944 +#else
9945 +       unsigned int cvid:12;
9946 +       unsigned int cv:1;      
9947 +       unsigned int svid:12;
9948 +       unsigned int sv:1;
9949 +       unsigned int pm:4;
9950 +       unsigned int fr:1;
9951 +       unsigned int lp:1;      
9952 +#endif
9953 +
9954 +       unsigned int sip;
9955 +       unsigned int dip;
9956 +       union {
9957 +               struct {
9958 +                       unsigned short src;
9959 +                       unsigned short dst;
9960 +               } port;
9961 +               struct {
9962 +                       unsigned short call_id;
9963 +                       unsigned short nat_call_id;
9964 +               } gre;
9965 +               struct {
9966 +                       unsigned char protocol;
9967 +               } others;
9968 +       } l4;
9969 +       unsigned int nat_ip;
9970 +       unsigned short nat_port;
9971 +       SPPE_LIMIT limit;
9972 +       unsigned int pkt_cnt;
9973 +} SPPE_FLOW_NAT_IPV4;
9974 +
9975 +/*
9976 + * SPPE_CMD_FLOW_NAT_IPV6
9977 + * type = 1, as = 1
9978 + */
9979 +typedef struct _sppe_flow_nat_ipv6 {
9980 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
9981 +       unsigned int fw:1;
9982 +       unsigned int s:1;
9983 +       unsigned int sws:1;
9984 +       unsigned int ag:2;
9985 +       unsigned int rl:1;
9986 +       unsigned int l4_prot:2;
9987 +       unsigned int l2s:2; /* L2 select */
9988 +       unsigned int prs:2;
9989 +       unsigned int kv:1;
9990 +       unsigned int rd:1;
9991 +       unsigned int dscp:6;
9992 +       unsigned int fp:1;
9993 +       unsigned int pri:3;
9994 +       unsigned int max_len:2; /* Max. length select */
9995 +       unsigned int pd:1;
9996 +       unsigned int pi:1;
9997 +       unsigned int psidx:4;
9998 +#else
9999 +       unsigned int psidx:4;
10000 +       unsigned int pi:1;
10001 +       unsigned int pd:1;
10002 +       unsigned int max_len:2; /* Max. length select */
10003 +       unsigned int pri:3;
10004 +       unsigned int fp:1;
10005 +       unsigned int dscp:6;
10006 +       unsigned int rd:1;
10007 +       unsigned int kv:1;
10008 +       unsigned int prs:2;
10009 +       unsigned int l2s:2; /* L2 select */
10010 +       unsigned int l4_prot:2;
10011 +       unsigned int rl:1;
10012 +       unsigned int ag:2;
10013 +       unsigned int sws:1;
10014 +       unsigned int s:1;
10015 +       unsigned int fw:1;
10016 +#endif
10017 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10018 +       unsigned int unused:16;
10019 +       unsigned int mac4732:16;
10020 +#else
10021 +       unsigned int mac4732:16;
10022 +       unsigned int unused:16;
10023 +#endif
10024 +       unsigned int mac3100;
10025 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10026 +       unsigned int lp:1;      
10027 +       unsigned int fr:1;
10028 +       unsigned int pm:4;
10029 +       unsigned int sv:1;
10030 +       unsigned int svid:12;
10031 +       unsigned int cv:1;      
10032 +       unsigned int cvid:12;
10033 +#else
10034 +       unsigned int cvid:12;
10035 +       unsigned int cv:1;      
10036 +       unsigned int svid:12;
10037 +       unsigned int sv:1;
10038 +       unsigned int pm:4;
10039 +       unsigned int fr:1;
10040 +       unsigned int lp:1;      
10041 +#endif
10042 +       unsigned int sip[4];
10043 +       unsigned int dip[4];
10044 +       union {
10045 +               struct {
10046 +                       unsigned short src;
10047 +                       unsigned short dst;
10048 +               } port;
10049 +               struct {
10050 +                       unsigned short call_id;
10051 +                       unsigned short nat_call_id;
10052 +               } gre;
10053 +               struct {
10054 +                       unsigned char protocol;
10055 +               } others;
10056 +       } l4;
10057 +       unsigned int nat_ip[4];
10058 +       unsigned short nat_port;
10059 +       SPPE_LIMIT limit;
10060 +       unsigned int pkt_cnt;
10061 +} SPPE_FLOW_NAT_IPV6;
10062 +
10063 +/*
10064 + * SPPE_CMD_FLOW_TWICE_NAT
10065 + * type = 0, as = 2
10066 + */
10067 +typedef struct _sppe_flow_twice_nat {
10068 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10069 +       unsigned int fw:1;
10070 +       unsigned int s:1;
10071 +       unsigned int sws:1;
10072 +       unsigned int ag:2;
10073 +       unsigned int rl:1;
10074 +       unsigned int l4_prot:2;
10075 +       unsigned int l2s:2; /* L2 select */
10076 +       unsigned int prs:2;
10077 +       unsigned int kv:1;
10078 +       unsigned int rd:1;
10079 +       unsigned int dscp:6;
10080 +       unsigned int fp:1;
10081 +       unsigned int pri:3;
10082 +       unsigned int max_len:2; /* Max. length select */
10083 +       unsigned int psidx:4;
10084 +       unsigned int reserved:2;
10085 +#else
10086 +       unsigned int reserved:2;
10087 +       unsigned int psidx:4;
10088 +       unsigned int max_len:2; /* Max. length select */
10089 +       unsigned int pri:3;
10090 +       unsigned int fp:1;
10091 +       unsigned int dscp:6;
10092 +       unsigned int rd:1;
10093 +       unsigned int kv:1;
10094 +       unsigned int prs:2;
10095 +       unsigned int l2s:2; /* L2 select */
10096 +       unsigned int l4_prot:2;
10097 +       unsigned int rl:1;
10098 +       unsigned int ag:2;
10099 +       unsigned int sws:1;
10100 +       unsigned int s:1;
10101 +       unsigned int fw:1;
10102 +#endif
10103 +       
10104 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10105 +       unsigned int unused:16;
10106 +       unsigned int mac4732:16;
10107 +#else
10108 +       unsigned int mac4732:16;
10109 +       unsigned int unused:16;
10110 +#endif
10111 +       unsigned int mac3100;
10112 +
10113 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10114 +       unsigned int lp:1;      
10115 +       unsigned int fr:1;
10116 +       unsigned int pm:4;
10117 +       unsigned int sv:1;
10118 +       unsigned int svid:12;
10119 +       unsigned int cv:1;      
10120 +       unsigned int cvid:12;
10121 +#else
10122 +       unsigned int cvid:12;
10123 +       unsigned int cv:1;      
10124 +       unsigned int svid:12;
10125 +       unsigned int sv:1;
10126 +       unsigned int pm:4;
10127 +       unsigned int fr:1;
10128 +       unsigned int lp:1;      
10129 +#endif
10130 +       unsigned int sip;
10131 +       unsigned int dip;
10132 +       unsigned short sport;
10133 +       unsigned short dport;
10134 +       unsigned int natsip;
10135 +       unsigned int natdip;
10136 +       unsigned short natsport;
10137 +       unsigned short natdport;
10138 +       SPPE_LIMIT limit;
10139 +       unsigned int pkt_cnt;
10140 +} SPPE_FLOW_TWICE_NAT;
10141 +
10142 +/*
10143 + * SPPE_CMD_FLOW_MULTICAST_IPV4
10144 + * type = 0, as = 0 or 3
10145 + */
10146 +typedef struct _sppe_flow_multicast_ipv4 {
10147 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10148 +       unsigned int fw:1;
10149 +       unsigned int s:1;
10150 +       unsigned int sws:1;
10151 +       unsigned int ag:2;
10152 +       unsigned int rl:1;
10153 +       unsigned int l2s:2; /* L2 select */
10154 +       unsigned int prs:2;
10155 +       unsigned int kv:1;
10156 +       unsigned int rd:1;
10157 +       unsigned int dscp:6;
10158 +       unsigned int fp:1;
10159 +       unsigned int pri:3;
10160 +       unsigned int max_len:2; /* Max. length select */
10161 +       unsigned int bridge:1;
10162 +       unsigned int reserved:7;
10163 +#else
10164 +       unsigned int reserved:7;
10165 +       unsigned int bridge:1;
10166 +       unsigned int max_len:2; /* Max. length select */
10167 +       unsigned int pri:3;
10168 +       unsigned int fp:1;
10169 +       unsigned int dscp:6;
10170 +       unsigned int rd:1;
10171 +       unsigned int kv:1;
10172 +       unsigned int prs:2;
10173 +       unsigned int l2s:2; /* L2 select */
10174 +       unsigned int rl:1;
10175 +       unsigned int ag:2;
10176 +       unsigned int sws:1;
10177 +       unsigned int s:1;
10178 +       unsigned int fw:1;
10179 +#endif
10180 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10181 +       unsigned int unused:16;
10182 +       unsigned int mac4732:16;
10183 +#else
10184 +       unsigned int mac4732:16;
10185 +       unsigned int unused:16;
10186 +#endif
10187 +       unsigned int mac3100;
10188 +
10189 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10190 +       unsigned int lp:1;      
10191 +       unsigned int fr:1;
10192 +       unsigned int pm:4;
10193 +       unsigned int sv:1;
10194 +       unsigned int svid:12;
10195 +       unsigned int cv:1;      
10196 +       unsigned int cvid:12;
10197 +#else
10198 +       unsigned int cvid:12;
10199 +       unsigned int cv:1;      
10200 +       unsigned int svid:12;
10201 +       unsigned int sv:1;
10202 +       unsigned int pm:4;
10203 +       unsigned int fr:1;
10204 +       unsigned int lp:1;      
10205 +#endif
10206 +
10207 +       unsigned int sip;
10208 +       unsigned int dip;
10209 +       SPPE_LIMIT limit;
10210 +       unsigned int pkt_cnt;
10211 +} SPPE_FLOW_MCAST_IPV4;
10212 +
10213 +/*
10214 + * SPPE_CMD_FLOW_MULTICAST_IPV6
10215 + * type = 1, as = 0 or 3
10216 + */
10217 +typedef struct _sppe_flow_multicast_ipv6 {
10218 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10219 +       unsigned int fw:1;
10220 +       unsigned int s:1;
10221 +       unsigned int sws:1;
10222 +       unsigned int ag:2;
10223 +       unsigned int rl:1;
10224 +       unsigned int l2s:2; /* L2 select */
10225 +       unsigned int prs:2;
10226 +       unsigned int kv:1;
10227 +       unsigned int rd:1;
10228 +       unsigned int dscp:6;
10229 +       unsigned int fp:1;
10230 +       unsigned int pri:3;
10231 +       unsigned int max_len:2; /* Max. length select */
10232 +       unsigned int bridge:1;
10233 +       unsigned int reserved:7;
10234 +#else
10235 +       unsigned int reserved:7;
10236 +       unsigned int bridge:1;
10237 +       unsigned int max_len:2; /* Max. length select */
10238 +       unsigned int pri:3;
10239 +       unsigned int fp:1;
10240 +       unsigned int dscp:6;
10241 +       unsigned int rd:1;
10242 +       unsigned int kv:1;
10243 +       unsigned int prs:2;
10244 +       unsigned int l2s:2; /* L2 select */
10245 +       unsigned int rl:1;
10246 +       unsigned int ag:2;
10247 +       unsigned int sws:1;
10248 +       unsigned int s:1;
10249 +       unsigned int fw:1;
10250 +#endif
10251 +       
10252 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10253 +       unsigned int unused:16;
10254 +       unsigned int mac4732:16;
10255 +#else
10256 +       unsigned int mac4732:16;
10257 +       unsigned int unused:16;
10258 +#endif
10259 +       unsigned int mac3100;
10260 +
10261 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10262 +       unsigned int lp:1;      
10263 +       unsigned int fr:1;
10264 +       unsigned int pm:4;
10265 +       unsigned int sv:1;
10266 +       unsigned int svid:12;
10267 +       unsigned int cv:1;      
10268 +       unsigned int cvid:12;
10269 +#else
10270 +       unsigned int cvid:12;
10271 +       unsigned int cv:1;      
10272 +       unsigned int svid:12;
10273 +       unsigned int sv:1;
10274 +       unsigned int pm:4;
10275 +       unsigned int fr:1;
10276 +       unsigned int lp:1;      
10277 +#endif
10278 +
10279 +       unsigned int sip[4];
10280 +       unsigned int dip[4];
10281 +       SPPE_LIMIT limit;
10282 +       unsigned int pkt_cnt;
10283 +} SPPE_FLOW_MCAST_IPV6;
10284 +
10285 +/* 
10286 + * SPPE_CMD_FLOW_LAYER_TWO
10287 + * type = 2
10288 + */
10289 +typedef struct _sppe_flow_bridge_l2 {
10290 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10291 +       unsigned int fw:1;
10292 +       unsigned int s:1;
10293 +       unsigned int sws:1;
10294 +       unsigned int ag:2;
10295 +       unsigned int rl:1;
10296 +       unsigned int l2_prot:2;
10297 +       unsigned int kv:1;
10298 +       unsigned int fp:1;
10299 +       unsigned int pri:3;
10300 +       unsigned int psidx:4;
10301 +       unsigned int reserved:15;
10302 +#else
10303 +       unsigned int reserved:15;
10304 +       unsigned int psidx:4;
10305 +       unsigned int pri:3;
10306 +       unsigned int fp:1;
10307 +       unsigned int kv:1;
10308 +       unsigned int l2_prot:2;
10309 +       unsigned int rl:1;
10310 +       unsigned int ag:2;
10311 +       unsigned int sws:1;
10312 +       unsigned int s:1;
10313 +       unsigned int fw:1;
10314 +#endif
10315 +
10316 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10317 +       unsigned int lp:1;      
10318 +       unsigned int fr:1;
10319 +       unsigned int pm:4;
10320 +       unsigned int sv:1;
10321 +       unsigned int svid:12;
10322 +       unsigned int cv:1;      
10323 +       unsigned int cvid:12;
10324 +#else
10325 +       unsigned int cvid:12;
10326 +       unsigned int cv:1;      
10327 +       unsigned int svid:12;
10328 +       unsigned int sv:1;
10329 +       unsigned int pm:4;
10330 +       unsigned int fr:1;
10331 +       unsigned int lp:1;      
10332 +#endif
10333 +
10334 +       unsigned short smac[3];
10335 +       unsigned short dmac[3];
10336 +       
10337 +       SPPE_LIMIT limit;
10338 +       unsigned int pkt_cnt;
10339 +} SPPE_FLOW_BRIDGE_L2;
10340 +
10341 +typedef struct _sppe_arl {
10342 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10343 +       unsigned int vid:12;
10344 +       unsigned int pmap:5;
10345 +       unsigned int age:3;
10346 +       unsigned int mymac:1;
10347 +       unsigned int filter:1;
10348 +       unsigned int reserved:10;
10349 +#else
10350 +       unsigned int reserved:10;
10351 +       unsigned int filter:1;
10352 +       unsigned int mymac:1;
10353 +       unsigned int age:3;
10354 +       unsigned int pmap:5;
10355 +       unsigned int vid:12;
10356 +#endif
10357 +       unsigned char mac[6];
10358 +} SPPE_ARL;
10359 +
10360 +typedef struct _sppe_init {
10361 +       unsigned int flow_pre_match_paddr;
10362 +       unsigned int flow_pre_match_vaddr;
10363 +       unsigned int flow_body_paddr;
10364 +       unsigned int flow_body_vaddr;
10365 +       unsigned int flow_ext_paddr;
10366 +       unsigned int flow_ext_vaddr;
10367 +       unsigned int flow_size;
10368 +       unsigned int arp_pre_match_paddr;
10369 +       unsigned int arp_pre_match_vaddr;
10370 +       unsigned int arp_body_paddr;
10371 +       unsigned int arp_body_vaddr;
10372 +       unsigned int arp_size;
10373 +       unsigned int ipv6_napt;
10374 +} SPPE_INIT;
10375 +
10376 +typedef struct _sppe_param_t {
10377 +       SPPE_CMD cmd;
10378 +       SPPE_OP op;
10379 +
10380 +       union {
10381 +               struct {
10382 +                       unsigned char major;
10383 +                       unsigned char minor;
10384 +                       unsigned char very_minor;
10385 +                       unsigned char pre;
10386 +               } sppe_version;
10387 +
10388 +               SPPE_BOOL sppe_enable;
10389 +               unsigned int sppe_lanip; 
10390 +
10391 +               struct {
10392 +                       unsigned int index;
10393 +                       unsigned int ip;
10394 +                       unsigned int session_id;
10395 +               } sppe_wanip;
10396 +
10397 +               struct {
10398 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10399 +                       unsigned int index:2;
10400 +                       unsigned int to:4;
10401 +                       unsigned int sv:1;
10402 +                       unsigned int stag_vid:12;
10403 +                       unsigned int cv:1;
10404 +                       unsigned int ctag_vid:12;
10405 +#else
10406 +                       unsigned int ctag_vid:12;
10407 +                       unsigned int cv:1;
10408 +                       unsigned int stag_vid:12;
10409 +                       unsigned int sv:1;
10410 +                       unsigned int to:4;
10411 +                       unsigned int index:2;
10412 +#endif
10413 +                       unsigned char mac[6]; /* MAC address */
10414 +               } sppe_prda;
10415 +
10416 +               struct {
10417 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10418 +                       unsigned int interval:2;
10419 +                       unsigned int mfactor:1;
10420 +                       unsigned int ununsed:29;
10421 +#else
10422 +                       unsigned int ununsed:29;
10423 +                       unsigned int mfactor:1;
10424 +                       unsigned int interval:2;
10425 +#endif
10426 +               } sppe_rlcfg;
10427 +
10428 +               struct {
10429 +                       unsigned int index;
10430 +                       SPPE_PPPOE_RELAY rule;
10431 +               } sppe_pppoe_relay;
10432 +               
10433 +               struct {
10434 +                       unsigned int index;
10435 +                       SPPE_BRIDGE rule;
10436 +               } sppe_bridge;
10437 +
10438 +               struct {
10439 +                       unsigned int index;
10440 +                       SPPE_ACL rule;
10441 +               } sppe_acl;
10442 +
10443 +               struct {
10444 +                       unsigned int index;
10445 +                       SPPE_ROUTE rule;
10446 +               } sppe_route;
10447 +#if 0
10448 +               struct {
10449 +                       unsigned int index;
10450 +                       SPPE_VSERVER rule;
10451 +               } sppe_vserver;
10452 +#else  
10453 +               struct {
10454 +                       unsigned int index;
10455 +                       SPPE_SNAT rule;
10456 +               } sppe_snat;
10457 +               
10458 +               struct {
10459 +                       unsigned int index;
10460 +                       SPPE_DNAT rule;
10461 +               } sppe_dnat;
10462 +#endif
10463 +               struct {
10464 +                       unsigned int index;
10465 +                       SPPE_GLOBAL_RATE_LIMIT rule;
10466 +               } sppe_grl;
10467 +
10468 +               struct {
10469 +                       unsigned char unit;
10470 +                       unsigned char arp;
10471 +                       unsigned char bridge;
10472 +                       unsigned char tcp;
10473 +                       unsigned char udp;
10474 +                       unsigned char pptp;
10475 +                       unsigned char other; 
10476 +               } sppe_agingout;
10477 +
10478 +               struct {
10479 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10480 +                       unsigned int index:2;
10481 +                       unsigned int reserved:20;
10482 +                       unsigned int max:10;
10483 +#else
10484 +                       unsigned int max:10;
10485 +                       unsigned int reserved:20;
10486 +                       unsigned int index:2;
10487 +#endif
10488 +               } sppe_max_length;
10489 +
10490 +               struct {
10491 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10492 +                       unsigned int v6:1;
10493 +                       unsigned int s:1;
10494 +                       unsigned int r:1;
10495 +                       unsigned int fr:1;
10496 +                       unsigned int to:4;
10497 +                       unsigned int unused:24;
10498 +#else
10499 +                       unsigned int unused:24;
10500 +                       unsigned int to:4;
10501 +                       unsigned int fr:1;
10502 +                       unsigned int r:1;
10503 +                       unsigned int s:1;
10504 +                       unsigned int v6:1;
10505 +#endif
10506 +
10507 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10508 +                       unsigned int sv:1;
10509 +                       unsigned int stag_vid:12;
10510 +                       unsigned int cv:1;
10511 +                       unsigned int ctag_vid:12;
10512 +                       unsigned int unused_1:6;
10513 +#else
10514 +                       unsigned int unused_1:6;
10515 +                       unsigned int ctag_vid:12;
10516 +                       unsigned int cv:1;
10517 +                       unsigned int stag_vid:12;
10518 +                       unsigned int sv:1;
10519 +#endif
10520 +                       unsigned int ip[4];
10521 +                       unsigned char mac[6];
10522 +               } sppe_arp;
10523 +
10524 +               SPPE_ARL sppe_arl;
10525 +
10526 +               struct {
10527 +                       unsigned int sid;
10528 +                       unsigned int index;
10529 +               } sppe_pppoe_sid;
10530 +
10531 +               SPPE_FLOW_BRIDGE_IPV4           flow_bridge_ipv4;
10532 +               SPPE_FLOW_BRIDGE_IPV6           flow_bridge_ipv6;
10533 +               SPPE_FLOW_ROUTE_IPV4            flow_route_ipv4;
10534 +               SPPE_FLOW_ROUTE_IPV6            flow_route_ipv6;
10535 +               SPPE_FLOW_NAT_IPV4                      flow_nat_ipv4;
10536 +               SPPE_FLOW_NAT_IPV6                      flow_nat_ipv6;
10537 +               SPPE_FLOW_TWICE_NAT                     flow_twice_nat;
10538 +               SPPE_FLOW_MCAST_IPV4            flow_mcast_ipv4;
10539 +               SPPE_FLOW_MCAST_IPV6            flow_mcast_ipv6;
10540 +               SPPE_FLOW_BRIDGE_L2                     flow_bridge_l2;
10541 +
10542 +               struct {
10543 +                       SPPE_DUMP_TYPE type;
10544 +                       unsigned short key;
10545 +                       unsigned short way;
10546 +                       unsigned int raw[23];
10547 +               } sppe_dump;
10548 +               
10549 +               unsigned int sppe_sna_th;
10550 +
10551 +               struct {
10552 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10553 +                       unsigned int enable:1;
10554 +                       unsigned int lan:6;
10555 +                       unsigned int wan:6;
10556 +                       unsigned int reserved:19;
10557 +#else
10558 +                       unsigned int reserved:19;
10559 +                       unsigned int wan:6;
10560 +                       unsigned int lan:6;
10561 +                       unsigned int enable:1;
10562 +#endif
10563 +               } sppe_chgdscp;
10564 +
10565 +               struct {
10566 +#ifndef CONFIG_SWITCH_BIG_ENDIAN
10567 +                       unsigned int enable:1;
10568 +                       unsigned int lan:3;
10569 +                       unsigned int wan:3;
10570 +                       unsigned int reserved:25;
10571 +#else
10572 +                       unsigned int reserved:25;
10573 +                       unsigned int wan:3;
10574 +                       unsigned int lan:3;
10575 +                       unsigned int enable:1;
10576 +#endif
10577 +               } sppe_chgpri;
10578 +
10579 +               struct {
10580 +                       int enable;
10581 +                       int module;
10582 +                       int level;
10583 +               } sppe_debug;
10584 +
10585 +               struct {
10586 +                       unsigned int offset;
10587 +                       unsigned int data;
10588 +               } sppe_reg;
10589 +
10590 +               struct {
10591 +                       unsigned int offset;
10592 +                       unsigned int data;
10593 +               } sppe_sram;
10594 +
10595 +               struct {
10596 +                       char enable;
10597 +                       unsigned int max;       
10598 +                       unsigned int min;
10599 +                       char drop_red;
10600 +                       char pass_green;
10601 +               } sppe_rl_flow;
10602 +
10603 +               struct {
10604 +                       char enable;
10605 +                       unsigned int max;       
10606 +                       unsigned int min;
10607 +                       char drop_red;
10608 +                       char pass_green;
10609 +               } sppe_rl_rule;
10610 +
10611 +               struct {
10612 +                       unsigned int index;
10613 +                       unsigned short start;
10614 +                       unsigned short end;
10615 +                       SPPE_LIMIT limit;
10616 +               } sppe_bm_flow;
10617 +
10618 +               struct {        
10619 +                       unsigned int index;
10620 +                       unsigned int pkt_cnt;
10621 +                       unsigned int byte_cnt;
10622 +               } sppe_accounting_group;
10623 +
10624 +               struct {
10625 +                       unsigned int pkt_cnt;
10626 +               } sppe_drop_ipcs_err; /* IP checksum error */
10627 +
10628 +               struct {
10629 +                       unsigned int pkt_cnt;
10630 +               } sppe_drop_rate_limit; 
10631 +
10632 +               struct {
10633 +                       unsigned int pkt_cnt;
10634 +               } sppe_drop_others;
10635 +
10636 +               struct {
10637 +                       unsigned int index;
10638 +                       unsigned char name[16];
10639 +                       struct net_device *dev;
10640 +                       unsigned int vid;
10641 +               } sppe_pci_fp_dev;
10642 +
10643 +               SPPE_INIT sppe_init;
10644 +
10645 +       } data;
10646 +} SPPE_PARAM;
10647 +
10648 +extern int sppe_hook_ready;
10649 +extern int (*sppe_func_hook)(SPPE_PARAM *param);
10650 +
10651 +extern int sppe_pci_fp_ready;
10652 +extern int (*sppe_pci_fp_hook)(SPPE_PARAM *param);
10653 +
10654 +#endif /* CONFIG_CNS3XXX_SPPE */
10655 +
10656 +#endif /* _SPPE_H_ */
10657 --- /dev/null
10658 +++ b/include/linux/cns3xxx/switch_api.h
10659 @@ -0,0 +1,366 @@
10660 +/*******************************************************************************
10661 + *
10662 + *   Copyright (c) 2008 Cavium Networks 
10663 + *
10664 + *   This program is free software; you can redistribute it and/or modify it
10665 + *   under the terms of the GNU General Public License as published by the Free
10666 + *   Software Foundation; either version 2 of the License, or (at your option)
10667 + *   any later version.
10668 + *
10669 + *   This program is distributed in the hope that it will be useful, but WITHOUT
10670 + *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10671 + *   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
10672 + *   more details.
10673 + *
10674 + *   You should have received a copy of the GNU General Public License along with
10675 + *   this program; if not, write to the Free Software Foundation, Inc., 59
10676 + *   Temple Place - Suite 330, Boston, MA  02111-1307, USA.
10677 + *
10678 + *   The full GNU General Public License is included in this distribution in the
10679 + *   file called LICENSE.
10680 + *
10681 + *   Contact Information:
10682 + *   Technology Support <tech@starsemi.com>
10683 + *   Star Semiconductor 4F, No.1, Chin-Shan 8th St, Hsin-Chu,300 Taiwan, R.O.C
10684 + *
10685 + ********************************************************************************/
10686 +
10687 +#ifndef SWITCH_API_H_K
10688 +#define SWITCH_API_H_K
10689 +
10690 +
10691 +#ifndef __KERNEL__
10692 +typedef unsigned int u32;
10693 +typedef unsigned short int u16;
10694 +typedef unsigned char u8;
10695 +typedef int s32;
10696 +#else
10697 +
10698 +#include <linux/types.h>
10699 +
10700 +#endif
10701 +
10702 +
10703 +#define CAVM_OK 0
10704 +#define CAVM_ERR 1
10705 +#define CAVM_NOT_FOUND 2
10706 +#define CAVM_FOUND 3
10707 +#define CAVM_FAIL -1 // use minus 
10708 +
10709 +#define MAC_PORT0 0
10710 +#define MAC_PORT1 1
10711 +#define MAC_PORT2 2
10712 +#define CPU_PORT 3
10713 +
10714 +typedef enum 
10715 +{
10716 +
10717 +
10718 +       CNS3XXX_ARL_TABLE_LOOKUP,
10719 +       CNS3XXX_ARL_TABLE_ADD,
10720 +       CNS3XXX_ARL_TABLE_DEL,
10721 +       CNS3XXX_ARL_TABLE_SEARCH,
10722 +       CNS3XXX_ARL_TABLE_SEARCH_AGAIN,
10723 +       CNS3XXX_ARL_IS_TABLE_END,
10724 +       CNS3XXX_ARL_TABLE_FLUSH,
10725 +
10726 +       CNS3XXX_VLAN_TABLE_LOOKUP,
10727 +       CNS3XXX_VLAN_TABLE_ADD,
10728 +       CNS3XXX_VLAN_TABLE_DEL,
10729 +       CNS3XXX_VLAN_TABLE_READ,
10730 +
10731 +       CNS3XXX_SKEW_SET,
10732 +       CNS3XXX_SKEW_GET,
10733 +
10734 +       CNS3XXX_BRIDGE_SET,
10735 +       CNS3XXX_BRIDGE_GET,
10736 +
10737 +       CNS3XXX_PORT_NEIGHBOR_SET,
10738 +       CNS3XXX_PORT_NEIGHBOR_GET,
10739 +
10740 +       CNS3XXX_HOL_PREVENT_SET,
10741 +       CNS3XXX_HOL_PREVENT_GET,
10742 +
10743 +       CNS3XXX_TC_SET, // traffic class, for 1, 2, 4, traffic class
10744 +       CNS3XXX_TC_GET,
10745 +
10746 +       CNS3XXX_PRI_CTRL_SET,
10747 +       CNS3XXX_PRI_CTRL_GET,
10748 +
10749 +       CNS3XXX_DMA_RING_CTRL_SET,
10750 +       CNS3XXX_DMA_RING_CTRL_GET,
10751 +
10752 +       CNS3XXX_PRI_IP_DSCP_SET,
10753 +       CNS3XXX_PRI_IP_DSCP_GET,
10754 +
10755 +       CNS3XXX_ETYPE_SET,
10756 +       CNS3XXX_ETYPE_GET,
10757 +
10758 +       CNS3XXX_UDP_RANGE_SET,
10759 +       CNS3XXX_UDP_RANGE_GET,
10760 +
10761 +       CNS3XXX_ARP_REQUEST_SET,
10762 +       CNS3XXX_ARP_REQUEST_GET,
10763 +
10764 +       CNS3XXX_RATE_LIMIT_SET,
10765 +       CNS3XXX_RATE_LIMIT_GET,
10766 +
10767 +       CNS3XXX_QUEUE_WEIGHT_SET,
10768 +       CNS3XXX_QUEUE_WEIGHT_GET,
10769 +
10770 +       CNS3XXX_FC_RLS_SET,
10771 +       CNS3XXX_FC_RLS_GET,
10772 +
10773 +       CNS3XXX_FC_SET_SET,
10774 +       CNS3XXX_FC_SET_GET,
10775 +
10776 +       CNS3XXX_SARL_RLS_SET,
10777 +       CNS3XXX_SARL_RLS_GET,
10778 +
10779 +       CNS3XXX_SARL_SET_SET,
10780 +       CNS3XXX_SARL_SET_GET,
10781 +
10782 +       CNS3XXX_SARL_OQ_SET,
10783 +       CNS3XXX_SARL_OQ_GET,
10784 +
10785 +       CNS3XXX_SARL_ENABLE_SET,
10786 +       CNS3XXX_SARL_ENABLE_GET,
10787 +
10788 +       CNS3XXX_FC_SET,
10789 +       CNS3XXX_FC_GET,
10790 +
10791 +       CNS3XXX_IVL_SET,
10792 +       CNS3XXX_IVL_GET,
10793 +
10794 +       CNS3XXX_WAN_PORT_SET,
10795 +       CNS3XXX_WAN_PORT_GET,
10796 +
10797 +       CNS3XXX_PVID_GET,
10798 +       CNS3XXX_PVID_SET,
10799 +
10800 +       CNS3XXX_QA_GET, // queue allocate
10801 +       CNS3XXX_QA_SET,
10802 +
10803 +       CNS3XXX_PACKET_MAX_LEN_GET, // set maximun frame length.
10804 +       CNS3XXX_PACKET_MAX_LEN_SET,
10805 +
10806 +       CNS3XXX_BCM53115M_REG_READ,
10807 +       CNS3XXX_BCM53115M_REG_WRITE,
10808 +
10809 +       CNS3XXX_RXRING_STATUS,
10810 +       CNS3XXX_TXRING_STATUS,
10811 +
10812 +       CNS3XXX_DUMP_MIB_COUNTER,
10813 +
10814 +       CNS3XXX_REG_READ,
10815 +       CNS3XXX_REG_WRITE,
10816 +
10817 +}CNS3XXXIoctlCmd;
10818 +
10819 +typedef struct
10820 +{
10821 +       u8 vlan_index;
10822 +       u8 valid;
10823 +       u16 vid;
10824 +       u8 wan_side;
10825 +       u8 etag_pmap;
10826 +       u8 mb_pmap;
10827 +       //u8 my_mac[6];
10828 +       u8 *my_mac;
10829 +}VLANTableEntry; // for vlan table function
10830 +
10831 +typedef struct
10832 +{
10833 +       u16 vid;
10834 +       u8 pmap;
10835 +       //u8 mac[6];
10836 +       u8 *mac;
10837 +       u8 age_field;
10838 +       u8 vlan_mac;
10839 +       u8 filter;
10840 +}ARLTableEntry; // for arl table function
10841 +
10842 +
10843 +typedef struct 
10844 +{
10845 +       CNS3XXXIoctlCmd cmd;
10846 +       ARLTableEntry entry;
10847 +}CNS3XXXARLTableEntry; // for ioctl arl ...
10848 +
10849 +typedef struct 
10850 +{
10851 +       CNS3XXXIoctlCmd cmd;
10852 +       VLANTableEntry entry;
10853 +}CNS3XXXVLANTableEntry; // for ioctl VLAN table ...
10854 +
10855 +typedef struct 
10856 +{
10857 +       CNS3XXXIoctlCmd cmd;
10858 +       u8 enable;
10859 +}CNS3XXXHOLPreventControl; 
10860 +
10861 +
10862 +typedef struct 
10863 +{
10864 +       CNS3XXXIoctlCmd cmd;
10865 +       unsigned char which_port; // 0, 1, 2, 3 (cpu port)
10866 +       unsigned char type; // 0: C-Neighbor, 1: S-Neighbor
10867 +}CNS3XXXPortNeighborControl;
10868 +
10869 +typedef struct 
10870 +{
10871 +       CNS3XXXIoctlCmd cmd;
10872 +       unsigned char type; // 0: C-Component, 1: S-Component
10873 +}CNS3XXXBridgeControl;
10874 +
10875 +typedef struct 
10876 +{
10877 +       CNS3XXXIoctlCmd cmd;
10878 +       unsigned char tc; // traffic class, for 1, 2, 4, traffic class
10879 +}CNS3XXXTrafficClassControl;
10880 +
10881 +typedef struct 
10882 +{
10883 +       CNS3XXXIoctlCmd cmd;
10884 +       unsigned char which_port; // 0, 1, 2, 3 (cpu port)
10885 +       unsigned int val;
10886 +       unsigned char port_pri;
10887 +       unsigned char udp_pri_en;
10888 +       unsigned char dscp_pri_en;
10889 +       unsigned char vlan_pri_en;
10890 +       unsigned char ether_pri_en;
10891 +}CNS3XXXPriCtrlControl;
10892 +
10893 +typedef struct 
10894 +{
10895 +       CNS3XXXIoctlCmd cmd;
10896 +       unsigned char ts_double_ring_en;
10897 +       unsigned char fs_double_ring_en;
10898 +       unsigned char fs_pkt_allocate;
10899 +}CNS3XXXDmaRingCtrlControl;
10900 +
10901 +typedef struct 
10902 +{
10903 +       CNS3XXXIoctlCmd cmd;
10904 +       unsigned int ip_dscp_num; // 0 ~ 63
10905 +       unsigned char pri; // 3 bits
10906 +}CNS3XXXPriIpDscpControl;
10907 +
10908 +typedef struct 
10909 +{
10910 +       CNS3XXXIoctlCmd cmd;
10911 +       unsigned int etype_num;
10912 +       unsigned int val;
10913 +       unsigned int pri;
10914 +}CNS3XXXEtypeControl;
10915 +
10916 +typedef struct 
10917 +{
10918 +       CNS3XXXIoctlCmd cmd;
10919 +       unsigned int udp_range_num;
10920 +       unsigned short int port_start;
10921 +       unsigned short int port_end;
10922 +}CNS3XXXUdpRangeEtypeControl;
10923 +
10924 +typedef struct 
10925 +{
10926 +       CNS3XXXIoctlCmd cmd;
10927 +       unsigned char val; // 0: boradcast forward, 1: redirect to the CPU
10928 +}CNS3XXXArpRequestControl;
10929 +
10930 +typedef struct 
10931 +{
10932 +       CNS3XXXIoctlCmd cmd;
10933 +       unsigned char which_port; // 0, 1, 2, 3 (port 0 extra dma)
10934 +       unsigned char band_width;
10935 +       unsigned char base_rate;
10936 +       
10937 +}CNS3XXXRateLimitEntry; // for ioctl arl ...
10938 +
10939 +typedef struct 
10940 +{
10941 +       CNS3XXXIoctlCmd cmd;
10942 +       unsigned char which_port; // 0, 1, 2, 3 (port 0 extra dma)
10943 +       unsigned char sch_mode;
10944 +       unsigned char q0_w;
10945 +       unsigned char q1_w;
10946 +       unsigned char q2_w;
10947 +       unsigned char q3_w;
10948 +}CNS3XXXQueueWeightEntry; // for ioctl arl ...
10949 +
10950 +typedef struct 
10951 +{
10952 +       CNS3XXXIoctlCmd cmd;
10953 +       unsigned int val;
10954 +       unsigned char tc; // 0-3
10955 +       unsigned char gyr; // 0 (green), 1(yellow), 2(red)
10956 +}CNS3XXXSARLEntry; // for ioctl arl ...
10957 +
10958 +typedef struct 
10959 +{
10960 +       CNS3XXXIoctlCmd cmd;
10961 +       unsigned char port; // 0, 1, 2, 3 (cpu port)
10962 +       unsigned char fc_en; // 0(rx/tx disable), 1(rx enable), 2(tx enable), 3(rx/tx enable)
10963 +}CNS3XXXFCEntry; // for ioctl arl ...
10964 +
10965 +typedef struct 
10966 +{
10967 +       CNS3XXXIoctlCmd cmd;
10968 +       unsigned char enable; // enable: 1 -> IVL, enable: 0 -> SVL
10969 +}CNS3XXXIVLEntry; // for ioctl arl ...
10970 +
10971 +typedef struct 
10972 +{
10973 +       CNS3XXXIoctlCmd cmd;
10974 +       unsigned char wan_port;
10975 +}CNS3XXXWANPortEntry; // for ioctl arl ...
10976 +
10977 +typedef struct 
10978 +{
10979 +       CNS3XXXIoctlCmd cmd;
10980 +       unsigned char which_port;
10981 +       unsigned int pvid;
10982 +}CNS3XXXPVIDEntry; // for ioctl arl ...
10983 +
10984 +typedef struct 
10985 +{
10986 +       CNS3XXXIoctlCmd cmd;
10987 +       unsigned char qa; // queue allocate
10988 +}CNS3XXXQAEntry; // for ioctl arl ...
10989 +
10990 +typedef struct 
10991 +{
10992 +       CNS3XXXIoctlCmd cmd;
10993 +       unsigned char max_len; // maximum frame length
10994 +}CNS3XXXMaxLenEntry; // for ioctl arl ...
10995 +
10996 +typedef struct 
10997 +{
10998 +       CNS3XXXIoctlCmd cmd;
10999 +       u8 page;
11000 +       u8 offset;
11001 +       u32 u32_val;
11002 +       u16 u16_val;
11003 +       u8 u8_val;
11004 +       u8 data_len;
11005 +
11006 +}CNS3XXXBCM53115M; 
11007 +
11008 +typedef struct 
11009 +{
11010 +       CNS3XXXIoctlCmd cmd;
11011 +       u32 mib[52];
11012 +       u16 mib_len;
11013 +}CNS3XXXMIBCounter;
11014 +
11015 +#if 0
11016 +typedef struct 
11017 +{
11018 +       CNS3XXXIoctlCmd cmd;
11019 +        TXRing *tx_ring;
11020 +        RXRing *rx_ring;
11021 +}CNS3XXXRingStatus; 
11022 +#endif
11023 +
11024 +
11025 +#endif
11026 --- a/net/core/dev.c
11027 +++ b/net/core/dev.c
11028 @@ -133,6 +133,10 @@
11029  
11030  #include "net-sysfs.h"
11031  
11032 +#if defined (CONFIG_CNS3XXX_SPPE)
11033 +#include <linux/cns3xxx/sppe.h>
11034 +#endif
11035 +
11036  /* Instead of increasing this, you should create a hash table. */
11037  #define MAX_GRO_SKBS 8
11038  
11039 @@ -1944,6 +1948,197 @@ int weight_p __read_mostly = 64;        
11040  
11041  DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
11042  
11043 +#if defined (CONFIG_CNS3XXX_SPPE)
11044 +static struct net_device *tun_netdev = NULL;
11045 +
11046 +int sppe_pci_fp(struct sk_buff *skb)
11047 +{
11048 +       SPPE_PARAM param;
11049 +       struct iphdr *iph;
11050 +#if defined (CONFIG_IPV6)
11051 +       struct ipv6hdr *ipv6h;
11052 +#endif
11053 +       struct tcphdr *th;
11054 +       struct udphdr *uh;
11055 +       int pci_dev_index;
11056 +
11057 +       if (!sppe_hook_ready) {
11058 +               goto NOT_IN_FP;
11059 +       }
11060 +
11061 +       if (!sppe_pci_fp_ready) {
11062 +               goto NOT_IN_FP;
11063 +       }
11064 +
11065 +       /* check device packet comes from, is a registed device? */
11066 +       memset(&param, 0, sizeof(SPPE_PARAM));
11067 +       param.cmd = SPPE_CMD_PCI_FP_DEV;
11068 +       param.op = SPPE_OP_GET;
11069 +       param.data.sppe_pci_fp_dev.dev = skb->dev;
11070 +       sppe_pci_fp_hook(&param);
11071 +
11072 +       pci_dev_index = param.data.sppe_pci_fp_dev.index;
11073 +
11074 +       if ((-1) == pci_dev_index) {
11075 +               goto NOT_IN_FP;
11076 +       }
11077 +
11078 +       if (!tun_netdev) {
11079 +               tun_netdev = dev_get_by_name(&init_net, "fp");
11080 +
11081 +               if (!tun_netdev) {
11082 +                       goto NOT_IN_FP;
11083 +               }
11084 +       }
11085 +
11086 +       /* check PPE status */
11087 +       memset(&param, 0, sizeof(SPPE_PARAM));
11088 +       param.cmd = SPPE_CMD_ENABLE;
11089 +       param.op = SPPE_OP_GET;
11090 +
11091 +       if (sppe_func_hook(&param)) {
11092 +               printk("<0><%s> fail to get PPE status!!\n", __FUNCTION__);
11093 +               goto NOT_IN_FP;
11094 +       }
11095 +
11096 +       if (!param.data.sppe_enable) {
11097 +               goto NOT_IN_FP;
11098 +       }
11099 +
11100 +       memset(&param, 0, sizeof(SPPE_PARAM));
11101 +
11102 +       switch (htons(skb->protocol)) {
11103 +       case ETH_P_IP:
11104 +               iph = (struct iphdr *)skb->data;
11105 +
11106 +               if (5 != iph->ihl) { goto NOT_IN_FP; }
11107 +
11108 +               if (iph->frag_off & 0x20) { goto NOT_IN_FP; }
11109 +
11110 +               param.cmd = SPPE_CMD_FLOW_NAT_IPV4;
11111 +               param.op = SPPE_OP_GET;
11112 +
11113 +               param.data.flow_nat_ipv4.sip = ntohl(iph->saddr);
11114 +               param.data.flow_nat_ipv4.dip = ntohl(iph->daddr);
11115 +
11116 +               switch (iph->protocol) {
11117 +               case IPPROTO_TCP:
11118 +                       th = (struct tcphdr *) ((int *)iph + 5); /* IP header length is 20 */
11119 +
11120 +                       if ((th->syn) || (th->fin) || (th->rst)) { goto NOT_IN_FP; }
11121 +
11122 +                       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_TCP;
11123 +                       param.data.flow_nat_ipv4.l4.port.src = ntohs(th->source);
11124 +                       param.data.flow_nat_ipv4.l4.port.dst = ntohs(th->dest);
11125 +                       break;
11126 +               case IPPROTO_UDP:
11127 +                       uh = (struct udphdr *) ((int *)iph + 5); /* IP header length is 20 */
11128 +                       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_UDP;
11129 +                       param.data.flow_nat_ipv4.l4.port.src = ntohs(uh->source);
11130 +                       param.data.flow_nat_ipv4.l4.port.dst = ntohs(uh->dest);
11131 +                       break;
11132 +               default:
11133 +                       goto NOT_IN_FP;
11134 +               }
11135 +
11136 +               if (SPPE_RESULT_SUCCESS != sppe_func_hook(&param)) {
11137 +                       goto NOT_IN_FP;
11138 +               } else {
11139 +                       struct ethhdr *eth;
11140 +
11141 +                       eth = (struct ethhdr *)skb->mac_header;
11142 +
11143 +                       memset(&param, 0, sizeof(SPPE_PARAM));
11144 +                       param.cmd = SPPE_CMD_ARP;
11145 +                       param.op = SPPE_OP_SET;
11146 +                       param.data.sppe_arp.s = 1;
11147 +                       param.data.sppe_arp.ip[0] = iph->saddr;
11148 +                       param.data.sppe_arp.mac[0] = eth->h_source[0];
11149 +                       param.data.sppe_arp.mac[1] = eth->h_source[1];
11150 +                       param.data.sppe_arp.mac[2] = eth->h_source[2];
11151 +                       param.data.sppe_arp.mac[3] = eth->h_source[3];
11152 +                       param.data.sppe_arp.mac[4] = eth->h_source[4];
11153 +                       param.data.sppe_arp.mac[5] = eth->h_source[5];
11154 +                       param.data.sppe_arp.unused_1 = pci_dev_index;
11155 +
11156 +                       if (SPPE_RESULT_SUCCESS != sppe_func_hook(&param)) {
11157 +                               printk("add ARP fail\n");
11158 +                       #if 0
11159 +                       } else {
11160 +                               param.data.sppe_arp.unused_1 = 0xf;
11161 +                               param.op = SPPE_OP_GET;
11162 +                               if (SPPE_RESULT_SUCCESS != sppe_func_hook(&param)) {
11163 +                               printk("read ARP fail\n");
11164 +                       } else {
11165 +                               printk("param.data.sppe_arp.unused_1 %d\n", param.data.sppe_arp.unused_1);
11166 +                       }
11167 +                       #endif
11168 +                       }
11169 +               }
11170 +               break; /* case ETH_P_IP: */
11171 +#if defined (CONFIG_IPV6)
11172 +       case ETH_P_IPV6:
11173 +               ipv6h = (struct ipv6hdr *)skb->data;
11174 +               switch (ipv6h->nexthdr) {
11175 +               case IPPROTO_TCP:
11176 +                       th = (struct tcphdr *) ((int *)ipv6h + 10); /* IPv6 header length is 40 bytes */
11177 +
11178 +                       if ((th->syn) || (th->fin) || (th->rst)) { goto NOT_IN_FP; }
11179 +
11180 +                       param.data.flow_route_ipv6.l4_prot = SPPE_PROT_TCP;
11181 +                       param.data.flow_route_ipv6.l4.port.src = ntohs(th->source);
11182 +                       param.data.flow_route_ipv6.l4.port.dst = ntohs(th->dest);
11183 +                       param.data.flow_route_ipv6.l4_prot = SPPE_PROT_TCP;
11184 +                       break;
11185 +               case IPPROTO_UDP:
11186 +                       uh = (struct udphdr *) ((int *)ipv6h + 10); /* IPv6 header length is 40 byte */
11187 +                       param.data.flow_route_ipv6.l4_prot = SPPE_PROT_UDP;
11188 +                       param.data.flow_route_ipv6.l4.port.src = ntohs(uh->source);
11189 +                       param.data.flow_route_ipv6.l4.port.dst = ntohs(uh->dest);
11190 +                       break;
11191 +               default:
11192 +                       goto NOT_IN_FP;
11193 +               }
11194 +
11195 +               param.data.flow_route_ipv6.sip[0] = ntohl(ipv6h->saddr.s6_addr32[0]);
11196 +               param.data.flow_route_ipv6.sip[1] = ntohl(ipv6h->saddr.s6_addr32[1]);
11197 +               param.data.flow_route_ipv6.sip[2] = ntohl(ipv6h->saddr.s6_addr32[2]);
11198 +               param.data.flow_route_ipv6.sip[3] = ntohl(ipv6h->saddr.s6_addr32[3]);
11199 +               param.data.flow_route_ipv6.dip[0] = ntohl(ipv6h->daddr.s6_addr32[0]);
11200 +               param.data.flow_route_ipv6.dip[1] = ntohl(ipv6h->daddr.s6_addr32[1]);
11201 +               param.data.flow_route_ipv6.dip[2] = ntohl(ipv6h->daddr.s6_addr32[2]);
11202 +               param.data.flow_route_ipv6.dip[3] = ntohl(ipv6h->daddr.s6_addr32[3]);
11203 +
11204 +               param.cmd = SPPE_CMD_FLOW_ROUTE_IPV6;
11205 +               param.op = SPPE_OP_GET;
11206 +
11207 +               if (SPPE_RESULT_SUCCESS != sppe_func_hook(&param)) {
11208 +                       goto NOT_IN_FP;
11209 +               }
11210 +
11211 +               break; /* case ETH_P_IPV6: */
11212 +#endif
11213 +       case ETH_P_PPP_SES:
11214 +               break;
11215 +       default: /* unsupport protocol */
11216 +               goto NOT_IN_FP;
11217 +       }
11218 +       /* Update counter */
11219 +       skb->dev = tun_netdev;
11220 +       skb->ip_summed = CHECKSUM_NONE;
11221 +       skb_push(skb, ETH_HLEN);
11222 +
11223 +       dev_queue_xmit(skb);
11224 +
11225 +return 0;
11226 +
11227 +NOT_IN_FP:
11228 +       return (-1);
11229 +}
11230 +#endif
11231 +
11232 +
11233 +
11234  
11235  /**
11236   *     netif_rx        -       post buffer to the network code
11237 @@ -1965,6 +2160,12 @@ int netif_rx(struct sk_buff *skb)
11238         struct softnet_data *queue;
11239         unsigned long flags;
11240  
11241 +#if defined (CONFIG_CNS3XXX_SPPE)
11242 +       if (0 == sppe_pci_fp(skb)) {
11243 +               return NET_RX_SUCCESS;
11244 +       }
11245 +#endif
11246 +
11247         /* if netpoll wants it, pretend we never saw it */
11248         if (netpoll_rx(skb))
11249                 return NET_RX_DROP;
11250 @@ -2259,6 +2460,12 @@ int netif_receive_skb(struct sk_buff *sk
11251         if (!skb->tstamp.tv64)
11252                 net_timestamp(skb);
11253  
11254 +#if defined (CONFIG_CNS3XXX_SPPE)
11255 +    if (0 == sppe_pci_fp(skb)) {
11256 +        return NET_RX_SUCCESS;
11257 +    }
11258 +#endif
11259 +
11260         if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
11261                 return NET_RX_SUCCESS;
11262  
11263 --- a/net/netfilter/nf_conntrack_core.c
11264 +++ b/net/netfilter/nf_conntrack_core.c
11265 @@ -42,6 +42,9 @@
11266  #include <net/netfilter/nf_conntrack_ecache.h>
11267  #include <net/netfilter/nf_nat.h>
11268  #include <net/netfilter/nf_nat_core.h>
11269 +#if defined (CONFIG_CNS3XXX_SPPE)
11270 +#include <linux/cns3xxx/sppe.h>
11271 +#endif
11272  
11273  #define NF_CONNTRACK_VERSION   "0.5.0"
11274  
11275 @@ -275,6 +278,92 @@ void nf_ct_insert_dying_list(struct nf_c
11276  }
11277  EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list);
11278  
11279 +#if defined (CONFIG_CNS3XXX_SPPE)
11280 +static int sppe_flow_del(struct nf_conn *ct)
11281 +{
11282 +       if (sppe_hook_ready) {
11283 +               SPPE_PARAM param;
11284 +
11285 +               struct nf_conntrack_tuple *orig, *reply;
11286 +
11287 +               orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11288 +               reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11289 +
11290 +               if (PF_INET == orig->src.l3num) {
11291 +                       param.cmd = SPPE_CMD_FLOW_NAT_IPV4;
11292 +               } else if (PF_INET6 == orig->src.l3num) {
11293 +                       param.cmd = SPPE_CMD_FLOW_ROUTE_IPV6;
11294 +               } else {
11295 +                       goto SPPE_FLOW_DEL_FINI;
11296 +               }
11297 +
11298 +               if (IPPROTO_TCP == orig->dst.protonum) {
11299 +                       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_TCP;
11300 +               } else if (IPPROTO_UDP == orig->dst.protonum) {
11301 +                       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_UDP;
11302 +               } else if (IPPROTO_GRE == orig->dst.protonum) {
11303 +                       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_PPTP_GRE;
11304 +               } else {
11305 +                       goto SPPE_FLOW_DEL_FINI;
11306 +               }
11307 +               
11308 +               param.op = SPPE_OP_DELETE_OUTDATED;
11309 +
11310 +               param.data.flow_nat_ipv4.fw = 0;
11311 +               if (SPPE_CMD_FLOW_ROUTE_IPV6 == param.cmd) {
11312 +                       param.data.flow_route_ipv6.sip[0] = htonl(orig->src.u3.ip6[0]);
11313 +                       param.data.flow_route_ipv6.sip[1] = htonl(orig->src.u3.ip6[1]);
11314 +                       param.data.flow_route_ipv6.sip[2] = htonl(orig->src.u3.ip6[2]);
11315 +                       param.data.flow_route_ipv6.sip[3] = htonl(orig->src.u3.ip6[3]);
11316 +                       param.data.flow_route_ipv6.dip[0] = htonl(orig->dst.u3.ip6[0]);
11317 +                       param.data.flow_route_ipv6.dip[1] = htonl(orig->dst.u3.ip6[1]);
11318 +                       param.data.flow_route_ipv6.dip[2] = htonl(orig->dst.u3.ip6[2]);
11319 +                       param.data.flow_route_ipv6.dip[3] = htonl(orig->dst.u3.ip6[3]);
11320 +                       param.data.flow_route_ipv6.l4.port.src = htons(orig->src.u.tcp.port);
11321 +                       param.data.flow_route_ipv6.l4.port.dst = htons(orig->dst.u.tcp.port);
11322 +               } else {
11323 +                       param.data.flow_nat_ipv4.sip = htonl(orig->src.u3.ip);
11324 +                       param.data.flow_nat_ipv4.dip = htonl(orig->dst.u3.ip);
11325 +                       param.data.flow_nat_ipv4.l4.port.src = htons(orig->src.u.tcp.port);
11326 +                       param.data.flow_nat_ipv4.l4.port.dst = htons(orig->dst.u.tcp.port);
11327 +               }
11328 +
11329 +               if (SPPE_RESULT_FAIL == sppe_func_hook(&param)) {
11330 +                       return (-1);
11331 +               }
11332 +               
11333 +               param.data.flow_nat_ipv4.fw = 1;
11334 +
11335 +               if (SPPE_CMD_FLOW_ROUTE_IPV6 == param.cmd) {
11336 +                       param.data.flow_route_ipv6.sip[0] = htonl(reply->src.u3.ip6[0]);
11337 +                       param.data.flow_route_ipv6.sip[1] = htonl(reply->src.u3.ip6[1]);
11338 +                       param.data.flow_route_ipv6.sip[2] = htonl(reply->src.u3.ip6[2]);
11339 +                       param.data.flow_route_ipv6.sip[3] = htonl(reply->src.u3.ip6[3]);
11340 +                       param.data.flow_route_ipv6.dip[0] = htonl(reply->dst.u3.ip6[0]);
11341 +                       param.data.flow_route_ipv6.dip[1] = htonl(reply->dst.u3.ip6[1]);
11342 +                       param.data.flow_route_ipv6.dip[2] = htonl(reply->dst.u3.ip6[2]);
11343 +                       param.data.flow_route_ipv6.dip[3] = htonl(reply->dst.u3.ip6[3]);
11344 +
11345 +                       param.data.flow_route_ipv6.l4.port.src = htons(reply->src.u.tcp.port);
11346 +                       param.data.flow_route_ipv6.l4.port.dst = htons(reply->dst.u.tcp.port);
11347 +               } else {
11348 +                       param.data.flow_nat_ipv4.sip = htonl(reply->src.u3.ip);
11349 +                       param.data.flow_nat_ipv4.dip = htonl(reply->dst.u3.ip);
11350 +                       param.data.flow_nat_ipv4.l4.port.src = htons(reply->src.u.tcp.port);
11351 +                       param.data.flow_nat_ipv4.l4.port.dst = htons(reply->dst.u.tcp.port);
11352 +               }
11353 +
11354 +               if (SPPE_RESULT_FAIL == sppe_func_hook(&param)) {
11355 +                       return (-1);
11356 +               }
11357 +       }
11358 +
11359 +SPPE_FLOW_DEL_FINI:
11360 +       return 0;
11361 +}
11362 +#endif
11363 +
11364 +
11365  static void death_by_timeout(unsigned long ul_conntrack)
11366  {
11367         struct nf_conn *ct = (void *)ul_conntrack;
11368 @@ -289,6 +378,16 @@ static void death_by_timeout(unsigned lo
11369         set_bit(IPS_DYING_BIT, &ct->status);
11370         nf_ct_delete_from_lists(ct);
11371         nf_ct_put(ct);
11372 +
11373 +#if defined (CONFIG_CNS3XXX_SPPE)
11374 +       if (sppe_flow_del(ct)) {
11375 +               #if 0
11376 +               ct->timeout.expires = jiffies + (120*HZ);
11377 +               add_timer(&ct->timeout);
11378 +               #endif
11379 +       }
11380 +#endif
11381 +
11382  }
11383  
11384  /*
11385 --- a/net/netfilter/nf_conntrack_proto_gre.c
11386 +++ b/net/netfilter/nf_conntrack_proto_gre.c
11387 @@ -40,6 +40,10 @@
11388  #include <linux/netfilter/nf_conntrack_proto_gre.h>
11389  #include <linux/netfilter/nf_conntrack_pptp.h>
11390  
11391 +#if defined (CONFIG_CNS3XXX_SPPE)
11392 +#include <linux/cns3xxx/sppe.h>
11393 +#endif
11394 +
11395  #define GRE_TIMEOUT            (30 * HZ)
11396  #define GRE_STREAM_TIMEOUT     (180 * HZ)
11397  
11398 @@ -226,6 +230,57 @@ static int gre_print_conntrack(struct se
11399                           (ct->proto.gre.stream_timeout / HZ));
11400  }
11401  
11402 +#if defined (CONFIG_CNS3XXX_SPPE)
11403 +static int sppe_gre_flow_add(struct nf_conn *ct)
11404 +{
11405 +       SPPE_PARAM param;
11406 +       struct nf_conntrack_tuple *orig, *reply;
11407 +
11408 +       if (0 == sppe_hook_ready) {
11409 +               return 0;
11410 +       }
11411 +
11412 +       memset(&param, 0, sizeof(SPPE_PARAM));
11413 +
11414 +       orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11415 +       reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11416 +
11417 +       param.cmd = SPPE_CMD_FLOW_NAT_IPV4;
11418 +       param.op = SPPE_OP_SET;
11419 +
11420 +       param.data.flow_nat_ipv4.fw = 0;
11421 +       param.data.flow_nat_ipv4.sip = htonl(orig->src.u3.ip);
11422 +       param.data.flow_nat_ipv4.dip = htonl(orig->dst.u3.ip);
11423 +
11424 +       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_PPTP_GRE;
11425 +       param.data.flow_nat_ipv4.l4.gre.call_id = htons(orig->dst.u.gre.key);
11426 +
11427 +       param.data.flow_nat_ipv4.nat_ip = htonl(reply->dst.u3.ip);
11428 +       param.data.flow_nat_ipv4.l4.gre.nat_call_id = htons(reply->src.u.gre.key);
11429 +
11430 +       if (sppe_func_hook(&param)) {
11431 +               printk("<0><%s> fail to add IPv4 from-LAN flow!!\n", __FUNCTION__);
11432 +       }
11433 +
11434 +       param.data.flow_nat_ipv4.fw = 1;
11435 +
11436 +       param.data.flow_nat_ipv4.sip = htonl(reply->src.u3.ip);
11437 +       param.data.flow_nat_ipv4.dip = htonl(reply->dst.u3.ip);
11438 +       param.data.flow_nat_ipv4.l4.gre.call_id = htons(reply->dst.u.gre.key);
11439 +
11440 +       param.data.flow_nat_ipv4.nat_ip = htonl(orig->src.u3.ip);
11441 +       param.data.flow_nat_ipv4.l4.gre.nat_call_id = htons(orig->src.u.gre.key);
11442 +
11443 +       if (sppe_func_hook(&param)) {
11444 +               printk("<0><%s> fail to add IPv4 from-WAN flow!!\n", __FUNCTION__);
11445 +       }
11446 +
11447 +       return 0;
11448 +}
11449 +#endif
11450 +
11451 +
11452 +
11453  /* Returns verdict for packet, and may modify conntrack */
11454  static int gre_packet(struct nf_conn *ct,
11455                       const struct sk_buff *skb,
11456 @@ -242,6 +297,10 @@ static int gre_packet(struct nf_conn *ct
11457                 /* Also, more likely to be important, and not a probe. */
11458                 set_bit(IPS_ASSURED_BIT, &ct->status);
11459                 nf_conntrack_event_cache(IPCT_STATUS, ct);
11460 +#if defined (CONFIG_CNS3XXX_SPPE)
11461 +        sppe_gre_flow_add(ct);
11462 +#endif
11463 +
11464         } else
11465                 nf_ct_refresh_acct(ct, ctinfo, skb,
11466                                    ct->proto.gre.timeout);
11467 --- a/net/netfilter/nf_conntrack_proto_tcp.c
11468 +++ b/net/netfilter/nf_conntrack_proto_tcp.c
11469 @@ -29,6 +29,10 @@
11470  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
11471  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
11472  
11473 +#if defined (CONFIG_CNS3XXX_SPPE)
11474 +#include <linux/cns3xxx/sppe.h>
11475 +#endif
11476 +
11477  /* "Be conservative in what you do,
11478      be liberal in what you accept from others."
11479      If it's non-zero, we mark only out of window RST segments as INVALID. */
11480 @@ -814,6 +818,141 @@ static int tcp_error(struct net *net,
11481         return NF_ACCEPT;
11482  }
11483  
11484 +#if defined (CONFIG_CNS3XXX_SPPE)
11485 +static int sppe_tcp_flow_add_ipv4(struct nf_conn *ct)
11486 +{
11487 +       SPPE_PARAM param;
11488 +       struct nf_conntrack_tuple *orig, *reply;
11489 +       
11490 +       orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11491 +       reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11492 +
11493 +#if defined (CONFIG_NF_CONNTRACK_PPTP)
11494 +       if (1723 == htons(orig->dst.u.tcp.port)) {
11495 +               /* PPTP Control Protocol, PPTP GRE tunneling need this kind of packet */
11496 +               return 0;
11497 +       }
11498 +#endif
11499 +#if defined (CONFIG_NF_CONNTRACK_FTP)
11500 +       if (21 == htons(orig->dst.u.tcp.port)) {
11501 +               /* PPTP Control Protocol, PPTP GRE tunneling need this kind of packet */
11502 +               return 0;
11503 +       }
11504 +#endif
11505 +
11506 +       memset(&param, 0, sizeof(SPPE_PARAM));
11507 +
11508 +       param.cmd = SPPE_CMD_FLOW_NAT_IPV4;
11509 +       param.op = SPPE_OP_SET;
11510 +
11511 +       param.data.flow_nat_ipv4.fw = 0;
11512 +       param.data.flow_nat_ipv4.sip = htonl(orig->src.u3.ip);
11513 +       param.data.flow_nat_ipv4.dip = htonl(orig->dst.u3.ip);
11514 +
11515 +       param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_TCP;
11516 +       param.data.flow_nat_ipv4.l4.port.src = htons(orig->src.u.tcp.port);
11517 +       param.data.flow_nat_ipv4.l4.port.dst = htons(orig->dst.u.tcp.port);
11518 +
11519 +       param.data.flow_nat_ipv4.nat_ip = htonl(reply->dst.u3.ip);
11520 +       param.data.flow_nat_ipv4.nat_port = htons(reply->dst.u.tcp.port);
11521 +       param.data.flow_nat_ipv4.max_len = 0x3;
11522 +       
11523 +       if (sppe_func_hook(&param)) {
11524 +               printk("<0><%s> fail to add IPv4 from-LAN flow!!\n", __FUNCTION__);
11525 +       }
11526 +
11527 +       param.data.flow_nat_ipv4.fw = 1;
11528 +       param.data.flow_nat_ipv4.sip = htonl(reply->src.u3.ip);
11529 +       param.data.flow_nat_ipv4.dip = htonl(reply->dst.u3.ip);
11530 +       param.data.flow_nat_ipv4.l4.port.src = htons(reply->src.u.tcp.port);
11531 +       param.data.flow_nat_ipv4.l4.port.dst = htons(reply->dst.u.tcp.port);
11532 +
11533 +       param.data.flow_nat_ipv4.nat_ip = htonl(orig->src.u3.ip);
11534 +       param.data.flow_nat_ipv4.nat_port = htons(orig->src.u.tcp.port);
11535 +
11536 +       if (sppe_func_hook(&param)) {
11537 +               printk("<0><%s> fail to add IPv4 from-WAN flow!!\n", __FUNCTION__);
11538 +       }
11539 +       
11540 +       return 0;
11541 +}
11542 +
11543 +static int sppe_tcp_flow_add_ipv6(struct nf_conn *ct)
11544 +{
11545 +       SPPE_PARAM param;
11546 +       struct nf_conntrack_tuple *orig, *reply;
11547 +
11548 +       orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11549 +       reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11550 +
11551 +       if (1723 == htons(orig->dst.u.tcp.port)) {
11552 +               /* PPTP Control Protocol, PPTP GRE tunneling need this kind of packet */
11553 +               return 0;
11554 +       }
11555 +
11556 +       memset(&param, 0, sizeof(SPPE_PARAM));
11557 +
11558 +       param.cmd = SPPE_CMD_FLOW_ROUTE_IPV6;
11559 +       param.op = SPPE_OP_SET;
11560 +
11561 +       /* from-LAN flow */
11562 +       param.data.flow_route_ipv6.fw = 0;
11563 +       param.data.flow_route_ipv6.sip[0] = htonl(orig->src.u3.ip6[0]);
11564 +       param.data.flow_route_ipv6.sip[1] = htonl(orig->src.u3.ip6[1]);
11565 +       param.data.flow_route_ipv6.sip[2] = htonl(orig->src.u3.ip6[2]);
11566 +       param.data.flow_route_ipv6.sip[3] = htonl(orig->src.u3.ip6[3]);
11567 +       param.data.flow_route_ipv6.dip[0] = htonl(orig->dst.u3.ip6[0]);
11568 +       param.data.flow_route_ipv6.dip[1] = htonl(orig->dst.u3.ip6[1]);
11569 +       param.data.flow_route_ipv6.dip[2] = htonl(orig->dst.u3.ip6[2]);
11570 +       param.data.flow_route_ipv6.dip[3] = htonl(orig->dst.u3.ip6[3]);
11571 +       param.data.flow_route_ipv6.l4_prot = SPPE_PROT_TCP;
11572 +       param.data.flow_route_ipv6.l4.port.src = htons(orig->src.u.tcp.port);
11573 +       param.data.flow_route_ipv6.l4.port.dst = htons(orig->dst.u.tcp.port);
11574 +       param.data.flow_route_ipv6.max_len = 0x3;
11575 +       
11576 +       if (sppe_func_hook(&param)) {
11577 +               printk("<0><%s> fail to add IPv6 from-LAN flow!!\n", __FUNCTION__);
11578 +       }
11579 +
11580 +       /* from-WAN flow */
11581 +       param.data.flow_route_ipv6.fw = 1;
11582 +       param.data.flow_route_ipv6.sip[0] = htonl(reply->src.u3.ip6[0]);
11583 +       param.data.flow_route_ipv6.sip[1] = htonl(reply->src.u3.ip6[1]);
11584 +       param.data.flow_route_ipv6.sip[2] = htonl(reply->src.u3.ip6[2]);
11585 +       param.data.flow_route_ipv6.sip[3] = htonl(reply->src.u3.ip6[3]);
11586 +       param.data.flow_route_ipv6.dip[0] = htonl(reply->dst.u3.ip6[0]);
11587 +       param.data.flow_route_ipv6.dip[1] = htonl(reply->dst.u3.ip6[1]);
11588 +       param.data.flow_route_ipv6.dip[2] = htonl(reply->dst.u3.ip6[2]);
11589 +       param.data.flow_route_ipv6.dip[3] = htonl(reply->dst.u3.ip6[3]);
11590 +       param.data.flow_route_ipv6.l4.port.src = htons(reply->src.u.tcp.port);
11591 +       param.data.flow_route_ipv6.l4.port.dst = htons(reply->dst.u.tcp.port);
11592 +
11593 +       if (sppe_func_hook(&param)) {
11594 +               printk("<0><%s> fail to add IPv6 from-LAN flow!!\n", __FUNCTION__);
11595 +       }
11596 +
11597 +       return 0;
11598 +}
11599 +
11600 +static int sppe_tcp_flow_add(struct nf_conn *ct)
11601 +{
11602 +       if (0 == sppe_hook_ready) {
11603 +               return 0;
11604 +       }
11605 +
11606 +       if (AF_INET == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) {
11607 +               sppe_tcp_flow_add_ipv4(ct);
11608 +               return 0;
11609 +       } else if (AF_INET6 == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) {
11610 +               sppe_tcp_flow_add_ipv6(ct);
11611 +               return 0;
11612 +       }
11613 +
11614 +       /* return fail */
11615 +       return (-1);
11616 +}
11617 +#endif
11618 +
11619  /* Returns verdict for packet, or -1 for invalid. */
11620  static int tcp_packet(struct nf_conn *ct,
11621                       const struct sk_buff *skb,
11622 @@ -961,11 +1100,18 @@ static int tcp_packet(struct nf_conn *ct
11623                 break;
11624         }
11625  
11626 +#if defined (CONFIG_CNS3XXX_SPPE)
11627 +    if(!(th->rst == 1 || th->fin == 1)) {
11628 +#endif
11629         if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
11630                            skb, dataoff, th, pf)) {
11631                 spin_unlock_bh(&ct->lock);
11632                 return -NF_ACCEPT;
11633         }
11634 +#if defined (CONFIG_CNS3XXX_SPPE)
11635 +    }
11636 +#endif
11637 +
11638       in_window:
11639         /* From now on we have got in-window packets */
11640         ct->proto.tcp.last_index = index;
11641 @@ -1015,6 +1161,10 @@ static int tcp_packet(struct nf_conn *ct
11642                    connection. */
11643                 set_bit(IPS_ASSURED_BIT, &ct->status);
11644                 nf_conntrack_event_cache(IPCT_STATUS, ct);
11645 +#if defined (CONFIG_CNS3XXX_SPPE)
11646 +               /* Add SPPE hardware flow */
11647 +               sppe_tcp_flow_add(ct);
11648 +#endif
11649         }
11650         nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
11651  
11652 --- a/net/netfilter/nf_conntrack_proto_udp.c
11653 +++ b/net/netfilter/nf_conntrack_proto_udp.c
11654 @@ -24,6 +24,9 @@
11655  #include <net/netfilter/nf_log.h>
11656  #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
11657  #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
11658 +#if defined (CONFIG_CNS3XXX_SPPE)
11659 +#include <linux/cns3xxx/sppe.h>
11660 +#endif
11661  
11662  static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ;
11663  static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ;
11664 @@ -63,6 +66,122 @@ static int udp_print_tuple(struct seq_fi
11665                           ntohs(tuple->dst.u.udp.port));
11666  }
11667  
11668 +#if defined (CONFIG_CNS3XXX_SPPE)
11669 +static int sppe_udp_flow_add_ipv4(struct nf_conn *ct)
11670 +{
11671 +    SPPE_PARAM param;
11672 +    struct nf_conntrack_tuple *orig, *reply;
11673 +
11674 +    orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11675 +    reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11676 +
11677 +    memset(&param, 0, sizeof(SPPE_PARAM));
11678 +
11679 +    param.cmd = SPPE_CMD_FLOW_NAT_IPV4;
11680 +    param.op = SPPE_OP_SET;
11681 +
11682 +    param.data.flow_nat_ipv4.fw = 0;
11683 +    param.data.flow_nat_ipv4.sip = htonl(orig->src.u3.ip);
11684 +    param.data.flow_nat_ipv4.dip = htonl(orig->dst.u3.ip);
11685 +    param.data.flow_nat_ipv4.l4_prot = SPPE_PROT_UDP;
11686 +
11687 +    param.data.flow_nat_ipv4.l4.port.src = htons(orig->src.u.tcp.port);
11688 +    param.data.flow_nat_ipv4.l4.port.dst = htons(orig->dst.u.tcp.port);
11689 +
11690 +    param.data.flow_nat_ipv4.nat_ip = htonl(reply->dst.u3.ip);
11691 +    param.data.flow_nat_ipv4.nat_port = htons(reply->dst.u.tcp.port);
11692 +
11693 +    if (sppe_func_hook(&param)) {
11694 +        printk("<0><%s> fail to add IPv4 UDP from-LAN flow!!\n", __FUNCTION__);
11695 +    }
11696 +    param.data.flow_nat_ipv4.fw = 1;
11697 +    param.data.flow_nat_ipv4.sip = htonl(reply->src.u3.ip);
11698 +    param.data.flow_nat_ipv4.dip = htonl(reply->dst.u3.ip);
11699 +
11700 +    param.data.flow_nat_ipv4.l4.port.src = htons(reply->src.u.tcp.port);
11701 +    param.data.flow_nat_ipv4.l4.port.dst = htons(reply->dst.u.tcp.port);
11702 +
11703 +    param.data.flow_nat_ipv4.nat_ip = htonl(orig->src.u3.ip);
11704 +    param.data.flow_nat_ipv4.nat_port = htons(orig->src.u.tcp.port);
11705 +
11706 +    if (sppe_func_hook(&param)) {
11707 +        printk("<0><%s> fail to add IPv4 from-WAN flow!!\n", __FUNCTION__);
11708 +    }
11709 +
11710 +    return 0;
11711 +}
11712 +
11713 +static int sppe_udp_flow_add_ipv6(struct nf_conn *ct)
11714 +{
11715 +    SPPE_PARAM param;
11716 +    struct nf_conntrack_tuple *orig, *reply;
11717 +
11718 +    orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
11719 +    reply = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
11720 +
11721 +    memset(&param, 0, sizeof(SPPE_PARAM));
11722 +
11723 +    param.cmd = SPPE_CMD_FLOW_ROUTE_IPV6;
11724 +    param.op = SPPE_OP_SET;
11725 +
11726 +    /* from-LAN flow */
11727 +    param.data.flow_route_ipv6.fw = 0;
11728 +    param.data.flow_route_ipv6.sip[0] = htonl(orig->src.u3.ip6[0]);
11729 +    param.data.flow_route_ipv6.sip[1] = htonl(orig->src.u3.ip6[1]);
11730 +    param.data.flow_route_ipv6.sip[2] = htonl(orig->src.u3.ip6[2]);
11731 +    param.data.flow_route_ipv6.sip[3] = htonl(orig->src.u3.ip6[3]);
11732 +    param.data.flow_route_ipv6.dip[0] = htonl(orig->dst.u3.ip6[0]);
11733 +    param.data.flow_route_ipv6.dip[1] = htonl(orig->dst.u3.ip6[1]);
11734 +    param.data.flow_route_ipv6.dip[2] = htonl(orig->dst.u3.ip6[2]);
11735 +    param.data.flow_route_ipv6.dip[3] = htonl(orig->dst.u3.ip6[3]);
11736 +    param.data.flow_route_ipv6.l4_prot = SPPE_PROT_UDP;
11737 +    param.data.flow_route_ipv6.l4.port.src = htons(orig->src.u.udp.port);
11738 +    param.data.flow_route_ipv6.l4.port.dst = htons(orig->dst.u.udp.port);
11739 +
11740 +    if (sppe_func_hook(&param)) {
11741 +        printk("<0><%s> fail to add IPv6 from-LAN flow!!\n", __FUNCTION__);
11742 +    }
11743 +
11744 +    /* from-WAN flow */
11745 +    param.data.flow_route_ipv6.fw = 1;
11746 +    param.data.flow_route_ipv6.sip[0] = htonl(reply->src.u3.ip6[0]);
11747 +    param.data.flow_route_ipv6.sip[1] = htonl(reply->src.u3.ip6[1]);
11748 +    param.data.flow_route_ipv6.sip[2] = htonl(reply->src.u3.ip6[2]);
11749 +    param.data.flow_route_ipv6.sip[3] = htonl(reply->src.u3.ip6[3]);
11750 +    param.data.flow_route_ipv6.dip[0] = htonl(reply->dst.u3.ip6[0]);
11751 +    param.data.flow_route_ipv6.dip[1] = htonl(reply->dst.u3.ip6[1]);
11752 +    param.data.flow_route_ipv6.dip[2] = htonl(reply->dst.u3.ip6[2]);
11753 +    param.data.flow_route_ipv6.dip[3] = htonl(reply->dst.u3.ip6[3]);
11754 +    param.data.flow_route_ipv6.l4.port.src = htons(reply->src.u.udp.port);
11755 +    param.data.flow_route_ipv6.l4.port.dst = htons(reply->dst.u.udp.port);
11756 +
11757 +    if (sppe_func_hook(&param)) {
11758 +        printk("<0><%s> fail to add IPv6 from-LAN flow!!\n", __FUNCTION__);
11759 +    }
11760 +
11761 +    return 0;
11762 +}
11763 +
11764 +static int sppe_udp_flow_add(struct nf_conn *ct)
11765 +{
11766 +    if (0 == sppe_hook_ready) {
11767 +        return 0;
11768 +    }
11769 +
11770 +    if (AF_INET == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) {
11771 +        sppe_udp_flow_add_ipv4(ct);
11772 +        return 0;
11773 +    } else if (AF_INET6 == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num) {
11774 +        sppe_udp_flow_add_ipv6(ct);
11775 +        return 0;
11776 +    }
11777 +
11778 +    /* return fail */
11779 +    return (-1);
11780 +}
11781 +#endif
11782 +
11783 +
11784  /* Returns verdict for packet, and may modify conntracktype */
11785  static int udp_packet(struct nf_conn *ct,
11786                       const struct sk_buff *skb,
11787 @@ -77,7 +196,15 @@ static int udp_packet(struct nf_conn *ct
11788                 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
11789                 /* Also, more likely to be important, and not a probe */
11790                 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
11791 +#if defined (CONFIG_CNS3XXX_SPPE)
11792 +        {
11793 +#endif
11794                         nf_conntrack_event_cache(IPCT_STATUS, ct);
11795 +#if defined (CONFIG_CNS3XXX_SPPE)
11796 +            /* Add SPPE hardware flow */
11797 +            sppe_udp_flow_add(ct);
11798 +        }
11799 +#endif
11800         } else
11801                 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
11802