<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 23, 2021, 2:31 PM Vijay Kumar Banerjee <<a href="mailto:vijay@rtems.org">vijay@rtems.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jun 23, 2021 at 1:24 PM Joel Sherrill <<a href="mailto:joel@rtems.org" target="_blank" rel="noreferrer">joel@rtems.org</a>> wrote:<br>
><br>
> Assuming you built the bsps in question, I'm ok with this.<br>
><br>
I tested the build and install for both the bsps involved.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Then I'm cool with pushing it.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> Any insight info the tftp code? Did it really need rtems_bsdnet.h?<br>
><br>
It looks like, the tftp code uses the hostname and<br>
rtems_bsdnet_bootp_server_address from the legacy stack. The<br>
rtems_bsdnet.h has the extern declaration for it. I couldn't come up<br>
with a clean solution to add the values to tftp code. Any suggestion?<br>
Or we can make copies of this in each stack.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Is there an equivalent method in the new stack? This may be a case for some level of compatibility between them for RTEMS specifics.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I'm planning to work on two different networking submodule<br>
"net-services" and "net-drivers" for the common services and to expand<br>
the driver support for each stack. This can shift to the services repo<br>
later if we make copies of it as a temporary workaround.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Also the old network demos are stack independent past initialization. They just need a bsp/lab specific configuration to be useful. The default configuration is loopback which isn't useful for testing or showing basic use of features.</div><div dir="auto"><br></div><div dir="auto">This part should be a separate thread. :)</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> On Wed, Jun 23, 2021, 2:21 PM Vijay Kumar Banerjee <<a href="mailto:vijay@rtems.org" target="_blank" rel="noreferrer">vijay@rtems.org</a>> wrote:<br>
>><br>
>> ---<br>
>> bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a> | 3 -<br>
>> bsps/include/grlib/greth.h | 165 --<br>
>> bsps/include/grlib/network_interface_add.h | 47 -<br>
>> bsps/powerpc/beatnik/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a> | 3 -<br>
>> bsps/powerpc/beatnik/include/bsp/if_em_pub.h | 22 -<br>
>> bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h | 30 -<br>
>> bsps/powerpc/beatnik/include/bsp/if_mve_pub.h | 426 -----<br>
>> bsps/shared/grlib/net/greth.c | 1663 -----------------<br>
>> spec/build/bsps/objgrlib.yml | 2 -<br>
>> .../build/bsps/powerpc/beatnik/bspbeatnik.yml | 3 -<br>
>> 10 files changed, 2364 deletions(-)<br>
>> delete mode 100644 bsps/include/grlib/greth.h<br>
>> delete mode 100644 bsps/include/grlib/network_interface_add.h<br>
>> delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_em_pub.h<br>
>> delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h<br>
>> delete mode 100644 bsps/powerpc/beatnik/include/bsp/if_mve_pub.h<br>
>> delete mode 100644 bsps/shared/grlib/net/greth.c<br>
>><br>
>> diff --git a/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a> b/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> index b89e5c2b28..b5821564b1 100644<br>
>> --- a/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> +++ b/bsps/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> @@ -82,7 +82,6 @@ include_grlib_HEADERS += ../../bsps/include/grlib/gradcdac.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/grascs.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/grcan.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/grctm.h<br>
>> -include_grlib_HEADERS += ../../bsps/include/grlib/greth.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/grgpio.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/griommu.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/grlib.h<br>
>> @@ -102,7 +101,6 @@ include_grlib_HEADERS += ../../bsps/include/grlib/l2c.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/l4stat.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/mctrl.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/memscrub.h<br>
>> -include_grlib_HEADERS += ../../bsps/include/grlib/network_interface_add.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/occan.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/pcif.h<br>
>> include_grlib_HEADERS += ../../bsps/include/grlib/satcan.h<br>
>> @@ -118,7 +116,6 @@ include_libchip_HEADERS += ../../bsps/include/libchip/ata.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/ata_internal.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/disp_hcms29xx.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/ds1375-rtc.h<br>
>> -include_libchip_HEADERS += ../../bsps/include/libchip/greth.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/i2c-2b-eeprom.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/i2c-ds1621.h<br>
>> include_libchip_HEADERS += ../../bsps/include/libchip/i2c-sc620.h<br>
>> diff --git a/bsps/include/grlib/greth.h b/bsps/include/grlib/greth.h<br>
>> deleted file mode 100644<br>
>> index e7970a79f7..0000000000<br>
>> --- a/bsps/include/grlib/greth.h<br>
>> +++ /dev/null<br>
>> @@ -1,165 +0,0 @@<br>
>> -/*<br>
>> - * Cobham Gaisler ethernet MAC driver<br>
>> - * adapted from Opencores driver by Marko Isomaki<br>
>> - *<br>
>> - * The license and distribution terms for this file may be<br>
>> - * found in found in the file LICENSE in this distribution or at<br>
>> - * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
>> - */<br>
>> -<br>
>> -#ifndef __GRETH_H__<br>
>> -#define __GRETH_H__<br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> -extern "C" {<br>
>> -#endif<br>
>> -<br>
>> -/* Ethernet configuration registers */<br>
>> -<br>
>> -typedef struct _greth_regs {<br>
>> - volatile uint32_t ctrl; /* Ctrl Register */<br>
>> - volatile uint32_t status; /* Status Register */<br>
>> - volatile uint32_t mac_addr_msb; /* Bit 47-32 of MAC address */<br>
>> - volatile uint32_t mac_addr_lsb; /* Bit 31-0 of MAC address */<br>
>> - volatile uint32_t mdio_ctrl; /* MDIO control and status */<br>
>> - volatile uint32_t txdesc; /* Transmit descriptor pointer */<br>
>> - volatile uint32_t rxdesc; /* Receive descriptor pointer */<br>
>> - volatile uint32_t edcl; /* EDCL IP register */<br>
>> - volatile uint32_t ht_msb; /* Multicast MSB hash */<br>
>> - volatile uint32_t ht_lsb; /* Multicast LSB hash */<br>
>> -} greth_regs;<br>
>> -<br>
>> -#define GRETH_TOTAL_BD 128<br>
>> -#define GRETH_MAXBUF_LEN 1520<br>
>> -<br>
>> -/* Tx BD */<br>
>> -#define GRETH_TXD_ENABLE 0x0800 /* Tx BD Enable */<br>
>> -#define GRETH_TXD_WRAP 0x1000 /* Tx BD Wrap (last BD) */<br>
>> -#define GRETH_TXD_IRQ 0x2000 /* Tx BD IRQ Enable */<br>
>> -#define GRETH_TXD_MORE 0x20000 /* Tx BD More (more descs for packet) */<br>
>> -#define GRETH_TXD_IPCS 0x40000 /* Tx BD insert ip chksum */<br>
>> -#define GRETH_TXD_TCPCS 0x80000 /* Tx BD insert tcp chksum */<br>
>> -#define GRETH_TXD_UDPCS 0x100000 /* Tx BD insert udp chksum */<br>
>> -<br>
>> -#define GRETH_TXD_UNDERRUN 0x4000 /* Tx BD Underrun Status */<br>
>> -#define GRETH_TXD_RETLIM 0x8000 /* Tx BD Retransmission Limit Status */<br>
>> -#define GRETH_TXD_LATECOL 0x10000 /* Tx BD Late Collision */<br>
>> -<br>
>> -#define GRETH_TXD_STATS (GRETH_TXD_UNDERRUN | \<br>
>> - GRETH_TXD_RETLIM | \<br>
>> - GRETH_TXD_LATECOL)<br>
>> -<br>
>> -#define GRETH_TXD_CS (GRETH_TXD_IPCS | \<br>
>> - GRETH_TXD_TCPCS | \<br>
>> - GRETH_TXD_UDPCS)<br>
>> -<br>
>> -/* Rx BD */<br>
>> -#define GRETH_RXD_ENABLE 0x0800 /* Rx BD Enable */<br>
>> -#define GRETH_RXD_WRAP 0x1000 /* Rx BD Wrap (last BD) */<br>
>> -#define GRETH_RXD_IRQ 0x2000 /* Rx BD IRQ Enable */<br>
>> -<br>
>> -#define GRETH_RXD_DRIBBLE 0x4000 /* Rx BD Dribble Nibble Status */<br>
>> -#define GRETH_RXD_TOOLONG 0x8000 /* Rx BD Too Long Status */<br>
>> -#define GRETH_RXD_CRCERR 0x10000 /* Rx BD CRC Error Status */<br>
>> -#define GRETH_RXD_OVERRUN 0x20000 /* Rx BD Overrun Status */<br>
>> -#define GRETH_RXD_LENERR 0x40000 /* Rx BD Length Error */<br>
>> -#define GRETH_RXD_ID 0x40000 /* Rx BD IP Detected */<br>
>> -#define GRETH_RXD_IR 0x40000 /* Rx BD IP Chksum Error */<br>
>> -#define GRETH_RXD_UD 0x40000 /* Rx BD UDP Detected*/<br>
>> -#define GRETH_RXD_UR 0x40000 /* Rx BD UDP Chksum Error */<br>
>> -#define GRETH_RXD_TD 0x40000 /* Rx BD TCP Detected */<br>
>> -#define GRETH_RXD_TR 0x40000 /* Rx BD TCP Chksum Error */<br>
>> -<br>
>> -<br>
>> -#define GRETH_RXD_STATS (GRETH_RXD_OVERRUN | \<br>
>> - GRETH_RXD_DRIBBLE | \<br>
>> - GRETH_RXD_TOOLONG | \<br>
>> - GRETH_RXD_CRCERR)<br>
>> -<br>
>> -/* CTRL Register */<br>
>> -#define GRETH_CTRL_TXEN 0x00000001 /* Transmit Enable */<br>
>> -#define GRETH_CTRL_RXEN 0x00000002 /* Receive Enable */<br>
>> -#define GRETH_CTRL_TXIRQ 0x00000004 /* Transmit Enable */<br>
>> -#define GRETH_CTRL_RXIRQ 0x00000008 /* Receive Enable */<br>
>> -#define GRETH_CTRL_FULLD 0x00000010 /* Full Duplex */<br>
>> -#define GRETH_CTRL_PRO 0x00000020 /* Promiscuous (receive all) */<br>
>> -#define GRETH_CTRL_RST 0x00000040 /* Reset MAC */<br>
>> -#define GRETH_CTRL_SP 0x00000080 /* 100MBit speed mode */<br>
>> -#define GRETH_CTRL_GB 0x00000100 /* 1GBit speed mode */<br>
>> -#define GRETH_CTRL_MCE 0x00000800 /* Multicast Enable */<br>
>> -#define GRETH_CTRL_DD 0x00001000 /* Disable EDCL Duplex Detection */<br>
>> -#define GRETH_CTRL_ED 0x00004000 /* EDCL Disable */<br>
>> -#define GRETH_CTRL_MC 0x02000000 /* Multicast available */<br>
>> -#define GRETH_CTRL_ME 0x04000000 /* MDIO interrupts enabled */<br>
>> -#define GRETH_CTRL_GA 0x08000000 /* Gigabit MAC available */<br>
>> -<br>
>> -/* Status Register */<br>
>> -#define GRETH_STATUS_RXERR 0x00000001 /* Receive Error */<br>
>> -#define GRETH_STATUS_TXERR 0x00000002 /* Transmit Error IRQ */<br>
>> -#define GRETH_STATUS_RXIRQ 0x00000004 /* Receive Frame IRQ */<br>
>> -#define GRETH_STATUS_TXIRQ 0x00000008 /* Transmit Error IRQ */<br>
>> -#define GRETH_STATUS_RXAHBERR 0x00000010 /* Receiver AHB Error */<br>
>> -#define GRETH_STATUS_TXAHBERR 0x00000020 /* Transmitter AHB Error */<br>
>> -#define GRETH_STATUS_NRD 0x0f000000 /* Number of descriptors */<br>
>> -<br>
>> -/* MDIO Control */<br>
>> -#define GRETH_MDIO_WRITE 0x00000001 /* MDIO Write */<br>
>> -#define GRETH_MDIO_READ 0x00000002 /* MDIO Read */<br>
>> -#define GRETH_MDIO_LINKFAIL 0x00000004 /* MDIO Link failed */<br>
>> -#define GRETH_MDIO_BUSY 0x00000008 /* MDIO Link Busy */<br>
>> -#define GRETH_MDIO_REGADR 0x000007C0 /* Register Address */<br>
>> -#define GRETH_MDIO_PHYADR 0x0000F800 /* PHY address */<br>
>> -#define GRETH_MDIO_DATA 0xFFFF0000 /* MDIO DATA */<br>
>> -<br>
>> -<br>
>> -/* MII registers */<br>
>> -#define GRETH_MII_EXTADV_1000FD 0x00000200<br>
>> -#define GRETH_MII_EXTADV_1000HD 0x00000100<br>
>> -#define GRETH_MII_EXTPRT_1000FD 0x00000800<br>
>> -#define GRETH_MII_EXTPRT_1000HD 0x00000400<br>
>> -<br>
>> -#define GRETH_MII_100T4 0x00000200<br>
>> -#define GRETH_MII_100TXFD 0x00000100<br>
>> -#define GRETH_MII_100TXHD 0x00000080<br>
>> -#define GRETH_MII_10FD 0x00000040<br>
>> -#define GRETH_MII_10HD 0x00000020<br>
>> -<br>
>> -<br>
>> -/* Attach routine */<br>
>> -<br>
>> -void greth_register_drv(void);<br>
>> -<br>
>> -/* PHY data */<br>
>> -struct phy_device_info<br>
>> -{<br>
>> - int vendor;<br>
>> - int device;<br>
>> - int rev;<br>
>> -<br>
>> - int adv;<br>
>> - int part;<br>
>> -<br>
>> - int extadv;<br>
>> - int extpart;<br>
>> -};<br>
>> -<br>
>> -/* Limit speed modes advertised during auto-negotiation */<br>
>> -#define GRETH_ADV_10_HD 0x0001<br>
>> -#define GRETH_ADV_10_FD 0x0002<br>
>> -#define GRETH_ADV_100_HD 0x0004<br>
>> -#define GRETH_ADV_100_FD 0x0008<br>
>> -#define GRETH_ADV_1000_HD 0x0010<br>
>> -#define GRETH_ADV_1000_FD 0x0020<br>
>> -#define GRETH_ADV_ALL 0x003f<br>
>> -/*<br>
>> -#ifdef CPU_U32_FIX<br>
>> -void ipalign(struct mbuf *m);<br>
>> -#endif<br>
>> -<br>
>> -*/<br>
>> -#ifdef __cplusplus<br>
>> -}<br>
>> -#endif<br>
>> -<br>
>> -#endif<br>
>> -<br>
>> diff --git a/bsps/include/grlib/network_interface_add.h b/bsps/include/grlib/network_interface_add.h<br>
>> deleted file mode 100644<br>
>> index b04a96f003..0000000000<br>
>> --- a/bsps/include/grlib/network_interface_add.h<br>
>> +++ /dev/null<br>
>> @@ -1,47 +0,0 @@<br>
>> -/* Network interface register help function<br>
>> - *<br>
>> - * COPYRIGHT (c) 2008.<br>
>> - * Cobham Gaisler AB.<br>
>> - *<br>
>> - * This function adds a network interface to the<br>
>> - * rtems_bsdnet_config.ifconfig linked list of interfaces.<br>
>> - * The interface configuration is taken from the user defined<br>
>> - * array interface_configs. This function is useful for PnP<br>
>> - * systems when an unknown number of interfaces are available.<br>
>> - *<br>
>> - * The license and distribution terms for this file may be<br>
>> - * found in found in the file LICENSE in this distribution or at<br>
>> - * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
>> - */<br>
>> -<br>
>> -#ifndef __NETWORK_INTERFACE_ADD_H__<br>
>> -#define __NETWORK_INTERFACE_ADD_H__<br>
>> -<br>
>> -#include <rtems/rtems_bsdnet.h><br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> -extern "C" {<br>
>> -#endif<br>
>> -<br>
>> -/* Interface configuration description */<br>
>> -struct ethernet_config {<br>
>> - char *ip_addr; /* IP address */<br>
>> - char *ip_netmask; /* IP Netmask */<br>
>> - char eth_adr[6]; /* Ethernet hardware MAC address */<br>
>> -};<br>
>> -<br>
>> -/* Array with configurations for all interfaces in the system<br>
>> - * Must be defined by the user.<br>
>> - */<br>
>> -extern struct ethernet_config interface_configs[];<br>
>> -<br>
>> -/* Routine adding interface to rtems_bsdnet_config.ifconfig linked<br>
>> - * list of interfaces.<br>
>> - */<br>
>> -int network_interface_add(struct rtems_bsdnet_ifconfig *interface);<br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> -}<br>
>> -#endif<br>
>> -<br>
>> -#endif /* _RTEMS_NETWORKCONFIG_H_ */<br>
>> diff --git a/bsps/powerpc/beatnik/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a> b/bsps/powerpc/beatnik/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> index 36df3cd759..364ea222a8 100644<br>
>> --- a/bsps/powerpc/beatnik/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> +++ b/bsps/powerpc/beatnik/<a href="http://headers.am" rel="noreferrer noreferrer" target="_blank">headers.am</a><br>
>> @@ -16,7 +16,4 @@ include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gti2cr<br>
>> include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtintrreg.h<br>
>> include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtpcireg.h<br>
>> include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/gtreg.h<br>
>> -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_em_pub.h<br>
>> -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h<br>
>> -include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/if_mve_pub.h<br>
>> include_bsp_HEADERS += ../../../../../../bsps/powerpc/beatnik/include/bsp/irq.h<br>
>> diff --git a/bsps/powerpc/beatnik/include/bsp/if_em_pub.h b/bsps/powerpc/beatnik/include/bsp/if_em_pub.h<br>
>> deleted file mode 100644<br>
>> index eb970e465b..0000000000<br>
>> --- a/bsps/powerpc/beatnik/include/bsp/if_em_pub.h<br>
>> +++ /dev/null<br>
>> @@ -1,22 +0,0 @@<br>
>> -#ifndef RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H<br>
>> -#define RTEMS_BSDNET_IF_EM_PUBLIC_SYMBOLS_H<br>
>> -<br>
>> -#include <rtems.h><br>
>> -#include <rtems/rtems_bsdnet.h><br>
>> -#include <bsp/early_enet_link_status.h><br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - extern "C" {<br>
>> -#endif<br>
>> -<br>
>> -extern int rtems_em_attach(struct rtems_bsdnet_ifconfig *, int);<br>
>> -extern int rtems_em_pci_setup(int);<br>
>> -extern rtems_bsdnet_early_link_check_ops rtems_em_early_link_check_ops;<br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - }<br>
>> -#endif<br>
>> -<br>
>> -#endif<br>
>> -<br>
>> -<br>
>> diff --git a/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h b/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h<br>
>> deleted file mode 100644<br>
>> index 8ea849efb1..0000000000<br>
>> --- a/bsps/powerpc/beatnik/include/bsp/if_gfe_pub.h<br>
>> +++ /dev/null<br>
>> @@ -1,30 +0,0 @@<br>
>> -#ifndef RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H<br>
>> -#define RTEMS_BSDNET_IF_GFE_PUBLIC_SYMBOLS_H<br>
>> -<br>
>> -#include <rtems.h><br>
>> -#include <rtems/rtems_bsdnet.h><br>
>> -#include <bsp/early_enet_link_status.h><br>
>> -#include <net/ethernet.h><br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - extern "C" {<br>
>> -#endif<br>
>> -<br>
>> -extern int<br>
>> -rtems_gfe_attach(struct rtems_bsdnet_ifconfig *, int);<br>
>> -<br>
>> -<br>
>> -/* enet_addr must be 6 bytes long */<br>
>> -int<br>
>> -rtems_gfe_setup(int unit, char *enet_addr, uint32_t base_addr);<br>
>> -<br>
>> -extern rtems_bsdnet_early_link_check_ops<br>
>> -rtems_gfe_early_link_check_ops;<br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - }<br>
>> -#endif<br>
>> -<br>
>> -#endif<br>
>> -<br>
>> -<br>
>> diff --git a/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h b/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h<br>
>> deleted file mode 100644<br>
>> index 46cc4ccd23..0000000000<br>
>> --- a/bsps/powerpc/beatnik/include/bsp/if_mve_pub.h<br>
>> +++ /dev/null<br>
>> @@ -1,426 +0,0 @@<br>
>> -#ifndef RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H<br>
>> -#define RTEMS_BSDNET_IF_MVE_PUBLIC_SYMBOLS_H<br>
>> -<br>
>> -/*<br>
>> - * Authorship<br>
>> - * ----------<br>
>> - * This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was<br>
>> - * created by Till Straumann <<a href="mailto:strauman@slac.stanford.edu" target="_blank" rel="noreferrer">strauman@slac.stanford.edu</a>>, 2005-2007,<br>
>> - * Stanford Linear Accelerator Center, Stanford University.<br>
>> - *<br>
>> - * Acknowledgement of sponsorship<br>
>> - * ------------------------------<br>
>> - * The 'beatnik' BSP was produced by<br>
>> - * the Stanford Linear Accelerator Center, Stanford University,<br>
>> - * under Contract DE-AC03-76SFO0515 with the Department of Energy.<br>
>> - *<br>
>> - * Government disclaimer of liability<br>
>> - * ----------------------------------<br>
>> - * Neither the United States nor the United States Department of Energy,<br>
>> - * nor any of their employees, makes any warranty, express or implied, or<br>
>> - * assumes any legal liability or responsibility for the accuracy,<br>
>> - * completeness, or usefulness of any data, apparatus, product, or process<br>
>> - * disclosed, or represents that its use would not infringe privately owned<br>
>> - * rights.<br>
>> - *<br>
>> - * Stanford disclaimer of liability<br>
>> - * --------------------------------<br>
>> - * Stanford University makes no representations or warranties, express or<br>
>> - * implied, nor assumes any liability for the use of this software.<br>
>> - *<br>
>> - * Stanford disclaimer of copyright<br>
>> - * --------------------------------<br>
>> - * Stanford University, owner of the copyright, hereby disclaims its<br>
>> - * copyright and all other rights in this software. Hence, anyone may<br>
>> - * freely use it for any purpose without restriction.<br>
>> - *<br>
>> - * Maintenance of notices<br>
>> - * ----------------------<br>
>> - * In the interest of clarity regarding the origin and status of this<br>
>> - * SLAC software, this and all the preceding Stanford University notices<br>
>> - * are to remain affixed to any copy or derivative of this software made<br>
>> - * or distributed by the recipient and are to be affixed to any copy of<br>
>> - * software made or distributed by the recipient that contains a copy or<br>
>> - * derivative of this software.<br>
>> - *<br>
>> - * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03<br>
>> - */<br>
>> -#include <rtems.h><br>
>> -#include <rtems/rtems_bsdnet.h><br>
>> -#include <bsp/early_enet_link_status.h><br>
>> -#include <stdint.h><br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - extern "C" {<br>
>> -#endif<br>
>> -<br>
>> -extern int rtems_mve_attach(struct rtems_bsdnet_ifconfig *, int);<br>
>> -extern rtems_bsdnet_early_link_check_ops rtems_mve_early_link_check_ops;<br>
>> -<br>
>> -/* Low-level Driver API.<br>
>> - * This provides driver access to applications that want to use e.g., the second<br>
>> - * ethernet interface w/o running the BSD TCP/IP stack.<br>
>> - */<br>
>> -<br>
>> -/* Opaque handle */<br>
>> -struct mveth_private;<br>
>> -<br>
>> -/* Direct assignment of MVE flags to user API relies on irqs and x-irqs not overlapping */<br>
>> -#define BSP_MVE_IRQ_RX (1<<2)<br>
>> -#define BSP_MVE_IRQ_TX (1<<0)<br>
>> -#define BSP_MVE_IRQ_LINK (1<<16)<br>
>> -<br>
>> -/* Setup an interface.<br>
>> - * Allocates resources for descriptor rings and sets up the driver software structure.<br>
>> - *<br>
>> - * Arguments:<br>
>> - * unit:<br>
>> - * interface # (1..2). The interface must not be attached to BSD.<br>
>> - *<br>
>> - * driver_tid:<br>
>> - * ISR posts RTEMS event # ('unit' - 1) to task with ID 'driver_tid' and disables interrupts<br>
>> - * from this interface.<br>
>> - *<br>
>> - * void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred):<br>
>> - * Pointer to user-supplied callback to release a buffer that had been sent<br>
>> - * by BSP_mve_send_buf() earlier. The callback is passed 'cleanup_txbuf_arg'<br>
>> - * and a flag indicating whether the send had been successful.<br>
>> - * The driver no longer accesses 'user_buf' after invoking this callback.<br>
>> - * CONTEXT: This callback is executed either by BSP_mve_swipe_tx() or<br>
>> - * BSP_mve_send_buf(), BSP_mve_init_hw(), BSP_mve_stop_hw() (the latter<br>
>> - * ones calling BSP_mve_swipe_tx()).<br>
>> - * void *cleanup_txbuf_arg:<br>
>> - * Closure argument that is passed on to 'cleanup_txbuf()' callback;<br>
>> - *<br>
>> - * void *(*alloc_rxbuf)(int *p_size, unsigned long *p_data_addr),<br>
>> - * Pointer to user-supplied callback to allocate a buffer for subsequent<br>
>> - * insertion into the RX ring by the driver.<br>
>> - * RETURNS: opaque handle to the buffer (which may be a more complex object<br>
>> - * such as an 'mbuf'). The handle is not used by the driver directly<br>
>> - * but passed back to the 'consume_rxbuf()' callback.<br>
>> - * Size of the available data area and pointer to buffer's data area<br>
>> - * in '*psize' and '*p_data_area', respectively.<br>
>> - * If no buffer is available, this routine should return NULL in which<br>
>> - * case the driver drops the last packet and re-uses the last buffer<br>
>> - * instead of handing it out to 'consume_rxbuf()'.<br>
>> - * CONTEXT: Called when initializing the RX ring (BSP_mve_init_hw()) or when<br>
>> - * swiping it (BSP_mve_swipe_rx()).<br>
>> - *<br>
>> - *<br>
>> - * void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len);<br>
>> - * Pointer to user-supplied callback to pass a received buffer back to<br>
>> - * the user. The driver no longer accesses the buffer after invoking this<br>
>> - * callback (with 'len'>0, see below). 'user_buf' is the buffer handle<br>
>> - * previously generated by 'alloc_rxbuf()'.<br>
>> - * The callback is passed 'cleanup_rxbuf_arg' and a 'len'<br>
>> - * argument giving the number of bytes that were received.<br>
>> - * 'len' may be <=0 in which case the 'user_buf' argument is NULL.<br>
>> - * 'len' == 0 means that the last 'alloc_rxbuf()' had failed,<br>
>> - * 'len' < 0 indicates a receiver error. In both cases, the last packet<br>
>> - * was dropped/missed and the last buffer will be re-used by the driver.<br>
>> - * NOTE: the data are 'prefixed' with two bytes, i.e., the ethernet packet header<br>
>> - * is stored at offset 2 in the buffer's data area. Also, the FCS (4 bytes)<br>
>> - * is appended. 'len' accounts for both.<br>
>> - * CONTEXT: Called from BSP_mve_swipe_rx().<br>
>> - * void *cleanup_rxbuf_arg:<br>
>> - * Closure argument that is passed on to 'consume_rxbuf()' callback;<br>
>> - *<br>
>> - * rx_ring_size, tx_ring_size:<br>
>> - * How many big to make the RX and TX descriptor rings. Note that the sizes<br>
>> - * may be 0 in which case a reasonable default will be used.<br>
>> - * If either ring size is < 0 then the RX or TX will be disabled.<br>
>> - * Note that it is illegal in this case to use BSP_mve_swipe_rx() or<br>
>> - * BSP_mve_swipe_tx(), respectively.<br>
>> - *<br>
>> - * irq_mask:<br>
>> - * Interrupts to enable. OR of flags from above.<br>
>> - *<br>
>> - */<br>
>> -struct mveth_private *<br>
>> -BSP_mve_setup(<br>
>> - int unit,<br>
>> - rtems_id driver_tid,<br>
>> - void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),<br>
>> - void *cleanup_txbuf_arg,<br>
>> - void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),<br>
>> - void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),<br>
>> - void *consume_rxbuf_arg,<br>
>> - int rx_ring_size,<br>
>> - int tx_ring_size,<br>
>> - int irq_mask<br>
>> -);<br>
>> -<br>
>> -/*<br>
>> - * Alternate 'setup' routine allowing the user to install an ISR rather<br>
>> - * than a task ID.<br>
>> - * All parameters (other than 'isr' / 'isr_arg') and the return value<br>
>> - * are identical to the BSP_mve_setup() entry point.<br>
>> - */<br>
>> -struct mveth_private *<br>
>> -BSP_mve_setup_1(<br>
>> - int unit,<br>
>> - void (*isr)(void *isr_arg),<br>
>> - void *isr_arg,<br>
>> - void (*cleanup_txbuf)(void *user_buf, void *cleanup_txbuf_arg, int error_on_tx_occurred),<br>
>> - void *cleanup_txbuf_arg,<br>
>> - void *(*alloc_rxbuf)(int *p_size, uintptr_t *p_data_addr),<br>
>> - void (*consume_rxbuf)(void *user_buf, void *consume_rxbuf_arg, int len),<br>
>> - void *consume_rxbuf_arg,<br>
>> - int rx_ring_size,<br>
>> - int tx_ring_size,<br>
>> - int irq_mask<br>
>> -);<br>
>> -<br>
>> -<br>
>> -/*<br>
>> - * Initialize interface hardware<br>
>> - *<br>
>> - * 'mp' handle obtained by from BSP_mve_setup().<br>
>> - * 'promisc' whether to set promiscuous flag.<br>
>> - * 'enaddr' pointer to six bytes with MAC address. Read<br>
>> - * from the device if NULL.<br>
>> - *<br>
>> - * Note: Multicast filters are cleared by this routine.<br>
>> - * However, in promiscuous mode the mcast filters<br>
>> - * are programmed to accept all multicast frames.<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_init_hw(struct mveth_private *mp, int promisc, unsigned char *enaddr);<br>
>> -<br>
>> -/*<br>
>> - * Clear multicast hash filter. No multicast frames are accepted<br>
>> - * after executing this routine (unless the hardware was initialized<br>
>> - * in 'promiscuous' mode).<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_mcast_filter_clear(struct mveth_private *mp);<br>
>> -<br>
>> -/*<br>
>> - * Program multicast filter to accept all multicast frames<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_mcast_filter_accept_all(struct mveth_private *mp);<br>
>> -<br>
>> -/*<br>
>> - * Add a MAC address to the multicast filter.<br>
>> - * Existing entries are not changed but note that<br>
>> - * the filter is imperfect, i.e., multiple MAC addresses<br>
>> - * may alias to a single filter entry. Hence software<br>
>> - * filtering must still be performed.<br>
>> - *<br>
>> - * If a higher-level driver implements IP multicasting<br>
>> - * then multiple IP addresses may alias to the same MAC<br>
>> - * address. This driver maintains a 'reference-count'<br>
>> - * which is incremented every time the same MAC-address<br>
>> - * is passed to this routine; the address is only removed<br>
>> - * from the filter if BSP_mve_mcast_filter_accept_del()<br>
>> - * is called the same number of times (or by BSP_mve_mcast_filter_clear).<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_mcast_filter_accept_add(struct mveth_private *mp, unsigned char *enaddr);<br>
>> -<br>
>> -/*<br>
>> - * Remove a MAC address from the multicast filter.<br>
>> - * This routine decrements the reference count of the given<br>
>> - * MAC-address and removes it from the filter once the<br>
>> - * count reaches zero.<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_mcast_filter_accept_del(struct mveth_private *mp, unsigned char *enaddr);<br>
>> -<br>
>> -/*<br>
>> - * Shutdown hardware and clean out the rings<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_stop_hw(struct mveth_private *mp);<br>
>> -<br>
>> -/* calls BSP_mve_stop_hw(), releases all resources and marks the interface<br>
>> - * as unused.<br>
>> - * RETURNS 0 on success, nonzero on failure.<br>
>> - * NOTE: the handle MUST NOT be used after successful execution of this<br>
>> - * routine.<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_detach(struct mveth_private *mp);<br>
>> -<br>
>> -int<br>
>> -BSP_mve_send_buf_raw(struct mveth_private *mp, void *head_p, int h_len,<br>
>> - void *data_p, int d_len);<br>
>> -<br>
>> -/*<br>
>> - * Enqueue a mbuf chain or a raw data buffer for transmission;<br>
>> - * RETURN: #bytes sent or -1 if there are not enough free descriptors<br>
>> - *<br>
>> - * If 'len' is <=0 then 'm_head' is assumed to point to a mbuf chain.<br>
>> - * OTOH, a raw data packet (or a different type of buffer)<br>
>> - * may be send (non-BSD driver) by pointing data_p to the start of<br>
>> - * the data and passing 'len' > 0.<br>
>> - * 'm_head' is passed back to the 'cleanup_txbuf()' callback.<br>
>> - *<br>
>> - * Comments: software cache-flushing incurs a penalty if the<br>
>> - * packet cannot be queued since it is flushed anyways.<br>
>> - * The algorithm is slightly more efficient in the normal<br>
>> - * case, though.<br>
>> - *<br>
>> - * RETURNS: # bytes enqueued to device for transmission or -1 if no<br>
>> - * space in the TX ring was available.<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_send_buf(struct mveth_private *mp, void *m_head, void *data_p, int len);<br>
>> -<br>
>> -/* Descriptor scavenger; cleanup the TX ring, passing all buffers<br>
>> - * that have been sent to the cleanup_tx() callback.<br>
>> - * This routine is called from BSP_mve_send_buf(), BSP_mve_init_hw(),<br>
>> - * BSP_mve_stop_hw().<br>
>> - *<br>
>> - * RETURNS: number of buffers processed.<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_swipe_tx(struct mveth_private *mp);<br>
>> -<br>
>> -/* Retrieve all received buffers from the RX ring, replacing them<br>
>> - * by fresh ones (obtained from the alloc_rxbuf() callback). The<br>
>> - * received buffers are passed to consume_rxbuf().<br>
>> - *<br>
>> - * RETURNS: number of buffers processed.<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_swipe_rx(struct mveth_private *mp);<br>
>> -<br>
>> -/* read ethernet address from hw to buffer */<br>
>> -void<br>
>> -BSP_mve_read_eaddr(struct mveth_private *mp, unsigned char *eaddr);<br>
>> -<br>
>> -/* read/write media word.<br>
>> - * 'cmd': can be SIOCGIFMEDIA, SIOCSIFMEDIA, 0 or 1. The latter<br>
>> - * are aliased to the former for convenience.<br>
>> - * 'parg': pointer to media word.<br>
>> - *<br>
>> - * RETURNS: 0 on success, nonzero on error<br>
>> - *<br>
>> - * NOTE: This routine is thread-safe.<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_media_ioctl(struct mveth_private *mp, int cmd, int *parg);<br>
>> -<br>
>> -/* Interrupt related routines */<br>
>> -<br>
>> -/* Note: the BSP_mve_enable/disable/ack_irqs() entry points<br>
>> - * are deprecated.<br>
>> - * The newer API where the user passes a mask allows<br>
>> - * for more selective control.<br>
>> - */<br>
>> -<br>
>> -/* Enable all supported interrupts at device */<br>
>> -void<br>
>> -BSP_mve_enable_irqs(struct mveth_private *mp);<br>
>> -<br>
>> -/* Disable all supported interrupts at device */<br>
>> -void<br>
>> -BSP_mve_disable_irqs(struct mveth_private *mp);<br>
>> -<br>
>> -/* Acknowledge (and clear) all supported interrupts.<br>
>> - * RETURNS: interrupts that were raised.<br>
>> - */<br>
>> -uint32_t<br>
>> -BSP_mve_ack_irqs(struct mveth_private *mp);<br>
>> -<br>
>> -/* Enable interrupts included in 'mask' (leaving<br>
>> - * already enabled interrupts on). If the mask<br>
>> - * includes bits that were not passed to the 'setup'<br>
>> - * routine then the behavior is undefined.<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_enable_irq_mask(struct mveth_private *mp, uint32_t irq_mask);<br>
>> -<br>
>> -/* Disable interrupts included in 'mask' (leaving<br>
>> - * other ones that are currently enabled on). If the<br>
>> - * mask includes bits that were not passed to the 'setup'<br>
>> - * routine then the behavior is undefined.<br>
>> - *<br>
>> - * RETURNS: Bitmask of interrupts that were enabled upon entry<br>
>> - * into this routine. This can be used to restore the<br>
>> - * previous state.<br>
>> - */<br>
>> -uint32_t<br>
>> -BSP_mve_disable_irq_mask(struct mveth_private *mp, uint32_t irq_mask);<br>
>> -<br>
>> -/* Acknowledge and clear selected interrupts.<br>
>> - *<br>
>> - * RETURNS: All pending interrupts.<br>
>> - *<br>
>> - * NOTE: Only pending interrupts contained in 'mask'<br>
>> - * are cleared. Others are left pending.<br>
>> - *<br>
>> - * This routine can be used to check for pending<br>
>> - * interrupts (pass mask == 0) or to clear all<br>
>> - * interrupts (pass mask == -1).<br>
>> - */<br>
>> -uint32_t<br>
>> -BSP_mve_ack_irq_mask(struct mveth_private *mp, uint32_t mask);<br>
>> -<br>
>> -/* If the PHY link status changes then some<br>
>> - * internal settings in the ethernet controller's<br>
>> - * serial port need to be updated to match the<br>
>> - * PHY settings. Use this routine to perform the<br>
>> - * necessary steps after a link change has been<br>
>> - * detected.<br>
>> - *<br>
>> - * RETURNS: 0 on success, -1 if the PHY state<br>
>> - * could not be determined.<br>
>> - *<br>
>> - * The current state of the media as read<br>
>> - * by BSP_mve_media_ioctl() is returned in<br>
>> - * *pmedia.<br>
>> - *<br>
>> - * NOTE: This routine calls BSP_mve_media_ioctl().<br>
>> - */<br>
>> -int<br>
>> -BSP_mve_ack_link_chg(struct mveth_private *mp, int *pmedia);<br>
>> -<br>
>> -/* Retrieve the driver daemon TID that was passed to<br>
>> - * BSP_mve_setup().<br>
>> - */<br>
>> -<br>
>> -rtems_id<br>
>> -BSP_mve_get_tid(struct mveth_private *mp);<br>
>> -<br>
>> -/* Dump statistics to file (stdout if NULL)<br>
>> - *<br>
>> - * NOTE: this routine is not thread safe<br>
>> - */<br>
>> -void<br>
>> -BSP_mve_dump_stats(struct mveth_private *mp, FILE *f);<br>
>> -<br>
>> -/*<br>
>> - *<br>
>> - * Example driver task loop (note: no synchronization of<br>
>> - * buffer access shown!).<br>
>> - * RTEMS_EVENTx = 0,1 or 2 depending on IF unit.<br>
>> - *<br>
>> - * / * setup (obtain handle) and initialize hw here * /<br>
>> - *<br>
>> - * do {<br>
>> - * / * ISR disables IRQs and posts event * /<br>
>> - * rtems_event_receive( RTEMS_EVENTx, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &evs );<br>
>> - * irqs = BSP_mve_ack_irqs(handle);<br>
>> - * if ( irqs & BSP_MVE_IRQ_TX ) {<br>
>> - * BSP_mve_swipe_tx(handle); / * cleanup_txbuf() callback executed * /<br>
>> - * }<br>
>> - * if ( irqs & BSP_MVE_IRQ_RX ) {<br>
>> - * BSP_mve_swipe_rx(handle); / * alloc_rxbuf() and consume_rxbuf() executed * /<br>
>> - * }<br>
>> - * if ( irqs & BSP_MVE_IRQ_LINK ) {<br>
>> - * / * update serial port settings from current link status * /<br>
>> - * BSP_mve_ack_link_chg(handle, 0);<br>
>> - * }<br>
>> - * BSP_mve_enable_irqs(handle);<br>
>> - * } while (1);<br>
>> - *<br>
>> - */<br>
>> -<br>
>> -#ifdef __cplusplus<br>
>> - }<br>
>> -#endif<br>
>> -<br>
>> -#endif<br>
>> diff --git a/bsps/shared/grlib/net/greth.c b/bsps/shared/grlib/net/greth.c<br>
>> deleted file mode 100644<br>
>> index 84efcd74ab..0000000000<br>
>> --- a/bsps/shared/grlib/net/greth.c<br>
>> +++ /dev/null<br>
>> @@ -1,1663 +0,0 @@<br>
>> -/*<br>
>> - * Gaisler Research ethernet MAC driver<br>
>> - * adapted from Opencores driver by Marko Isomaki<br>
>> - *<br>
>> - * The license and distribution terms for this file may be<br>
>> - * found in found in the file LICENSE in this distribution or at<br>
>> - * <a href="http://www.rtems.org/license/LICENSE" rel="noreferrer noreferrer" target="_blank">http://www.rtems.org/license/LICENSE</a>.<br>
>> - *<br>
>> - *<br>
>> - * 2008-12-10, Converted to driver manager and added support for<br>
>> - * multiple GRETH cores. <<a href="mailto:daniel@gaisler.com" target="_blank" rel="noreferrer">daniel@gaisler.com</a>><br>
>> - * 2007-09-07, Ported GBIT support from 4.6.5<br>
>> - */<br>
>> -<br>
>> -#include <machine/rtems-bsd-kernel-space.h><br>
>> -<br>
>> -#include <rtems.h><br>
>> -#define CPU_U32_FIX<br>
>> -#include <bsp.h><br>
>> -<br>
>> -#ifdef GRETH_SUPPORTED<br>
>> -<br>
>> -#include <inttypes.h><br>
>> -#include <errno.h><br>
>> -#include <rtems/bspIo.h><br>
>> -#include <stdlib.h><br>
>> -#include <stdio.h><br>
>> -#include <string.h><br>
>> -#include <stdarg.h><br>
>> -#include <rtems/error.h><br>
>> -#include <rtems/rtems_bsdnet.h><br>
>> -<br>
>> -#include <grlib/greth.h><br>
>> -#include <drvmgr/drvmgr.h><br>
>> -#include <grlib/ambapp_bus.h><br>
>> -#include <grlib/ambapp.h><br>
>> -<br>
>> -#include <sys/param.h><br>
>> -#include <sys/mbuf.h><br>
>> -<br>
>> -#include <sys/socket.h><br>
>> -#include <sys/sockio.h><br>
>> -#include <net/if.h><br>
>> -#include <netinet/in.h><br>
>> -#include <netinet/if_ether.h><br>
>> -<br>
>> -#ifdef malloc<br>
>> -#undef malloc<br>
>> -#endif<br>
>> -#ifdef free<br>
>> -#undef free<br>
>> -#endif<br>
>> -<br>
>> -#include <grlib/grlib_impl.h><br>
>> -<br>
>> -#if defined(__m68k__)<br>
>> -extern m68k_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );<br>
>> -#else<br>
>> -extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );<br>
>> -#endif<br>
>> -<br>
>> -<br>
>> -/* #define GRETH_DEBUG */<br>
>> -<br>
>> -#ifdef GRETH_DEBUG<br>
>> -#define DBG(args...) printk(args)<br>
>> -#else<br>
>> -#define DBG(args...)<br>
>> -#endif<br>
>> -<br>
>> -/* #define GRETH_DEBUG_MII */<br>
>> -<br>
>> -#ifdef GRETH_DEBUG_MII<br>
>> -#define MIIDBG(args...) printk(args)<br>
>> -#else<br>
>> -#define MIIDBG(args...)<br>
>> -#endif<br>
>> -<br>
>> -#ifdef CPU_U32_FIX<br>
>> -extern void ipalign(struct mbuf *m);<br>
>> -#endif<br>
>> -<br>
>> -/* Used when reading from memory written by GRETH DMA unit */<br>
>> -#ifndef GRETH_MEM_LOAD<br>
>> -#define GRETH_MEM_LOAD(addr) (*(volatile unsigned int *)(addr))<br>
>> -#endif<br>
>> -<br>
>> -/*<br>
>> - * Number of OCs supported by this driver<br>
>> - */<br>
>> -#define NOCDRIVER 1<br>
>> -<br>
>> -/*<br>
>> - * Receive buffer size -- Allow for a full ethernet packet including CRC<br>
>> - */<br>
>> -#define RBUF_SIZE 1518<br>
>> -<br>
>> -#define ET_MINLEN 64 /* minimum message length */<br>
>> -<br>
>> -/*<br>
>> - * RTEMS event used by interrupt handler to signal driver tasks.<br>
>> - * This must not be any of the events used by the network task synchronization.<br>
>> - */<br>
>> -#define INTERRUPT_EVENT RTEMS_EVENT_1<br>
>> -<br>
>> -/*<br>
>> - * RTEMS event used to start transmit daemon.<br>
>> - * This must not be the same as INTERRUPT_EVENT.<br>
>> - */<br>
>> -#define START_TRANSMIT_EVENT RTEMS_EVENT_2<br>
>> -<br>
>> - /* event to send when tx buffers become available */<br>
>> -#define GRETH_TX_WAIT_EVENT RTEMS_EVENT_3<br>
>> -<br>
>> -#if (MCLBYTES < RBUF_SIZE)<br>
>> -# error "Driver must have MCLBYTES > RBUF_SIZE"<br>
>> -#endif<br>
>> -<br>
>> -/* 4s Autonegotiation Timeout */<br>
>> -#ifndef GRETH_AUTONEGO_TIMEOUT_MS<br>
>> -#define GRETH_AUTONEGO_TIMEOUT_MS 4000<br>
>> -#endif<br>
>> -const struct timespec greth_tan = {<br>
>> - GRETH_AUTONEGO_TIMEOUT_MS/1000,<br>
>> - (GRETH_AUTONEGO_TIMEOUT_MS % 1000) * 1000000<br>
>> -};<br>
>> -<br>
>> -/* For optimizing the autonegotiation time */<br>
>> -#define GRETH_AUTONEGO_PRINT_TIME<br>
>> -<br>
>> -/* Ethernet buffer descriptor */<br>
>> -<br>
>> -typedef struct _greth_rxtxdesc {<br>
>> - volatile uint32_t ctrl; /* Length and status */<br>
>> - uint32_t *addr; /* Buffer pointer */<br>
>> -} greth_rxtxdesc;<br>
>> -<br>
>> -<br>
>> -/*<br>
>> - * Per-device data<br>
>> - */<br>
>> -struct greth_softc<br>
>> -{<br>
>> -<br>
>> - struct arpcom arpcom;<br>
>> - struct drvmgr_dev *dev; /* Driver manager device */<br>
>> - char devName[32];<br>
>> -<br>
>> - greth_regs *regs;<br>
>> - int minor;<br>
>> - int phyaddr; /* PHY Address configured by user (or -1 to autodetect) */<br>
>> - unsigned int edcl_dis;<br>
>> - int greth_rst;<br>
>> -<br>
>> - int acceptBroadcast;<br>
>> - rtems_id daemonTid;<br>
>> -<br>
>> - unsigned int tx_ptr;<br>
>> - unsigned int tx_dptr;<br>
>> - unsigned int tx_cnt;<br>
>> - unsigned int rx_ptr;<br>
>> - unsigned int txbufs;<br>
>> - unsigned int rxbufs;<br>
>> - greth_rxtxdesc *txdesc;<br>
>> - greth_rxtxdesc *rxdesc;<br>
>> - unsigned int txdesc_remote;<br>
>> - unsigned int rxdesc_remote;<br>
>> - struct mbuf **rxmbuf;<br>
>> - struct mbuf **txmbuf;<br>
>> - rtems_vector_number vector;<br>
>> -<br>
>> - /* TX descriptor interrupt generation */<br>
>> - int tx_int_gen;<br>
>> - int tx_int_gen_cur;<br>
>> - struct mbuf *next_tx_mbuf;<br>
>> - int max_fragsize;<br>
>> -<br>
>> - /*Status*/<br>
>> - struct phy_device_info phydev;<br>
>> - int phy_read_access;<br>
>> - int phy_write_access;<br>
>> - int fd;<br>
>> - int sp;<br>
>> - int gb;<br>
>> - int gbit_mac;<br>
>> - int auto_neg;<br>
>> - unsigned int advmodes; /* advertise ethernet speed modes. 0 = all modes. */<br>
>> - struct timespec auto_neg_time;<br>
>> - int mc_available;<br>
>> - int num_descs;<br>
>> -<br>
>> - /*<br>
>> - * Statistics<br>
>> - */<br>
>> - unsigned long rxInterrupts;<br>
>> -<br>
>> - unsigned long rxPackets;<br>
>> - unsigned long rxLengthError;<br>
>> - unsigned long rxNonOctet;<br>
>> - unsigned long rxBadCRC;<br>
>> - unsigned long rxOverrun;<br>
>> -<br>
>> - unsigned long txInterrupts;<br>
>> -<br>
>> - unsigned long txDeferred;<br>
>> - unsigned long txHeartbeat;<br>
>> - unsigned long txLateCollision;<br>
>> - unsigned long txRetryLimit;<br>
>> - unsigned long txUnderrun;<br>
>> -<br>
>> - /* Spin-lock ISR protection */<br>
>> - SPIN_DECLARE(devlock);<br>
>> -};<br>
>> -<br>
>> -int greth_process_tx_gbit(struct greth_softc *sc);<br>
>> -int greth_process_tx(struct greth_softc *sc);<br>
>> -<br>
>> -static char *almalloc(int sz, int alignment)<br>
>> -{<br>
>> - char *tmp;<br>
>> - tmp = grlib_calloc(1, sz + (alignment-1));<br>
>> - tmp = (char *) (((int)tmp+alignment) & ~(alignment -1));<br>
>> - return(tmp);<br>
>> -}<br>
>> -<br>
>> -/* GRETH interrupt handler */<br>
>> -<br>
>> -static void greth_interrupt (void *arg)<br>
>> -{<br>
>> - uint32_t status;<br>
>> - uint32_t ctrl;<br>
>> - rtems_event_set events = 0;<br>
>> - struct greth_softc *greth = arg;<br>
>> - SPIN_ISR_IRQFLAGS(flags);<br>
>> -<br>
>> - /* read and clear interrupt cause */<br>
>> - status = greth->regs->status;<br>
>> - greth->regs->status = status;<br>
>> -<br>
>> - SPIN_LOCK(&greth->devlock, flags);<br>
>> - ctrl = greth->regs->ctrl;<br>
>> -<br>
>> - /* Frame received? */<br>
>> - if ((ctrl & GRETH_CTRL_RXIRQ) && (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ)))<br>
>> - {<br>
>> - greth->rxInterrupts++;<br>
>> - /* Stop RX-Error and RX-Packet interrupts */<br>
>> - ctrl &= ~GRETH_CTRL_RXIRQ;<br>
>> - events |= INTERRUPT_EVENT;<br>
>> - }<br>
>> -<br>
>> - if ( (ctrl & GRETH_CTRL_TXIRQ) && (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) )<br>
>> - {<br>
>> - greth->txInterrupts++;<br>
>> - ctrl &= ~GRETH_CTRL_TXIRQ;<br>
>> - events |= GRETH_TX_WAIT_EVENT;<br>
>> - }<br>
>> -<br>
>> - /* Clear interrupt sources */<br>
>> - greth->regs->ctrl = ctrl;<br>
>> - SPIN_UNLOCK(&greth->devlock, flags);<br>
>> -<br>
>> - /* Send the event(s) */<br>
>> - if ( events )<br>
>> - rtems_bsdnet_event_send(greth->daemonTid, events);<br>
>> -}<br>
>> -<br>
>> -static uint32_t read_mii(struct greth_softc *sc, uint32_t phy_addr, uint32_t reg_addr)<br>
>> -{<br>
>> - sc->phy_read_access++;<br>
>> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}<br>
>> - sc->regs->mdio_ctrl = (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_READ;<br>
>> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}<br>
>> - if (!(sc->regs->mdio_ctrl & GRETH_MDIO_LINKFAIL)) {<br>
>> - MIIDBG("greth%d: mii read[%d] OK to %" PRIx32 ".%" PRIx32<br>
>> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",<br>
>> - sc->minor, sc->phy_read_access, phy_addr, reg_addr,<br>
>> - sc->regs->ctrl, sc->regs->mdio_ctrl);<br>
>> - return((sc->regs->mdio_ctrl >> 16) & 0xFFFF);<br>
>> - } else {<br>
>> - printf("greth%d: mii read[%d] failed to %" PRIx32 ".%" PRIx32<br>
>> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",<br>
>> - sc->minor, sc->phy_read_access, phy_addr, reg_addr,<br>
>> - sc->regs->ctrl, sc->regs->mdio_ctrl);<br>
>> - return (0xffff);<br>
>> - }<br>
>> -}<br>
>> -<br>
>> -static void write_mii(struct greth_softc *sc, uint32_t phy_addr, uint32_t reg_addr, uint32_t data)<br>
>> -{<br>
>> - sc->phy_write_access++;<br>
>> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}<br>
>> - sc->regs->mdio_ctrl =<br>
>> - ((data & 0xFFFF) << 16) | (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_WRITE;<br>
>> - while (sc->regs->mdio_ctrl & GRETH_MDIO_BUSY) {}<br>
>> - if (!(sc->regs->mdio_ctrl & GRETH_MDIO_LINKFAIL)) {<br>
>> - MIIDBG("greth%d: mii write[%d] OK to to %" PRIx32 ".%" PRIx32<br>
>> - "(0x%08" PRIx32 ",0x%08" PRIx32 ")\n",<br>
>> - sc->minor, sc->phy_write_access, phy_addr, reg_addr,<br>
>> - sc->regs->ctrl, sc->regs->mdio_ctrl);<br>
>> - } else {<br>
>> - printf("greth%d: mii write[%d] failed to to %" PRIx32 ".%" PRIx32<br>
>> - " (0x%08" PRIx32 ",0x%08" PRIx32 ")\n",<br>
>> - sc->minor, sc->phy_write_access, phy_addr, reg_addr,<br>
>> - sc->regs->ctrl, sc->regs->mdio_ctrl);<br>
>> - }<br>
>> -}<br>
>> -<br>
>> -static void print_init_info(struct greth_softc *sc)<br>
>> -{<br>
>> - printf("greth: driver attached\n");<br>
>> - if ( sc->auto_neg == -1 ){<br>
>> - printf("Auto negotiation timed out. Selecting default config\n");<br>
>> - }<br>
>> - printf("**** PHY ****\n");<br>
>> - printf("Vendor: %x Device: %x Revision: %d\n",sc->phydev.vendor, sc->phydev.device, sc->phydev.rev);<br>
>> - printf("Current Operating Mode: ");<br>
>> - if (sc->gb) {<br>
>> - printf("1000 Mbit ");<br>
>> - } else if (sc->sp) {<br>
>> - printf("100 Mbit ");<br>
>> - } else {<br>
>> - printf("10 Mbit ");<br>
>> - }<br>
>> - if (sc->fd) {<br>
>> - printf("Full Duplex\n");<br>
>> - } else {<br>
>> - printf("Half Duplex\n");<br>
>> - }<br>
>> -#ifdef GRETH_AUTONEGO_PRINT_TIME<br>
>> - if ( sc->auto_neg ) {<br>
>> - printf("Autonegotiation Time: %" PRIdMAX "ms\n",<br>
>> - (intmax_t)sc->auto_neg_time.tv_sec * 1000 +<br>
>> - sc->auto_neg_time.tv_nsec / 1000000);<br>
>> - }<br>
>> -#endif<br>
>> -}<br>
>> -<br>
>> -/*<br>
>> - * Generates the hash words based on CRCs of the enabled MAC addresses that are<br>
>> - * allowed to be received. The allowed MAC addresses are maintained in a linked<br>
>> - * "multi-cast" list available in the arpcom structure.<br>
>> - *<br>
>> - * Returns the number of MAC addresses that were processed (in the list)<br>
>> - */<br>
>> -static int<br>
>> -greth_mac_filter_calc(struct arpcom *ac, uint32_t *msb, uint32_t *lsb)<br>
>> -{<br>
>> - struct ether_multistep step;<br>
>> - struct ether_multi *enm;<br>
>> - int cnt = 0;<br>
>> - uint32_t crc, htindex, ht[2] = {0, 0};<br>
>> -<br>
>> - /* Go through the Ethernet Multicast addresses one by one and add their<br>
>> - * CRC contribution to the MAC filter.<br>
>> - */<br>
>> - ETHER_FIRST_MULTI(step, ac, enm);<br>
>> - while (enm) {<br>
>> - crc = ether_crc32_be((uint8_t *)enm->enm_addrlo, 6);<br>
>> - htindex = crc & 0x3f;<br>
>> - ht[htindex >> 5] |= (1 << (htindex & 0x1F));<br>
>> - cnt++;<br>
>> - ETHER_NEXT_MULTI(step, enm);<br>
>> - }<br>
>> -<br>
>> - if (cnt > 0) {<br>
>> - *msb = ht[1];<br>
>> - *lsb = ht[0];<br>
>> - }<br>
>> -<br>
>> - return cnt;<br>
>> -}<br>
>> -<br>
>> -/*<br>
>> - * Initialize the ethernet hardware<br>
>> - */<br>
>> -static int greth_mac_filter_set(struct greth_softc *sc)<br>
>> -{<br>
>> - struct ifnet *ifp = &sc->arpcom.ac_if;<br>
>> - uint32_t hash_msb, hash_lsb, ctrl;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> -<br>
>> - hash_msb = 0;<br>
>> - hash_lsb = 0;<br>
>> - ctrl = 0;<br>
>> - if (ifp->if_flags & IFF_PROMISC) {<br>
>> - /* No need to enable multi-cast when promiscous mode accepts all */<br>
>> - ctrl |= GRETH_CTRL_PRO;<br>
>> - } else if(!sc->mc_available) {<br>
>> - return EINVAL; /* no hardware support for multicast filtering. */<br>
>> - } else if (ifp->if_flags & IFF_ALLMULTI) {<br>
>> - /* We should accept all multicast addresses */<br>
>> - ctrl |= GRETH_CTRL_MCE;<br>
>> - hash_msb = 0xFFFFFFFF;<br>
>> - hash_lsb = 0xFFFFFFFF;<br>
>> - } else if (greth_mac_filter_calc(&sc->arpcom, &hash_msb, &hash_lsb) > 0) {<br>
>> - /* Generate hash for MAC filtering out multicast addresses */<br>
>> - ctrl |= GRETH_CTRL_MCE;<br>
>> - } else {<br>
>> - /* Multicast list is empty .. disable multicast */<br>
>> - }<br>
>> - SPIN_LOCK_IRQ(&sc->devlock, flags);<br>
>> - sc->regs->ht_msb = hash_msb;<br>
>> - sc->regs->ht_lsb = hash_lsb;<br>
>> - sc->regs->ctrl = (sc->regs->ctrl & ~(GRETH_CTRL_PRO | GRETH_CTRL_MCE)) |<br>
>> - ctrl;<br>
>> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);<br>
>> -<br>
>> - return 0;<br>
>> -}<br>
>> -<br>
>> -/*<br>
>> - * Initialize the ethernet hardware<br>
>> - */<br>
>> -static void<br>
>> -greth_initialize_hardware (struct greth_softc *sc)<br>
>> -{<br>
>> - struct mbuf *m;<br>
>> - int i;<br>
>> - int phyaddr;<br>
>> - int phyctrl;<br>
>> - int phystatus;<br>
>> - int tmp1;<br>
>> - int tmp2;<br>
>> - struct timespec tstart, tnow;<br>
>> - greth_regs *regs;<br>
>> - unsigned int advmodes, speed, tabsize;<br>
>> -<br>
>> - regs = sc->regs;<br>
>> -<br>
>> - /* Reset the controller. */<br>
>> - sc->rxInterrupts = 0;<br>
>> - sc->rxPackets = 0;<br>
>> -<br>
>> - if (sc->greth_rst) {<br>
>> - /* Reset ON */<br>
>> - regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED;<br>
>> - for (i = 0; i<100 && (regs->ctrl & GRETH_CTRL_RST); i++)<br>
>> - ;<br>
>> - speed = 0; /* probe mode below */<br>
>> - } else {<br>
>> - /* inherit EDCL mode for now */<br>
>> - speed = sc->regs->ctrl & (GRETH_CTRL_GB|GRETH_CTRL_SP|GRETH_CTRL_FULLD);<br>
>> - }<br>
>> - /* Reset OFF and RX/TX DMA OFF. SW do PHY Init */<br>
>> - regs->ctrl = GRETH_CTRL_DD | GRETH_CTRL_ED | speed;<br>
>> -<br>
>> - /* Check if mac is gbit capable*/<br>
>> - sc->gbit_mac = (regs->ctrl >> 27) & 1;<br>
>> -<br>
>> - /* Get the phy address which assumed to have been set<br>
>> - correctly with the reset value in hardware*/<br>
>> - if ( sc->phyaddr == -1 ) {<br>
>> - phyaddr = (regs->mdio_ctrl >> 11) & 0x1F;<br>
>> - } else {<br>
>> - phyaddr = sc->phyaddr;<br>
>> - }<br>
>> - sc->phy_read_access = 0;<br>
>> - sc->phy_write_access = 0;<br>
>> -<br>
>> - /* As I understand the PHY comes back to a good default state after<br>
>> - * Power-down or Reset, so we do both just in case. Power-down bit should<br>
>> - * be cleared.<br>
>> - * Wait for old reset (if asserted by boot loader) to complete, otherwise<br>
>> - * power-down instruction might not have any effect.<br>
>> - */<br>
>> - while (read_mii(sc, phyaddr, 0) & 0x8000) {}<br>
>> - write_mii(sc, phyaddr, 0, 0x0800); /* Power-down */<br>
>> - write_mii(sc, phyaddr, 0, 0x0000); /* Power-Up */<br>
>> - write_mii(sc, phyaddr, 0, 0x8000); /* Reset */<br>
>> -<br>
>> - /* We wait about 30ms */<br>
>> - rtems_task_wake_after(rtems_clock_get_ticks_per_second()/32);<br>
>> -<br>
>> - /* Wait for reset to complete and get default values */<br>
>> - while ((phyctrl = read_mii(sc, phyaddr, 0)) & 0x8000) {}<br>
>> -<br>
>> - /* Set up PHY advertising modes for auto-negotiation */<br>
>> - advmodes = sc->advmodes;<br>
>> - if (advmodes == 0)<br>
>> - advmodes = GRETH_ADV_ALL;<br>
>> - if (!sc->gbit_mac)<br>
>> - advmodes &= ~(GRETH_ADV_1000_FD | GRETH_ADV_1000_HD);<br>
>> -<br>
>> - /* Enable/Disable GBit auto-neg advetisement so that the link partner<br>
>> - * know that we have/haven't GBit capability. The MAC may not support<br>
>> - * Gbit even though PHY does...<br>
>> - */<br>
>> - phystatus = read_mii(sc, phyaddr, 1);<br>
>> - if (phystatus & 0x0100) {<br>
>> - tmp1 = read_mii(sc, phyaddr, 9);<br>
>> - tmp1 &= ~0x300;<br>
>> - if (advmodes & GRETH_ADV_1000_FD)<br>
>> - tmp1 |= 0x200;<br>
>> - if (advmodes & GRETH_ADV_1000_HD)<br>
>> - tmp1 |= 0x100;<br>
>> - write_mii(sc, phyaddr, 9, tmp1);<br>
>> - }<br>
>> -<br>
>> - /* Optionally limit the 10/100 modes as configured by user */<br>
>> - tmp1 = read_mii(sc, phyaddr, 4);<br>
>> - tmp1 &= ~0x1e0;<br>
>> - if (advmodes & GRETH_ADV_100_FD)<br>
>> - tmp1 |= 0x100;<br>
>> - if (advmodes & GRETH_ADV_100_HD)<br>
>> - tmp1 |= 0x080;<br>
>> - if (advmodes & GRETH_ADV_10_FD)<br>
>> - tmp1 |= 0x040;<br>
>> - if (advmodes & GRETH_ADV_10_HD)<br>
>> - tmp1 |= 0x020;<br>
>> - write_mii(sc, phyaddr, 4, tmp1);<br>
>> -<br>
>> - /* If autonegotiation implemented we start it */<br>
>> - if (phystatus & 0x0008) {<br>
>> - write_mii(sc, phyaddr, 0, phyctrl | 0x1200);<br>
>> - phyctrl = read_mii(sc, phyaddr, 0);<br>
>> - }<br>
>> -<br>
>> - /* Check if PHY is autoneg capable and then determine operating mode,<br>
>> - otherwise force it to 10 Mbit halfduplex */<br>
>> - sc->gb = 0;<br>
>> - sc->fd = 0;<br>
>> - sc->sp = 0;<br>
>> - sc->auto_neg = 0;<br>
>> - timespecclear(&sc->auto_neg_time);<br>
>> - if ((phyctrl >> 12) & 1) {<br>
>> - /*wait for auto negotiation to complete*/<br>
>> - sc->auto_neg = 1;<br>
>> - if (rtems_clock_get_uptime(&tstart) != RTEMS_SUCCESSFUL)<br>
>> - printk("rtems_clock_get_uptime failed\n");<br>
>> - while (!(((phystatus = read_mii(sc, phyaddr, 1)) >> 5) & 1)) {<br>
>> - if (rtems_clock_get_uptime(&tnow) != RTEMS_SUCCESSFUL)<br>
>> - printk("rtems_clock_get_uptime failed\n");<br>
>> - timespecsub(&tnow, &tstart, &sc->auto_neg_time);<br>
>> - if (timespeccmp(&sc->auto_neg_time, &greth_tan, >)) {<br>
>> - sc->auto_neg = -1; /* Failed */<br>
>> - tmp1 = read_mii(sc, phyaddr, 0);<br>
>> - sc->gb = ((phyctrl >> 6) & 1) && !((phyctrl >> 13) & 1);<br>
>> - sc->sp = !((phyctrl >> 6) & 1) && ((phyctrl >> 13) & 1);<br>
>> - sc->fd = (phyctrl >> 8) & 1;<br>
>> - goto auto_neg_done;<br>
>> - }<br>
>> - /* Wait about 30ms, time is PHY dependent */<br>
>> - rtems_task_wake_after(rtems_clock_get_ticks_per_second()/32);<br>
>> - }<br>
>> - sc->phydev.adv = read_mii(sc, phyaddr, 4);<br>
>> - sc->phydev.part = read_mii(sc, phyaddr, 5);<br>
>> - if ((phystatus >> 8) & 1) {<br>
>> - sc->phydev.extadv = read_mii(sc, phyaddr, 9);<br>
>> - sc->phydev.extpart = read_mii(sc, phyaddr, 10);<br>
>> - if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000HD) &&<br>
>> - (sc->phydev.extpart & GRETH_MII_EXTPRT_1000HD)) {<br>
>> - sc->gb = 1;<br>
>> - sc->fd = 0;<br>
>> - }<br>
>> - if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000FD) &&<br>
>> - (sc->phydev.extpart & GRETH_MII_EXTPRT_1000FD)) {<br>
>> - sc->gb = 1;<br>
>> - sc->fd = 1;<br>
>> - }<br>
>> - }<br>
>> - if ((sc->gb == 0) || ((sc->gb == 1) && (sc->gbit_mac == 0))) {<br>
>> - if ( (sc->phydev.adv & GRETH_MII_100TXFD) &&<br>
>> - (sc->phydev.part & GRETH_MII_100TXFD)) {<br>
>> - sc->sp = 1;<br>
>> - sc->fd = 1;<br>
>> - } else if ( (sc->phydev.adv & GRETH_MII_100TXHD) &&<br>
>> - (sc->phydev.part & GRETH_MII_100TXHD)) {<br>
>> - sc->sp = 1;<br>
>> - sc->fd = 0;<br>
>> - } else if ( (sc->phydev.adv & GRETH_MII_10FD) &&<br>
>> - (sc->phydev.part & GRETH_MII_10FD)) {<br>
>> - sc->fd = 1;<br>
>> - }<br>
>> - }<br>
>> - }<br>
>> -auto_neg_done:<br>
>> - sc->phydev.vendor = 0;<br>
>> - sc->phydev.device = 0;<br>
>> - sc->phydev.rev = 0;<br>
>> - phystatus = read_mii(sc, phyaddr, 1);<br>
>> -<br>
>> - /* Read out PHY info if extended registers are available */<br>
>> - if (phystatus & 1) {<br>
>> - tmp1 = read_mii(sc, phyaddr, 2);<br>
>> - tmp2 = read_mii(sc, phyaddr, 3);<br>
>> -<br>
>> - sc->phydev.vendor = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);<br>
>> - sc->phydev.rev = tmp2 & 0xF;<br>
>> - sc->phydev.device = (tmp2 >> 4) & 0x3F;<br>
>> - }<br>
>> -<br>
>> - /* Force to 10 mbit half duplex if the 10/100 MAC is used with a 1000 PHY */<br>
>> - if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {<br>
>> - write_mii(sc, phyaddr, 0, sc->sp << 13);<br>
>> -<br>
>> - /* check if marvell 88EE1111 PHY. Needs special reset handling */<br>
>> - if ((phystatus & 1) && (sc->phydev.vendor == 0x005043) &&<br>
>> - (sc->phydev.device == 0x0C))<br>
>> - write_mii(sc, phyaddr, 0, 0x8000);<br>
>> -<br>
>> - sc->gb = 0;<br>
>> - sc->sp = 0;<br>
>> - sc->fd = 0;<br>
>> - }<br>
>> - while ((read_mii(sc, phyaddr, 0)) & 0x8000) {}<br>
>> -<br>
>> - if (sc->greth_rst) {<br>
>> - /* Reset ON */<br>
>> - regs->ctrl = GRETH_CTRL_RST | GRETH_CTRL_DD | GRETH_CTRL_ED;<br>
>> - for (i = 0; i < 100 && (regs->ctrl & GRETH_CTRL_RST); i++)<br>
>> - ;<br>
>> - }<br>
>> - /* Reset OFF. Set mode matching PHY settings. */<br>
>> - speed = (sc->gb << 8) | (sc->sp << 7) | (sc->fd << 4);<br>
>> - regs->ctrl = GRETH_CTRL_DD | sc->edcl_dis | speed;<br>
>> -<br>
>> - /* Initialize rx/tx descriptor table pointers. Due to alignment we<br>
>> - * always allocate maximum table size.<br>
>> - */<br>
>> - tabsize = sc->num_descs * 8;<br>
>> - sc->txdesc = (greth_rxtxdesc *) almalloc(tabsize * 2, tabsize);<br>
>> - sc->rxdesc = (greth_rxtxdesc *) (tabsize + (void *)sc->txdesc);<br>
>> - sc->tx_ptr = 0;<br>
>> - sc->tx_dptr = 0;<br>
>> - sc->tx_cnt = 0;<br>
>> - sc->rx_ptr = 0;<br>
>> -<br>
>> - /* Translate the Descriptor DMA table base address into an address that<br>
>> - * the GRETH core can understand<br>
>> - */<br>
>> - drvmgr_translate_check(<br>
>> - sc->dev,<br>
>> - CPUMEM_TO_DMA,<br>
>> - (void *)sc->txdesc,<br>
>> - (void **)&sc->txdesc_remote,<br>
>> - tabsize * 2);<br>
>> - sc->rxdesc_remote = sc->txdesc_remote + tabsize;<br>
>> - regs->txdesc = (int) sc->txdesc_remote;<br>
>> - regs->rxdesc = (int) sc->rxdesc_remote;<br>
>> -<br>
>> - sc->rxmbuf = grlib_calloc(sc->rxbufs, sizeof(*sc->rxmbuf));<br>
>> - sc->txmbuf = grlib_calloc(sc->txbufs, sizeof(*sc->txmbuf));<br>
>> -<br>
>> - for (i = 0; i < sc->txbufs; i++)<br>
>> - {<br>
>> - sc->txdesc[i].ctrl = 0;<br>
>> - if (!(sc->gbit_mac)) {<br>
>> - drvmgr_translate_check(<br>
>> - sc->dev,<br>
>> - CPUMEM_TO_DMA,<br>
>> - (void *)grlib_malloc(GRETH_MAXBUF_LEN),<br>
>> - (void **)&sc->txdesc[i].addr,<br>
>> - GRETH_MAXBUF_LEN);<br>
>> - }<br>
>> -#ifdef GRETH_DEBUG<br>
>> - /* printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr); */<br>
>> -#endif<br>
>> - }<br>
>> - for (i = 0; i < sc->rxbufs; i++)<br>
>> - {<br>
>> - MGETHDR (m, M_WAIT, MT_DATA);<br>
>> - MCLGET (m, M_WAIT);<br>
>> - if (sc->gbit_mac)<br>
>> - m->m_data += 2;<br>
>> - m->m_pkthdr.rcvif = &sc->arpcom.ac_if;<br>
>> - sc->rxmbuf[i] = m;<br>
>> - drvmgr_translate_check(<br>
>> - sc->dev,<br>
>> - CPUMEM_TO_DMA,<br>
>> - (void *)mtod(m, uint32_t *),<br>
>> - (void **)&sc->rxdesc[i].addr,<br>
>> - GRETH_MAXBUF_LEN);<br>
>> - sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;<br>
>> -#ifdef GRETH_DEBUG<br>
>> -/* printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr); */<br>
>> -#endif<br>
>> - }<br>
>> - sc->rxdesc[sc->rxbufs - 1].ctrl |= GRETH_RXD_WRAP;<br>
>> -<br>
>> - /* set ethernet address. */<br>
>> - regs->mac_addr_msb =<br>
>> - sc->arpcom.ac_enaddr[0] << 8 | sc->arpcom.ac_enaddr[1];<br>
>> - regs->mac_addr_lsb =<br>
>> - sc->arpcom.ac_enaddr[2] << 24 | sc->arpcom.ac_enaddr[3] << 16 |<br>
>> - sc->arpcom.ac_enaddr[4] << 8 | sc->arpcom.ac_enaddr[5];<br>
>> -<br>
>> - if ( sc->rxbufs < 10 ) {<br>
>> - sc->tx_int_gen = sc->tx_int_gen_cur = 1;<br>
>> - }else{<br>
>> - sc->tx_int_gen = sc->tx_int_gen_cur = sc->txbufs/2;<br>
>> - }<br>
>> - sc->next_tx_mbuf = NULL;<br>
>> -<br>
>> - if ( !sc->gbit_mac )<br>
>> - sc->max_fragsize = 1;<br>
>> -<br>
>> - /* clear all pending interrupts */<br>
>> - regs->status = 0xffffffff;<br>
>> -<br>
>> - /* install interrupt handler */<br>
>> - drvmgr_interrupt_register(sc->dev, 0, "greth", greth_interrupt, sc);<br>
>> -<br>
>> - regs->ctrl |= GRETH_CTRL_RXEN | GRETH_CTRL_RXIRQ;<br>
>> -<br>
>> - print_init_info(sc);<br>
>> -}<br>
>> -<br>
>> -#ifdef CPU_U32_FIX<br>
>> -<br>
>> -/*<br>
>> - * Routine to align the received packet so that the ip header<br>
>> - * is on a 32-bit boundary. Necessary for cpu's that do not<br>
>> - * allow unaligned loads and stores and when the 32-bit DMA<br>
>> - * mode is used.<br>
>> - *<br>
>> - * Transfers are done on word basis to avoid possibly slow byte<br>
>> - * and half-word writes.<br>
>> - */<br>
>> -<br>
>> -void ipalign(struct mbuf *m)<br>
>> -{<br>
>> - unsigned int *first, *last, data;<br>
>> - unsigned int tmp = 0;<br>
>> -<br>
>> - if ((((int) m->m_data) & 2) && (m->m_len)) {<br>
>> -#if CPU_LITTLE_ENDIAN == TRUE<br>
>> - memmove((caddr_t)(((int) m->m_data) + 2), m->m_data, m->m_len);<br>
>> -#else<br>
>> - last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) & ~3);<br>
>> - first = (unsigned int *) (((int) m->m_data) & ~3);<br>
>> - /* tmp = *first << 16; */<br>
>> - tmp = GRETH_MEM_LOAD(first);<br>
>> - tmp = tmp << 16;<br>
>> - first++;<br>
>> - do {<br>
>> - /* When snooping is not available the LDA instruction must be used<br>
>> - * to avoid the cache to return an illegal value.<br>
>> - ** Load with forced cache miss<br>
>> - * data = *first;<br>
>> - */<br>
>> - data = GRETH_MEM_LOAD(first);<br>
>> - *first = tmp | (data >> 16);<br>
>> - tmp = data << 16;<br>
>> - first++;<br>
>> - } while (first <= last);<br>
>> -#endif<br>
>> - m->m_data = (caddr_t)(((int) m->m_data) + 2);<br>
>> - }<br>
>> -}<br>
>> -#endif<br>
>> -<br>
>> -static void<br>
>> -greth_Daemon (void *arg)<br>
>> -{<br>
>> - struct ether_header *eh;<br>
>> - struct greth_softc *dp = (struct greth_softc *) arg;<br>
>> - struct ifnet *ifp = &dp->arpcom.ac_if;<br>
>> - struct mbuf *m;<br>
>> - unsigned int len, len_status, bad;<br>
>> - rtems_event_set events;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> - int first;<br>
>> - int tmp;<br>
>> -<br>
>> - for (;;)<br>
>> - {<br>
>> - rtems_bsdnet_event_receive (INTERRUPT_EVENT | GRETH_TX_WAIT_EVENT,<br>
>> - RTEMS_WAIT | RTEMS_EVENT_ANY,<br>
>> - RTEMS_NO_TIMEOUT, &events);<br>
>> -<br>
>> - if ( events & GRETH_TX_WAIT_EVENT ){<br>
>> - /* TX interrupt.<br>
>> - * We only end up here when all TX descriptors has been used,<br>
>> - * and<br>
>> - */<br>
>> - if ( dp->gbit_mac )<br>
>> - greth_process_tx_gbit(dp);<br>
>> - else<br>
>> - greth_process_tx(dp);<br>
>> -<br>
>> - /* If we didn't get a RX interrupt we don't process it */<br>
>> - if ( (events & INTERRUPT_EVENT) == 0 )<br>
>> - continue;<br>
>> - }<br>
>> -<br>
>> -<br>
>> -#ifdef GRETH_ETH_DEBUG<br>
>> - printf ("r\n");<br>
>> -#endif<br>
>> - first=1;<br>
>> - /* Scan for Received packets */<br>
>> -again:<br>
>> - while (!((len_status =<br>
>> - GRETH_MEM_LOAD(&dp->rxdesc[dp->rx_ptr].ctrl)) & GRETH_RXD_ENABLE))<br>
>> - {<br>
>> - bad = 0;<br>
>> - if (len_status & GRETH_RXD_TOOLONG)<br>
>> - {<br>
>> - dp->rxLengthError++;<br>
>> - bad = 1;<br>
>> - }<br>
>> - if (len_status & GRETH_RXD_DRIBBLE)<br>
>> - {<br>
>> - dp->rxNonOctet++;<br>
>> - bad = 1;<br>
>> - }<br>
>> - if (len_status & GRETH_RXD_CRCERR)<br>
>> - {<br>
>> - dp->rxBadCRC++;<br>
>> - bad = 1;<br>
>> - }<br>
>> - if (len_status & GRETH_RXD_OVERRUN)<br>
>> - {<br>
>> - dp->rxOverrun++;<br>
>> - bad = 1;<br>
>> - }<br>
>> - if (len_status & GRETH_RXD_LENERR)<br>
>> - {<br>
>> - dp->rxLengthError++;<br>
>> - bad = 1;<br>
>> - }<br>
>> - if (!bad)<br>
>> - {<br>
>> - /* pass on the packet in the receive buffer */<br>
>> - len = len_status & 0x7FF;<br>
>> - m = dp->rxmbuf[dp->rx_ptr];<br>
>> -#ifdef GRETH_DEBUG<br>
>> - int i;<br>
>> - printf("RX: 0x%08x, Len: %d : ", (int) m->m_data, len);<br>
>> - for (i=0; i<len; i++)<br>
>> - printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);<br>
>> - printf("\n");<br>
>> -#endif<br>
>> - m->m_len = m->m_pkthdr.len =<br>
>> - len - sizeof (struct ether_header);<br>
>> -<br>
>> - eh = mtod (m, struct ether_header *);<br>
>> -<br>
>> - m->m_data += sizeof (struct ether_header);<br>
>> -#ifdef CPU_U32_FIX<br>
>> - if(!dp->gbit_mac) {<br>
>> - /* OVERRIDE CACHED ETHERNET HEADER FOR NON-SNOOPING SYSTEMS */<br>
>> - tmp = GRETH_MEM_LOAD((uintptr_t)eh);<br>
>> - tmp = GRETH_MEM_LOAD(4+(uintptr_t)eh);<br>
>> - tmp = GRETH_MEM_LOAD(8+(uintptr_t)eh);<br>
>> - tmp = GRETH_MEM_LOAD(12+(uintptr_t)eh);<br>
>> - (void)tmp;<br>
>> -<br>
>> - ipalign(m); /* Align packet on 32-bit boundary */<br>
>> - }<br>
>> -#endif<br>
>> -/*<br>
>> - if(!(dp->gbit_mac) && !CPU_SPARC_HAS_SNOOPING) {<br>
>> - rtems_cache_invalidate_entire_data();<br>
>> - }<br>
>> -*/<br>
>> - ether_input (ifp, eh, m);<br>
>> - MGETHDR (m, M_WAIT, MT_DATA);<br>
>> - MCLGET (m, M_WAIT);<br>
>> - if (dp->gbit_mac)<br>
>> - m->m_data += 2;<br>
>> - dp->rxmbuf[dp->rx_ptr] = m;<br>
>> - m->m_pkthdr.rcvif = ifp;<br>
>> - drvmgr_translate_check(<br>
>> - dp->dev,<br>
>> - CPUMEM_TO_DMA,<br>
>> - (void *)mtod (m, uint32_t *),<br>
>> - (void **)&dp->rxdesc[dp->rx_ptr].addr,<br>
>> - GRETH_MAXBUF_LEN);<br>
>> - dp->rxPackets++;<br>
>> - }<br>
>> - if (dp->rx_ptr == dp->rxbufs - 1) {<br>
>> - dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ | GRETH_RXD_WRAP;<br>
>> - } else {<br>
>> - dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;<br>
>> - }<br>
>> - SPIN_LOCK_IRQ(&dp->devlock, flags);<br>
>> - dp->regs->ctrl |= GRETH_CTRL_RXEN;<br>
>> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);<br>
>> - dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;<br>
>> - }<br>
>> -<br>
>> - /* Always scan twice to avoid deadlock */<br>
>> - if ( first ){<br>
>> - first=0;<br>
>> - SPIN_LOCK_IRQ(&dp->devlock, flags);<br>
>> - dp->regs->ctrl |= GRETH_CTRL_RXIRQ;<br>
>> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);<br>
>> - goto again;<br>
>> - }<br>
>> -<br>
>> - }<br>
>> -}<br>
>> -<br>
>> -static int<br>
>> -sendpacket (struct ifnet *ifp, struct mbuf *m)<br>
>> -{<br>
>> - struct greth_softc *dp = ifp->if_softc;<br>
>> - unsigned char *temp;<br>
>> - struct mbuf *n;<br>
>> - unsigned int len;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> -<br>
>> - /*<br>
>> - * Is there a free descriptor available?<br>
>> - */<br>
>> - if (GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].ctrl) & GRETH_TXD_ENABLE){<br>
>> - /* No. */<br>
>> - return 1;<br>
>> - }<br>
>> -<br>
>> - /* Remember head of chain */<br>
>> - n = m;<br>
>> -<br>
>> - len = 0;<br>
>> - temp = (unsigned char *) GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].addr);<br>
>> - drvmgr_translate(dp->dev, CPUMEM_FROM_DMA, (void *)temp, (void **)&temp);<br>
>> -#ifdef GRETH_DEBUG<br>
>> - printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int) temp);<br>
>> -#endif<br>
>> - for (;;)<br>
>> - {<br>
>> -#ifdef GRETH_DEBUG<br>
>> - int i;<br>
>> - printf("MBUF: 0x%08x : ", (int) m->m_data);<br>
>> - for (i=0;i<m->m_len;i++)<br>
>> - printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);<br>
>> - printf("\n");<br>
>> -#endif<br>
>> - len += m->m_len;<br>
>> - if (len <= RBUF_SIZE)<br>
>> - memcpy ((void *) temp, (char *) m->m_data, m->m_len);<br>
>> - temp += m->m_len;<br>
>> - if ((m = m->m_next) == NULL)<br>
>> - break;<br>
>> - }<br>
>> -<br>
>> - m_freem (n);<br>
>> -<br>
>> - /* don't send long packets */<br>
>> -<br>
>> - if (len <= GRETH_MAXBUF_LEN) {<br>
>> - if (dp->tx_ptr < dp->txbufs-1) {<br>
>> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_IRQ |<br>
>> - GRETH_TXD_ENABLE | len;<br>
>> - } else {<br>
>> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_IRQ |<br>
>> - GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;<br>
>> - }<br>
>> - dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;<br>
>> - SPIN_LOCK_IRQ(&dp->devlock, flags);<br>
>> - dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;<br>
>> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);<br>
>> - }<br>
>> -<br>
>> - return 0;<br>
>> -}<br>
>> -<br>
>> -<br>
>> -static int<br>
>> -sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)<br>
>> -{<br>
>> - struct greth_softc *dp = ifp->if_softc;<br>
>> - unsigned int len;<br>
>> -<br>
>> - unsigned int ctrl;<br>
>> - int frags;<br>
>> - struct mbuf *mtmp;<br>
>> - int int_en;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> -<br>
>> - len = 0;<br>
>> -#ifdef GRETH_DEBUG<br>
>> - printf("TXD: 0x%08x\n", (int) m->m_data);<br>
>> -#endif<br>
>> - /* Get number of fragments too see if we have enough<br>
>> - * resources.<br>
>> - */<br>
>> - frags=1;<br>
>> - mtmp=m;<br>
>> - while(mtmp->m_next){<br>
>> - frags++;<br>
>> - mtmp = mtmp->m_next;<br>
>> - }<br>
>> -<br>
>> - if ( frags > dp->max_fragsize )<br>
>> - dp->max_fragsize = frags;<br>
>> -<br>
>> - if ( frags > dp->txbufs ){<br>
>> - printf("GRETH: MBUF-chain cannot be sent. Increase descriptor count.\n");<br>
>> - return -1;<br>
>> - }<br>
>> -<br>
>> - if ( frags > (dp->txbufs-dp->tx_cnt) ){<br>
>> - /* Return number of fragments */<br>
>> - return frags;<br>
>> - }<br>
>> -<br>
>> -<br>
>> - /* Enable interrupt from descriptor every tx_int_gen<br>
>> - * descriptor. Typically every 16 descriptor. This<br>
>> - * is only to reduce the number of interrupts during<br>
>> - * heavy load.<br>
>> - */<br>
>> - dp->tx_int_gen_cur-=frags;<br>
>> - if ( dp->tx_int_gen_cur <= 0 ){<br>
>> - dp->tx_int_gen_cur = dp->tx_int_gen;<br>
>> - int_en = GRETH_TXD_IRQ;<br>
>> - }else{<br>
>> - int_en = 0;<br>
>> - }<br>
>> -<br>
>> - /* At this stage we know that enough descriptors are available */<br>
>> - for (;;)<br>
>> - {<br>
>> -<br>
>> -#ifdef GRETH_DEBUG<br>
>> - int i;<br>
>> - printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);<br>
>> - for (i=0; i<m->m_len; i++)<br>
>> - printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);<br>
>> - printf("\n");<br>
>> -#endif<br>
>> - len += m->m_len;<br>
>> - drvmgr_translate_check(<br>
>> - dp->dev,<br>
>> - CPUMEM_TO_DMA,<br>
>> - (void *)(uint32_t *)m->m_data,<br>
>> - (void **)&dp->txdesc[dp->tx_ptr].addr,<br>
>> - m->m_len);<br>
>> -<br>
>> - /* Wrap around? */<br>
>> - if (dp->tx_ptr < dp->txbufs-1) {<br>
>> - ctrl = GRETH_TXD_ENABLE;<br>
>> - }else{<br>
>> - ctrl = GRETH_TXD_ENABLE | GRETH_TXD_WRAP;<br>
>> - }<br>
>> -<br>
>> - /* Enable Descriptor */<br>
>> - if ((m->m_next) == NULL) {<br>
>> - dp->txdesc[dp->tx_ptr].ctrl = ctrl | int_en | m->m_len;<br>
>> - break;<br>
>> - }else{<br>
>> - dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_MORE | ctrl | int_en | m->m_len;<br>
>> - }<br>
>> -<br>
>> - /* Next */<br>
>> - dp->txmbuf[dp->tx_ptr] = m;<br>
>> - dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;<br>
>> - dp->tx_cnt++;<br>
>> - m = m->m_next;<br>
>> - }<br>
>> - dp->txmbuf[dp->tx_ptr] = m;<br>
>> - dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;<br>
>> - dp->tx_cnt++;<br>
>> -<br>
>> - /* Tell Hardware about newly enabled descriptor */<br>
>> - SPIN_LOCK_IRQ(&dp->devlock, flags);<br>
>> - dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;<br>
>> - SPIN_UNLOCK_IRQ(&dp->devlock, flags);<br>
>> -<br>
>> - return 0;<br>
>> -}<br>
>> -<br>
>> -int greth_process_tx_gbit(struct greth_softc *sc)<br>
>> -{<br>
>> - struct ifnet *ifp = &sc->arpcom.ac_if;<br>
>> - struct mbuf *m;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> - int first=1;<br>
>> -<br>
>> - /*<br>
>> - * Send packets till queue is empty<br>
>> - */<br>
>> - for (;;){<br>
>> - /* Reap Sent packets */<br>
>> - while((sc->tx_cnt > 0) && !(GRETH_MEM_LOAD(&sc->txdesc[sc->tx_dptr].ctrl) & GRETH_TXD_ENABLE)) {<br>
>> - m_free(sc->txmbuf[sc->tx_dptr]);<br>
>> - sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;<br>
>> - sc->tx_cnt--;<br>
>> - }<br>
>> -<br>
>> - if ( sc->next_tx_mbuf ){<br>
>> - /* Get packet we tried but faild to transmit last time */<br>
>> - m = sc->next_tx_mbuf;<br>
>> - sc->next_tx_mbuf = NULL; /* Mark packet taken */<br>
>> - }else{<br>
>> - /*<br>
>> - * Get the next mbuf chain to transmit from Stack.<br>
>> - */<br>
>> - IF_DEQUEUE (&ifp->if_snd, m);<br>
>> - if (!m){<br>
>> - /* Hardware has sent all schedule packets, this<br>
>> - * makes the stack enter at greth_start next time<br>
>> - * a packet is to be sent.<br>
>> - */<br>
>> - ifp->if_flags &= ~IFF_OACTIVE;<br>
>> - break;<br>
>> - }<br>
>> - }<br>
>> -<br>
>> - /* Are there free descriptors available? */<br>
>> - /* Try to send packet, if it a negative number is returned. */<br>
>> - if ( (sc->tx_cnt >= sc->txbufs) || sendpacket_gbit(ifp, m) ){<br>
>> - /* Not enough resources */<br>
>> -<br>
>> - /* Since we have taken the mbuf out of the "send chain"<br>
>> - * we must remember to use that next time we come back.<br>
>> - * or else we have dropped a packet.<br>
>> - */<br>
>> - sc->next_tx_mbuf = m;<br>
>> -<br>
>> - /* Not enough resources, enable interrupt for transmissions<br>
>> - * this way we will be informed when more TX-descriptors are<br>
>> - * available.<br>
>> - */<br>
>> - if ( first ){<br>
>> - first = 0;<br>
>> - SPIN_LOCK_IRQ(&sc->devlock, flags);<br>
>> - ifp->if_flags |= IFF_OACTIVE;<br>
>> - sc->regs->ctrl |= GRETH_CTRL_TXIRQ;<br>
>> - SPIN_UNLOCK_IRQ(&sc->devlock, flags);<br>
>> -<br>
>> - /* We must check again to be sure that we didn't<br>
>> - * miss an interrupt (if a packet was sent just before<br>
>> - * enabling interrupts)<br>
>> - */<br>
>> - continue;<br>
>> - }<br>
>> -<br>
>> - return -1;<br>
>> - }else{<br>
>> - /* Sent Ok, proceed to process more packets if available */<br>
>> - }<br>
>> - }<br>
>> - return 0;<br>
>> -}<br>
>> -<br>
>> -int greth_process_tx(struct greth_softc *sc)<br>
>> -{<br>
>> - struct ifnet *ifp = &sc->arpcom.ac_if;<br>
>> - struct mbuf *m;<br>
>> - SPIN_IRQFLAGS(flags);<br>
>> - int first=1;<br>
>> -<br>
>> - /*<br>
>> - * Send packets till queue is empty<br>
>> - */<br>
>> - for (;;){<br>
>> - if ( sc->next_tx_mbuf ){<br>
>> - /* Get packet we tried but failed to transmit last time */<br>
>> - m = sc->next_tx_mbuf;<br>
>> - sc->next_tx_mbuf = NULL; /* Mark packet taken */<br>
>> - }else{<br>
>> - /*<br>
>> - * Get the next mbuf chain to transmit from Stack.<br>
>> - */<br>
>> - IF_DEQUEUE (&ifp->if_snd, m);<br>
>> - if (!m){<br>
>> - /* Hardware has sent all schedule packets, this<br>
>> - * makes the stack enter at greth_start next time<br>
>> - * a packet is to be sent.<br>
>> - */<br>
>> - ifp->if_flags &= ~IFF_OACTIVE;<br>
>> - break;<br>
>> - }<br>
>> - }<br>
>> -<br>
>> - /* Try to send packet, failed if it a non-zero number is returned. */<br>
>> - if ( sendpacket(ifp, m) ){<br>
>> - /* Not enough resources */<br>
>> -<br>
></blockquote></div></div></div>