2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 //-----------------------------------------------------------------------
19 * Driver for Infineon Amazon 3 port switch
21 //-----------------------------------------------------------------------
22 /* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com]
23 * Created: 7-April-2004
25 //-----------------------------------------------------------------------
27 * Changed on: Jun 28, 2004
28 * Changed by: peng.liu@infineon.com
29 * Reason: add hardware flow control (HFC) (CONFIG_NET_HW_FLOWCONTROL)
31 * Changed on: Apr 6, 2005
32 * Changed by: mars.lin@infineon.com
33 * Reason : supoort port identification
37 // copyright 2004-2005 infineon.com
39 // copyright 2007 john crispin <blogic@openwrt.org>
40 // copyright 2007 felix fietkau <nbd@openwrt.org>
44 // port vlan code from bcrm target... the tawainese code was scrapped due to crappyness
45 // check all the mmi reg settings and possibly document them better
46 // verify the ethtool code
47 // remove the while(1) stuff
48 // further clean up and rework ... but it works for now
49 // check the mode[]=bridge stuff
50 // verify that the ethaddr can be set from u-boot
58 #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
62 #if defined(MODVERSIONS) && !defined(__GENKSYMS__)
63 #include <linux/modversions.h>
66 #include <linux/module.h>
67 #include <linux/string.h>
68 #include <linux/sched.h>
69 #include <linux/kernel.h>
70 #include <linux/slab.h>
71 #include <linux/errno.h>
72 #include <linux/types.h>
73 #include <linux/interrupt.h>
74 #include <linux/mii.h>
75 #include <asm/uaccess.h>
77 #include <linux/netdevice.h>
78 #include <linux/etherdevice.h>
80 #include <linux/tcp.h>
81 #include <linux/skbuff.h>
82 #include <linux/in6.h>
83 #include <linux/proc_fs.h>
85 #include <linux/ethtool.h>
86 #include <asm/checksum.h>
87 #include <linux/init.h>
89 #include <asm/amazon/amazon.h>
90 #include <asm/amazon/amazon_dma.h>
91 #include <asm/amazon/amazon_sw.h>
93 // how many mii ports are there ?
94 #define AMAZON_SW_INT_NO 2
96 #define ETHERNET_PACKET_DMA_BUFFER_SIZE 1536
98 /***************************************** Module Parameters *************************************/
99 char mode
[] = "bridge";
100 module_param_array(mode
, charp
, NULL
, 0);
102 static int timeout
= 1 * HZ
;
103 module_param(timeout
, int, 0);
105 int switch_init(struct net_device
*dev
);
106 void switch_tx_timeout(struct net_device
*dev
);
108 struct net_device switch_devs
[2] = {
113 int add_mac_table_entry(u64 entry_value
)
118 AMAZON_SW_REG32(AMAZON_SW_ARL_CTL
) = ~7;
120 for (i
= 0; i
< 32; i
++) {
121 AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) = 0x80000000 | 0x20 | i
;
122 while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) & (0x80000000)) {};
123 data1
= AMAZON_SW_REG32(AMAZON_SW_DATA1
);
124 data2
= AMAZON_SW_REG32(AMAZON_SW_DATA2
);
125 if ((data1
& (0x00700000)) != 0x00700000)
127 AMAZON_SW_REG32(AMAZON_SW_DATA1
) = (u32
) (entry_value
>> 32);
128 AMAZON_SW_REG32(AMAZON_SW_DATA2
) = (u32
) entry_value
& 0xffffffff;
129 AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) = 0xc0000020 | i
;
130 while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) & (0x80000000)) {};
133 AMAZON_SW_REG32(AMAZON_SW_ARL_CTL
) |= 7;
139 u64
read_mac_table_entry(int index
)
143 AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) = 0x80000000 | 0x20 | index
;
144 while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) & (0x80000000)) {};
145 data1
= AMAZON_SW_REG32(AMAZON_SW_DATA1
) & 0xffffff;
146 data2
= AMAZON_SW_REG32(AMAZON_SW_DATA2
);
147 value
= (u64
) data1
<< 32 | (u64
) data2
;
151 int write_mac_table_entry(int index
, u64 value
)
154 data1
= (u32
) (value
>> 32);
155 data2
= (u32
) value
& 0xffffffff;
156 AMAZON_SW_REG32(AMAZON_SW_DATA1
) = data1
;
157 AMAZON_SW_REG32(AMAZON_SW_DATA2
) = data2
;
158 AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) = 0xc0000020 | index
;
159 while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL
) & (0x80000000)) {};
163 u32
get_mdio_reg(int phy_addr
, int reg_num
)
166 AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) = (3 << 30) | ((phy_addr
& 0x1f) << 21) | ((reg_num
& 0x1f) << 16);
167 while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) & (1 << 31)) {};
168 value
= AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) & 0xffff;
172 int set_mdio_reg(int phy_addr
, int reg_num
, u32 value
)
174 AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) = (2 << 30) | ((phy_addr
& 0x1f) << 21) | ((reg_num
& 0x1f) << 16) | (value
& 0xffff);
175 while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) & (1 << 31)) {};
179 int auto_negotiate(int phy_addr
)
182 value
= get_mdio_reg(phy_addr
, MDIO_BASE_CONTROL_REG
);
183 set_mdio_reg(phy_addr
, MDIO_BASE_CONTROL_REG
, (value
| RESTART_AUTO_NEGOTIATION
| AUTO_NEGOTIATION_ENABLE
| PHY_RESET
));
188 In this version of switch driver, we split the dma channels for the switch.
189 2 for port0 and 2 for port1. So that we can do internal bridging if necessary.
190 In switch mode, packets coming in from port0 or port1 is able to do Destination
191 address lookup. Packets coming from port0 with destination address of port1 should
192 not go to pmac again. The switch hardware should be able to do the switch in the hard
193 ware level. Packets coming from the pmac should not do the DA look up in that the
194 desination is already known for the kernel. It only needs to go to the correct NIC to
197 int amazon_sw_chip_init(void)
202 /* Aging tick select: 5mins */
204 if (strcmp(mode
, "bridge") == 0) {
205 // bridge mode, set militarised mode to 1, no learning!
208 // enable learning for P0 and P1,
212 /* unknown broadcast/multicast/unicast to all ports */
213 AMAZON_SW_REG32(AMAZON_SW_UN_DEST
) = 0x1ff;
215 AMAZON_SW_REG32(AMAZON_SW_ARL_CTL
) = tmp1
;
217 /* OCS:1 set OCS bit, split the two NIC in rx direction EDL:1 (enable DA lookup) */
218 #if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE)
219 AMAZON_SW_REG32(AMAZON_SW_P2_PCTL
) = 0x700;
221 AMAZON_SW_REG32(AMAZON_SW_P2_PCTL
) = 0x401;
224 /* EPC: 1 split the two NIC in tx direction CRC is generated */
225 AMAZON_SW_REG32(AMAZON_SW_P2_CTL
) = 0x6;
227 // for bi-directional
228 AMAZON_SW_REG32(AMAZON_SW_P0_WM
) = 0x14141412;
229 AMAZON_SW_REG32(AMAZON_SW_P1_WM
) = 0x14141412;
230 AMAZON_SW_REG32(AMAZON_SW_P2_WM
) = 0x28282826;
231 AMAZON_SW_REG32(AMAZON_SW_GBL_WM
) = 0x0;
233 AMAZON_SW_REG32(AMAZON_CGU_PLL0SR
) = (AMAZON_SW_REG32(AMAZON_CGU_PLL0SR
)) | 0x58000000;
235 AMAZON_SW_REG32(AMAZON_CGU_IFCCR
) = (AMAZON_SW_REG32(AMAZON_CGU_IFCCR
)) | 0x80000004;
236 // enable power for PHY
237 AMAZON_SW_REG32(AMAZON_PMU_PWDCR
) = (AMAZON_SW_REG32(AMAZON_PMU_PWDCR
)) | AMAZON_PMU_PWDCR_EPHY
;
238 // set reverse MII, enable MDIO statemachine
239 AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG
) = 0x800027bf;
241 if (((AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG
)) & 0x80000000) == 0)
243 AMAZON_SW_REG32(AMAZON_SW_EPHY
) = 0xff;
246 AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC
) = 0x83e08000;
247 auto_negotiate(0x1f);
249 /* enable all ports */
250 AMAZON_SW_REG32(AMAZON_SW_PS_CTL
) = 0x7;
251 for (i
= 0; i
< 32; i
++)
252 write_mac_table_entry(i
, 1 << 50);
256 static unsigned char my_ethaddr
[MAX_ADDR_LEN
];
257 /* need to get the ether addr from u-boot */
258 static int __init
ethaddr_setup(char *line
)
263 memset(my_ethaddr
, 0, MAX_ADDR_LEN
);
264 for (i
= 0; i
< 6; i
++) {
265 my_ethaddr
[i
] = line
? simple_strtoul(line
, &ep
, 16) : 0;
267 line
= (*ep
) ? ep
+ 1 : ep
;
269 printk("mac address %2x-%2x-%2x-%2x-%2x-%2x \n", my_ethaddr
[0], my_ethaddr
[1], my_ethaddr
[2], my_ethaddr
[3], my_ethaddr
[4], my_ethaddr
[5]);
273 __setup("ethaddr=", ethaddr_setup
);
275 static void open_rx_dma(struct net_device
*dev
)
277 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
278 struct dma_device_info
*dma_dev
= priv
->dma_device
;
281 for (i
= 0; i
< dma_dev
->num_rx_chan
; i
++)
282 dma_dev
->rx_chan
[i
].control
= 1;
283 dma_device_update_rx(dma_dev
);
286 #ifdef CONFIG_NET_HW_FLOWCONTROL
287 static void close_rx_dma(struct net_device
*dev
)
289 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
290 struct dma_device_info
*dma_dev
= priv
->dma_device
;
293 for (i
= 0; i
< dma_dev
->num_rx_chan
; i
++)
294 dma_dev
->rx_chan
[i
].control
= 0;
295 dma_device_update_rx(dma_dev
);
298 void amazon_xon(struct net_device
*dev
)
301 local_irq_save(flag
);
303 local_irq_restore(flag
);
307 int switch_open(struct net_device
*dev
)
309 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
310 if (!strcmp(dev
->name
, "eth1")) {
311 priv
->mdio_phy_addr
= PHY0_ADDR
;
315 #ifdef CONFIG_NET_HW_FLOWCONTROL
316 if ((priv
->fc_bit
= netdev_register_fc(dev
, amazon_xon
)) == 0) {
317 printk("Hardware Flow Control register fails\n");
321 netif_start_queue(dev
);
325 int switch_release(struct net_device
*dev
)
328 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
329 struct dma_device_info
*dma_dev
= priv
->dma_device
;
331 for (i
= 0; i
< dma_dev
->num_tx_chan
; i
++)
332 dma_dev
->tx_chan
[i
].control
= 0;
333 for (i
= 0; i
< dma_dev
->num_rx_chan
; i
++)
334 dma_dev
->rx_chan
[i
].control
= 0;
336 dma_device_update(dma_dev
);
338 #ifdef CONFIG_NET_HW_FLOWCONTROL
340 netdev_unregister_fc(priv
->fc_bit
);
343 netif_stop_queue(dev
);
349 void switch_rx(struct net_device
*dev
, int len
, struct sk_buff
*skb
)
351 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
352 #ifdef CONFIG_NET_HW_FLOWCONTROL
356 skb
->protocol
= eth_type_trans(skb
, dev
);
358 #ifdef CONFIG_NET_HW_FLOWCONTROL
359 mit_sel
= netif_rx(skb
);
369 && (!test_and_set_bit(priv
->fc_bit
, &netdev_fc_xoff
))) {
377 priv
->stats
.rx_packets
++;
378 priv
->stats
.rx_bytes
+= len
;
382 int asmlinkage
switch_hw_tx(char *buf
, int len
, struct net_device
*dev
)
384 struct switch_priv
*priv
= dev
->priv
;
385 struct dma_device_info
*dma_dev
= priv
->dma_device
;
387 dma_dev
->current_tx_chan
= 0;
388 return dma_device_write(dma_dev
, buf
, len
, priv
->skb
);
391 int asmlinkage
switch_tx(struct sk_buff
*skb
, struct net_device
*dev
)
395 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
397 len
= skb
->len
< ETH_ZLEN
? ETH_ZLEN
: skb
->len
;
400 dev
->trans_start
= jiffies
;
402 if (switch_hw_tx(data
, len
, dev
) != len
) {
403 dev_kfree_skb_any(skb
);
407 priv
->stats
.tx_packets
++;
408 priv
->stats
.tx_bytes
+= len
;
412 void switch_tx_timeout(struct net_device
*dev
)
414 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
415 priv
->stats
.tx_errors
++;
416 netif_wake_queue(dev
);
420 void negotiate(struct net_device
*dev
)
422 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
423 unsigned short data
= get_mdio_reg(priv
->mdio_phy_addr
, MDIO_ADVERTISMENT_REG
);
425 data
&= ~(MDIO_ADVERT_100_HD
| MDIO_ADVERT_100_FD
| MDIO_ADVERT_10_FD
| MDIO_ADVERT_10_HD
);
427 switch (priv
->current_speed_selection
) {
429 if (priv
->current_duplex
== full
)
430 data
|= MDIO_ADVERT_10_FD
;
431 else if (priv
->current_duplex
== half
)
432 data
|= MDIO_ADVERT_10_HD
;
434 data
|= MDIO_ADVERT_10_HD
| MDIO_ADVERT_10_FD
;
438 if (priv
->current_duplex
== full
)
439 data
|= MDIO_ADVERT_100_FD
;
440 else if (priv
->current_duplex
== half
)
441 data
|= MDIO_ADVERT_100_HD
;
443 data
|= MDIO_ADVERT_100_HD
| MDIO_ADVERT_100_FD
;
447 if (priv
->current_duplex
== full
)
448 data
|= MDIO_ADVERT_100_FD
| MDIO_ADVERT_10_FD
;
449 else if (priv
->current_duplex
== half
)
450 data
|= MDIO_ADVERT_100_HD
| MDIO_ADVERT_10_HD
;
452 data
|= MDIO_ADVERT_100_HD
| MDIO_ADVERT_100_FD
| MDIO_ADVERT_10_FD
| MDIO_ADVERT_10_HD
;
455 default: /* assume autoneg speed and duplex */
456 data
|= MDIO_ADVERT_100_HD
| MDIO_ADVERT_100_FD
| MDIO_ADVERT_10_FD
| MDIO_ADVERT_10_HD
;
459 set_mdio_reg(priv
->mdio_phy_addr
, MDIO_ADVERTISMENT_REG
, data
);
461 /* Renegotiate with link partner */
463 data
= get_mdio_reg(priv
->mdio_phy_addr
, MDIO_BASE_CONTROL_REG
);
464 data
|= MDIO_BC_NEGOTIATE
;
466 set_mdio_reg(priv
->mdio_phy_addr
, MDIO_BASE_CONTROL_REG
, data
);
471 void set_duplex(struct net_device
*dev
, enum duplex new_duplex
)
473 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
474 if (new_duplex
!= priv
->current_duplex
) {
475 priv
->current_duplex
= new_duplex
;
480 void set_speed(struct net_device
*dev
, unsigned long speed
)
482 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
483 priv
->current_speed_selection
= speed
;
487 static int switch_ethtool_ioctl(struct net_device
*dev
, struct ifreq
*ifr
)
489 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
490 struct ethtool_cmd ecmd
;
492 if (copy_from_user(&ecmd
, ifr
->ifr_data
, sizeof(ecmd
)))
497 memset((void *) &ecmd
, 0, sizeof(ecmd
));
498 ecmd
.supported
= SUPPORTED_Autoneg
| SUPPORTED_TP
| SUPPORTED_MII
| SUPPORTED_10baseT_Half
| SUPPORTED_10baseT_Full
|
499 SUPPORTED_100baseT_Half
| SUPPORTED_100baseT_Full
;
501 ecmd
.transceiver
= XCVR_EXTERNAL
;
502 ecmd
.phy_address
= priv
->mdio_phy_addr
;
504 ecmd
.speed
= priv
->current_speed
;
506 ecmd
.duplex
= priv
->full_duplex
? DUPLEX_FULL
: DUPLEX_HALF
;
508 ecmd
.advertising
= ADVERTISED_TP
;
509 if (priv
->current_duplex
== autoneg
&& priv
->current_speed_selection
== 0)
510 ecmd
.advertising
|= ADVERTISED_Autoneg
;
512 ecmd
.advertising
|= ADVERTISED_10baseT_Half
| ADVERTISED_10baseT_Full
|
513 ADVERTISED_100baseT_Half
| ADVERTISED_100baseT_Full
;
514 if (priv
->current_speed_selection
== 10)
515 ecmd
.advertising
&= ~(ADVERTISED_100baseT_Half
| ADVERTISED_100baseT_Full
);
516 else if (priv
->current_speed_selection
== 100)
517 ecmd
.advertising
&= ~(ADVERTISED_10baseT_Half
| ADVERTISED_10baseT_Full
);
518 if (priv
->current_duplex
== half
)
519 ecmd
.advertising
&= ~(ADVERTISED_10baseT_Full
| ADVERTISED_100baseT_Full
);
520 else if (priv
->current_duplex
== full
)
521 ecmd
.advertising
&= ~(ADVERTISED_10baseT_Half
| ADVERTISED_100baseT_Half
);
523 ecmd
.autoneg
= AUTONEG_ENABLE
;
524 if (copy_to_user(ifr
->ifr_data
, &ecmd
, sizeof(ecmd
)))
529 if (!capable(CAP_NET_ADMIN
)) {
532 if (ecmd
.autoneg
== AUTONEG_ENABLE
) {
533 set_duplex(dev
, autoneg
);
536 set_duplex(dev
, ecmd
.duplex
== DUPLEX_HALF
? half
: full
);
537 set_speed(dev
, ecmd
.speed
== SPEED_10
? 10 : 100);
541 case ETHTOOL_GDRVINFO
:
543 struct ethtool_drvinfo info
;
544 memset((void *) &info
, 0, sizeof(info
));
545 strncpy(info
.driver
, "AMAZONE", sizeof(info
.driver
) - 1);
546 strncpy(info
.fw_version
, "N/A", sizeof(info
.fw_version
) - 1);
547 strncpy(info
.bus_info
, "N/A", sizeof(info
.bus_info
) - 1);
548 info
.regdump_len
= 0;
550 info
.testinfo_len
= 0;
551 if (copy_to_user(ifr
->ifr_data
, &info
, sizeof(info
)))
555 case ETHTOOL_NWAY_RST
:
556 if (priv
->current_duplex
== autoneg
&& priv
->current_speed_selection
== 0)
568 int mac_table_tools_ioctl(struct net_device
*dev
, struct mac_table_req
*req
)
574 case RESET_MAC_TABLE
:
575 for (i
= 0; i
< 32; i
++) {
576 write_mac_table_entry(i
, 0);
580 req
->entry_value
= read_mac_table_entry(req
->index
);
582 case WRITE_MAC_ENTRY
:
583 write_mac_table_entry(req
->index
, req
->entry_value
);
586 add_mac_table_entry(req
->entry_value
);
597 the ioctl for the switch driver is developed in the conventional way
598 the control type falls into some basic categories, among them, the
599 SIOCETHTOOL is the traditional eth interface. VLAN_TOOLS and
600 MAC_TABLE_TOOLS are designed specifically for amazon chip. User
601 should be aware of the data structures used in these interfaces.
603 int switch_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
605 struct data_req
*switch_data_req
= (struct data_req
*) ifr
->ifr_data
;
606 struct mac_table_req
*switch_mac_table_req
;
609 switch_ethtool_ioctl(dev
, ifr
);
611 case SIOCGMIIPHY
: /* Get PHY address */
613 case SIOCGMIIREG
: /* Read MII register */
615 case SIOCSMIIREG
: /* Write MII register */
617 case SET_ETH_SPEED_10
: /* 10 Mbps */
619 case SET_ETH_SPEED_100
: /* 100 Mbps */
621 case SET_ETH_SPEED_AUTO
: /* Auto negotiate speed */
623 case SET_ETH_DUPLEX_HALF
: /* Half duplex. */
625 case SET_ETH_DUPLEX_FULL
: /* Full duplex. */
627 case SET_ETH_DUPLEX_AUTO
: /* Autonegotiate duplex */
630 AMAZON_SW_REG32(switch_data_req
->index
) = switch_data_req
->value
;
632 case MAC_TABLE_TOOLS
:
633 switch_mac_table_req
= (struct mac_table_req
*) ifr
->ifr_data
;
634 mac_table_tools_ioctl(dev
, switch_mac_table_req
);
643 struct net_device_stats
*switch_stats(struct net_device
*dev
)
645 struct switch_priv
*priv
= (struct switch_priv
*) dev
->priv
;
649 int switch_change_mtu(struct net_device
*dev
, int new_mtu
)
657 int switch_hw_receive(struct net_device
*dev
, struct dma_device_info
*dma_dev
)
661 struct sk_buff
*skb
= NULL
;
663 len
= dma_device_read(dma_dev
, &buf
, (void **) &skb
);
666 printk("packet too large %d\n", len
);
667 goto switch_hw_receive_err_exit
;
673 printk("cannot restore pointer\n");
674 goto switch_hw_receive_err_exit
;
676 if (len
> (skb
->end
- skb
->tail
)) {
677 printk("BUG, len:%d end:%p tail:%p\n", (len
+ 4), skb
->end
, skb
->tail
);
678 goto switch_hw_receive_err_exit
;
682 switch_rx(dev
, len
, skb
);
685 switch_hw_receive_err_exit
:
687 dev_kfree_skb_any(skb
);
691 int dma_intr_handler(struct dma_device_info
*dma_dev
, int status
)
693 struct net_device
*dev
;
695 dev
= switch_devs
+ (u32
) dma_dev
->priv
;
698 switch_hw_receive(dev
, dma_dev
);
700 case TX_BUF_FULL_INT
:
701 netif_stop_queue(dev
);
703 case TRANSMIT_CPT_INT
:
704 netif_wake_queue(dev
);
710 /* reserve 2 bytes in front of data pointer*/
711 u8
*dma_buffer_alloc(int len
, int *byte_offset
, void **opt
)
714 struct sk_buff
*skb
= NULL
;
715 skb
= dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE
);
719 buffer
= (u8
*) (skb
->data
);
721 *(int *) opt
= (int) skb
;
726 int dma_buffer_free(u8
* dataptr
, void *opt
)
728 struct sk_buff
*skb
= NULL
;
732 skb
= (struct sk_buff
*) opt
;
733 dev_kfree_skb_any(skb
);
738 int init_dma_device(_dma_device_info
* dma_dev
)
741 int num_tx_chan
, num_rx_chan
;
742 if (strcmp(dma_dev
->device_name
, "switch1") == 0) {
745 dma_dev
->priv
= (void *) 0;
749 dma_dev
->priv
= (void *) 1;
753 dma_dev
->num_tx_chan
= num_tx_chan
;
754 dma_dev
->num_rx_chan
= num_rx_chan
;
756 dma_dev
->tx_burst_len
= 4;
757 dma_dev
->rx_burst_len
= 4;
758 for (i
= 0; i
< dma_dev
->num_tx_chan
; i
++) {
759 dma_dev
->tx_chan
[i
].weight
= QOS_DEFAULT_WGT
;
760 dma_dev
->tx_chan
[i
].desc_num
= 10;
761 dma_dev
->tx_chan
[i
].packet_size
= 0;
762 dma_dev
->tx_chan
[i
].control
= 0;
764 for (i
= 0; i
< num_rx_chan
; i
++) {
765 dma_dev
->rx_chan
[i
].weight
= QOS_DEFAULT_WGT
;
766 dma_dev
->rx_chan
[i
].desc_num
= 10;
767 dma_dev
->rx_chan
[i
].packet_size
= ETHERNET_PACKET_DMA_BUFFER_SIZE
;
768 dma_dev
->rx_chan
[i
].control
= 0;
770 dma_dev
->intr_handler
= dma_intr_handler
;
771 dma_dev
->buffer_alloc
= dma_buffer_alloc
;
772 dma_dev
->buffer_free
= dma_buffer_free
;
776 int switch_set_mac_address(struct net_device
*dev
, void *p
)
778 struct sockaddr
*addr
= p
;
779 memcpy(dev
->dev_addr
, addr
->sa_data
, dev
->addr_len
);
784 int switch_init(struct net_device
*dev
)
789 struct switch_priv
*priv
;
790 ether_setup(dev
); /* assign some of the fields */
791 printk("%s up using ", dev
->name
);
792 dev
->open
= switch_open
;
793 dev
->stop
= switch_release
;
794 dev
->hard_start_xmit
= switch_tx
;
795 dev
->do_ioctl
= switch_ioctl
;
796 dev
->get_stats
= switch_stats
;
797 dev
->change_mtu
= switch_change_mtu
;
798 dev
->set_mac_address
= switch_set_mac_address
;
799 dev
->tx_timeout
= switch_tx_timeout
;
800 dev
->watchdog_timeo
= timeout
;
802 SET_MODULE_OWNER(dev
);
804 dev
->priv
= kmalloc(sizeof(struct switch_priv
), GFP_KERNEL
);
805 if (dev
->priv
== NULL
)
807 memset(dev
->priv
, 0, sizeof(struct switch_priv
));
809 priv
->dma_device
= (struct dma_device_info
*) kmalloc(sizeof(struct dma_device_info
), GFP_KERNEL
);
810 if ((dev
- switch_devs
) == 0) {
811 sprintf(priv
->dma_device
->device_name
, "switch1");
812 } else if ((dev
- switch_devs
) == 1) {
813 sprintf(priv
->dma_device
->device_name
, "switch2");
815 printk("\"%s\"\n", priv
->dma_device
->device_name
);
816 init_dma_device(priv
->dma_device
);
817 result
= dma_device_register(priv
->dma_device
);
819 /* read the mac address from the mac table and put them into the mac table. */
820 for (i
= 0; i
< 6; i
++) {
821 retval
+= my_ethaddr
[i
];
823 /* ethaddr not set in u-boot ? */
825 dev
->dev_addr
[0] = 0x00;
826 dev
->dev_addr
[1] = 0x20;
827 dev
->dev_addr
[2] = 0xda;
828 dev
->dev_addr
[3] = 0x86;
829 dev
->dev_addr
[4] = 0x23;
830 dev
->dev_addr
[5] = 0x74 + (unsigned char) (dev
- switch_devs
);
832 for (i
= 0; i
< 6; i
++) {
833 dev
->dev_addr
[i
] = my_ethaddr
[i
];
835 dev
->dev_addr
[5] += +(unsigned char) (dev
- switch_devs
);
840 int switch_init_module(void)
842 int i
= 0, result
, device_present
= 0;
844 for (i
= 0; i
< AMAZON_SW_INT_NO
; i
++) {
845 sprintf(switch_devs
[i
].name
, "eth%d", i
);
847 if ((result
= register_netdev(switch_devs
+ i
)))
848 printk("error %i registering device \"%s\"\n", result
, switch_devs
[i
].name
);
852 amazon_sw_chip_init();
853 return device_present
? 0 : -ENODEV
;
856 void switch_cleanup(void)
859 struct switch_priv
*priv
;
860 for (i
= 0; i
< AMAZON_SW_INT_NO
; i
++) {
861 priv
= switch_devs
[i
].priv
;
862 if (priv
->dma_device
) {
863 dma_device_unregister(priv
->dma_device
);
864 kfree(priv
->dma_device
);
866 kfree(switch_devs
[i
].priv
);
867 unregister_netdev(switch_devs
+ i
);
872 module_init(switch_init_module
);
873 module_exit(switch_cleanup
);
875 MODULE_LICENSE("GPL");
876 MODULE_AUTHOR("Wu Qi Ming");