diff --git a/iop/network/Makefile b/iop/network/Makefile index 6dd71ba7ae4..3853cea4362 100644 --- a/iop/network/Makefile +++ b/iop/network/Makefile @@ -13,6 +13,7 @@ SUBDIRS = \ smap \ smap-modular-netman \ smap-modular-none \ + smap-netdev \ smap-none \ smap-ps2ip \ smbman \ diff --git a/iop/network/netman/Makefile b/iop/network/netman/Makefile index a5bd481d5f0..85659093a96 100644 --- a/iop/network/netman/Makefile +++ b/iop/network/netman/Makefile @@ -18,7 +18,13 @@ IOP_IMPORT_INCS += \ system/sysmem \ system/threadman -IOP_OBJS = netman.o rpc_server.o rpc_client.o imports.o exports.o +IOP_OBJS = \ + netman.o \ + rpc_server.o \ + rpc_client.o \ + netdev.o \ + imports.o \ + exports.o include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/iop/Rules.bin.make diff --git a/iop/network/netman/include/netdev.h b/iop/network/netman/include/netdev.h new file mode 100644 index 00000000000..a9b9b3d125f --- /dev/null +++ b/iop/network/netman/include/netdev.h @@ -0,0 +1,180 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +*/ + +#ifndef _NETDEV_H +#define _NETDEV_H + +#include + +#define sceInetBus_Unknown 0 +#define sceInetBus_USB 1 +#define sceInetBus_1394 2 +#define sceInetBus_PCMCIA 3 +#define sceInetBus_PSEUDO 4 +#define sceInetBus_NIC 5 + +#define sceInetDevProtVer 2 + +#define sceInetDevF_Up 0x0001 +#define sceInetDevF_Running 0x0002 +#define sceInetDevF_Broadcast 0x0004 +#define sceInetDevF_ARP 0x0010 +#define sceInetDevF_DHCP 0x0020 +#define sceInetDevF_PPP 0x0040 +#define sceInetDevF_NIC 0x0080 +#define sceInetDevF_Error 0x0100 +#define sceInetDevF_PPPoE 0x0200 +#define sceInetDevF_Multicast 0x0400 + +#define sceInetDevEFP_StartDone 0x00000001 +#define sceInetDevEFP_PlugOut 0x00000002 +#define sceInetDevEFP_Recv 0x00000004 +#define sceInetDevEFP_Error 0x00000010 +#define sceInetDevEFP_TimeOut 0x00000020 +#define sceInetDevEFP_InetUse 0xffff0000 + +#define sceInetDevDHCP_RelOnStop 0x00000001 + +#define sceInetNDCC_GET_THPRI 0x80000000 +#define sceInetNDCC_SET_THPRI 0x81000000 +#define sceInetNDCC_GET_IF_TYPE 0x80000100 +#define sceInetNDCC_GET_RX_PACKETS 0x80010000 +#define sceInetNDCC_GET_TX_PACKETS 0x80010001 +#define sceInetNDCC_GET_RX_BYTES 0x80010002 +#define sceInetNDCC_GET_TX_BYTES 0x80010003 +#define sceInetNDCC_GET_RX_ERRORS 0x80010004 +#define sceInetNDCC_GET_TX_ERRORS 0x80010005 +#define sceInetNDCC_GET_RX_DROPPED 0x80010006 +#define sceInetNDCC_GET_TX_DROPPED 0x80010007 +#define sceInetNDCC_GET_RX_BROADCAST_PACKETS 0x80010008 +#define sceInetNDCC_GET_TX_BROADCAST_PACKETS 0x80010009 +#define sceInetNDCC_GET_RX_BROADCAST_BYTES 0x8001000a +#define sceInetNDCC_GET_TX_BROADCAST_BYTES 0x8001000b +#define sceInetNDCC_GET_RX_MULTICAST_PACKETS 0x8001000c +#define sceInetNDCC_GET_TX_MULTICAST_PACKETS 0x8001000d +#define sceInetNDCC_GET_RX_MULTICAST_BYTES 0x8001000e +#define sceInetNDCC_GET_TX_MULTICAST_BYTES 0x8001000f + +#define sceInetNDIFT_GENERIC 0x00000000 +#define sceInetNDIFT_ETHERNET 0x00000001 +#define sceInetNDIFT_PPP 0x00000002 + +#define sceInetNDCC_GET_MULTICAST 0x80011000 +#define sceInetNDCC_GET_COLLISIONS 0x80011001 +#define sceInetNDCC_GET_RX_LENGTH_ER 0x80011002 +#define sceInetNDCC_GET_RX_OVER_ER 0x80011003 +#define sceInetNDCC_GET_RX_CRC_ER 0x80011004 +#define sceInetNDCC_GET_RX_FRAME_ER 0x80011005 +#define sceInetNDCC_GET_RX_FIFO_ER 0x80011006 +#define sceInetNDCC_GET_RX_MISSED_ER 0x80011007 +#define sceInetNDCC_GET_TX_ABORTED_ER 0x80011008 +#define sceInetNDCC_GET_TX_CARRIER_ER 0x80011009 +#define sceInetNDCC_GET_TX_FIFO_ER 0x8001100a +#define sceInetNDCC_GET_TX_HEARTBEAT_ER 0x8001100b +#define sceInetNDCC_GET_TX_WINDOW_ER 0x8001100c +#define sceInetNDCC_GET_NEGO_MODE 0x80020000 +#define sceInetNDCC_SET_NEGO_MODE 0x81020000 +#define sceInetNDCC_GET_NEGO_STATUS 0x80020001 +#define sceInetNDCC_GET_LINK_STATUS 0x80030000 +#define sceInetNDCC_SET_MULTICAST_LIST 0x81040000 + +#define sceInetNDNEGO_10 0x0001 +#define sceInetNDNEGO_10_FD 0x0002 +#define sceInetNDNEGO_TX 0x0004 +#define sceInetNDNEGO_TX_FD 0x0008 +#define sceInetNDNEGO_PAUSE 0x0040 +#define sceInetNDNEGO_AUTO 0x0080 + +typedef struct sceInetPkt +{ + struct sceInetPkt *forw; + struct sceInetPkt *back; +#ifdef NETDEV_OPAQUE + int reserved[2]; +#else + void *m_reserved1; + void *m_reserved2; +#endif + u8 *rp; + u8 *wp; +} sceInetPkt_t; + +typedef struct sceInetPktQ +{ + struct sceInetPkt *head; + struct sceInetPkt *tail; +} sceInetPktQ_t; + +typedef struct sceInetDevOps +{ + struct sceInetDevOps *forw; + struct sceInetDevOps *back; + char interface[9]; + char *module_name; + char *vendor_name; + char *device_name; + u8 bus_type; + u8 bus_loc[31]; + u16 prot_ver; + u16 impl_ver; + void *priv; + int flags; + int evfid; + struct sceInetPktQ rcvq; + struct sceInetPktQ sndq; + int (*start)(void *priv, int flags); + int (*stop)(void *priv, int flags); + int (*xmit)(void *priv, int flags); + int (*control)(void *priv, int code, void *ptr, int len); + unsigned int ip_addr; + unsigned int ip_mask; + unsigned int broad_addr; + unsigned int gw_addr; + unsigned int ns_addr1; + int mtu; + u8 hw_addr[16]; + u8 dhcp_hostname[256]; + int dhcp_hostname_len; + int dhcp_flags; + void *reserved[4]; + unsigned int ns_addr2; + void *pppoe_priv; +} sceInetDevOps_t; + +extern int sceInetRegisterNetDevice(sceInetDevOps_t *ops); +extern int sceInetUnregisterNetDevice(sceInetDevOps_t *ops); +extern void *sceInetAllocMem(sceInetDevOps_t *ops, int siz); +extern void sceInetFreeMem(sceInetDevOps_t *ops, void *ptr); +extern void sceInetPktEnQ(sceInetPktQ_t *que, sceInetPkt_t *pkt); +extern sceInetPkt_t *sceInetPktDeQ(sceInetPktQ_t *que); +extern unsigned int sceInetRand(void); +extern int sceInetPrintf(const char *fmt, ...); +extern sceInetPkt_t *sceInetAllocPkt(sceInetDevOps_t *ops, int siz); +extern void sceInetFreePkt(sceInetDevOps_t *ops, sceInetPkt_t *pkt); +// TODO: sceInetRegisterPPPoE +// TODO: sceInetUnregisterPPPoE + +#define netdev_IMPORTS_start DECLARE_IMPORT_TABLE(netdev, 1, 1) +#define netdev_IMPORTS_end END_IMPORT_TABLE + +#define I_sceInetRegisterNetDevice DECLARE_IMPORT(4, sceInetRegisterNetDevice) +#define I_sceInetUnregisterNetDevice DECLARE_IMPORT(5, sceInetUnregisterNetDevice) +#define I_sceInetAllocMem DECLARE_IMPORT(6, sceInetAllocMem) +#define I_sceInetFreeMem DECLARE_IMPORT(7, sceInetFreeMem) +#define I_sceInetPktEnQ DECLARE_IMPORT(8, sceInetPktEnQ) +#define I_sceInetPktDeQ DECLARE_IMPORT(9, sceInetPktDeQ) +#define I_sceInetRand DECLARE_IMPORT(10, sceInetRand) +#define I_sceInetPrintf DECLARE_IMPORT(11, sceInetPrintf) +#define I_sceInetAllocPkt DECLARE_IMPORT(12, sceInetAllocPkt) +#define I_sceInetFreePkt DECLARE_IMPORT(13, sceInetFreePkt) +#define I_sceInetRegisterPPPoE DECLARE_IMPORT(14, sceInetRegisterPPPoE) +#define I_sceInetUnregisterPPPoE DECLARE_IMPORT(15, sceInetUnregisterPPPoE) + +#endif diff --git a/iop/network/netman/src/exports.tab b/iop/network/netman/src/exports.tab index e4e1c9dcf03..5818a486277 100644 --- a/iop/network/netman/src/exports.tab +++ b/iop/network/netman/src/exports.tab @@ -1,3 +1,4 @@ + DECLARE_EXPORT_TABLE(netman, 3, 1) DECLARE_EXPORT(_start) DECLARE_EXPORT(_retonly) @@ -22,4 +23,31 @@ DECLARE_EXPORT_TABLE(netman, 3, 1) DECLARE_EXPORT(NetManTxPacketDeQ) END_EXPORT_TABLE +DECLARE_EXPORT_TABLE(netdev, 1, 1) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(sceInetRegisterNetDevice) + DECLARE_EXPORT(sceInetUnregisterNetDevice) + DECLARE_EXPORT(sceInetAllocMem) + DECLARE_EXPORT(sceInetFreeMem) + DECLARE_EXPORT(sceInetPktEnQ) + DECLARE_EXPORT(sceInetPktDeQ) + DECLARE_EXPORT(sceInetRand) + DECLARE_EXPORT(sceInetPrintf) + DECLARE_EXPORT(sceInetAllocPkt) + DECLARE_EXPORT(sceInetFreePkt) + DECLARE_EXPORT(_retonly) // TODO sceInetRegisterPPPoE + DECLARE_EXPORT(_retonly) // TODO sceInetUnregisterPPPoE + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) + DECLARE_EXPORT(_retonly) +END_EXPORT_TABLE + void _retonly(){}; diff --git a/iop/network/netman/src/netdev.c b/iop/network/netman/src/netdev.c new file mode 100644 index 00000000000..c90a0338a03 --- /dev/null +++ b/iop/network/netman/src/netdev.c @@ -0,0 +1,277 @@ + +#include +#include +#include + +static sceInetDevOps_t *g_ops; + +static int NetDevAdaptorStart(void) +{ + if (!g_ops) + { + return 0; + } + g_ops->start(g_ops->priv, 0); + return 0; +} + +static void NetDevAdaptorStop(void) +{ + if (!g_ops) + { + return; + } + g_ops->stop(g_ops->priv, 0); +} + +static void NetDevAdaptorXmit(void) +{ + if (!g_ops) + { + return; + } + g_ops->xmit(g_ops->priv, 0); +} + +static int NetDevAdaptorIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length) +{ + int result; + int ret2; + int mode; + + (void)args_len; + (void)length; + + if (!g_ops) + { + return 0; + } + + result = 0; + ret2 = 0; + switch (command) { + case NETMAN_NETIF_IOCTL_ETH_GET_MAC: + memcpy(output, g_ops->hw_addr, (length > sizeof(g_ops->hw_addr)) ? sizeof(g_ops->hw_addr) : length); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_LINK_MODE: + g_ops->control(g_ops->priv, sceInetNDCC_GET_NEGO_MODE, &ret2, sizeof(ret2)); + if (ret2 & 0x08) + result = NETMAN_NETIF_ETH_LINK_MODE_100M_FDX; /* 100Base-TX FDX */ + if (ret2 & 0x04) + result = NETMAN_NETIF_ETH_LINK_MODE_100M_HDX; /* 100Base-TX HDX */ + if (ret2 & 0x02) + result = NETMAN_NETIF_ETH_LINK_MODE_10M_FDX; /* 10Base-TX FDX */ + if (ret2 & 0x01) + result = NETMAN_NETIF_ETH_LINK_MODE_10M_HDX; /* 10Base-TX HDX */ + if (!(ret2 & 0x40)) + result |= NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE; + break; + case NETMAN_NETIF_IOCTL_GET_LINK_STATUS: + g_ops->control(g_ops->priv, sceInetNDCC_GET_LINK_STATUS, &ret2, sizeof(ret2)); + result = (ret2 > 0) ? NETMAN_NETIF_ETH_LINK_STATE_UP : NETMAN_NETIF_ETH_LINK_STATE_DOWN; + break; + case NETMAN_NETIF_IOCTL_GET_TX_DROPPED_COUNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_ERRORS, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_GET_RX_DROPPED_COUNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_ERRORS, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_RX_EOVERRUN_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_OVER_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADLEN_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_LENGTH_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADFCS_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_CRC_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_RX_EBADALIGN_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_FRAME_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_TX_ELOSSCR_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_CARRIER_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_TX_EEDEFER_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_WINDOW_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_TX_ECOLL_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_COLLISIONS, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_TX_EUNDERRUN_CNT: + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_FIFO_ER, &result, sizeof(result)); + break; + case NETMAN_NETIF_IOCTL_ETH_SET_LINK_MODE: + int baseMode; + + mode = *(int *)args; + baseMode = mode & (~NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE); + ret2 = sceInetNDNEGO_AUTO | sceInetNDNEGO_TX_FD | sceInetNDNEGO_TX | sceInetNDNEGO_10_FD | sceInetNDNEGO_10; + + if (baseMode != NETMAN_NETIF_ETH_LINK_MODE_AUTO) { + switch (baseMode) { + case NETMAN_NETIF_ETH_LINK_MODE_10M_HDX: + ret2 = sceInetNDNEGO_10; + break; + case NETMAN_NETIF_ETH_LINK_MODE_10M_FDX: + ret2 = sceInetNDNEGO_10_FD; + break; + case NETMAN_NETIF_ETH_LINK_MODE_100M_HDX: + ret2 = sceInetNDNEGO_TX; + break; + case NETMAN_NETIF_ETH_LINK_MODE_100M_FDX: + ret2 = sceInetNDNEGO_TX_FD; + break; + default: + break; + } + } + if (!(mode & NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE)) + ret2 |= sceInetNDNEGO_PAUSE; + g_ops->control(g_ops->priv, sceInetNDCC_SET_NEGO_MODE, &ret2, sizeof(ret2)); + break; + case NETMAN_NETIF_IOCTL_ETH_GET_STATUS: + g_ops->control(g_ops->priv, sceInetNDCC_GET_NEGO_MODE, &ret2, sizeof(ret2)); + if (ret2 & 0x08) + result = NETMAN_NETIF_ETH_LINK_MODE_100M_FDX; /* 100Base-TX FDX */ + if (ret2 & 0x04) + result = NETMAN_NETIF_ETH_LINK_MODE_100M_HDX; /* 100Base-TX HDX */ + if (ret2 & 0x02) + result = NETMAN_NETIF_ETH_LINK_MODE_10M_FDX; /* 10Base-TX FDX */ + if (ret2 & 0x01) + result = NETMAN_NETIF_ETH_LINK_MODE_10M_HDX; /* 10Base-TX HDX */ + if (!(ret2 & 0x40)) + result |= NETMAN_NETIF_ETH_LINK_DISABLE_PAUSE; + ((struct NetManEthStatus *)output)->LinkMode = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_LINK_STATUS, &ret2, sizeof(ret2)); + result = (ret2 > 0) ? NETMAN_NETIF_ETH_LINK_STATE_UP : NETMAN_NETIF_ETH_LINK_STATE_DOWN; + ((struct NetManEthStatus *)output)->LinkStatus = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_ERRORS, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxDroppedFrameCount = result; + // TODO: RxErrorCount not exposed through netdev ctrl + ((struct NetManEthStatus *)output)->stats.RxErrorCount = 0; + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_OVER_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxFrameOverrunCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_LENGTH_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxFrameBadLengthCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_CRC_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxFrameBadFCSCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_FRAME_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxFrameBadAlignmentCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_ERRORS, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.TxDroppedFrameCount = result; + // TODO: TxErrorCount not exposed through netdev ctrl + ((struct NetManEthStatus *)output)->stats.TxErrorCount = 0; + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_CARRIER_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.TxFrameLOSSCRCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_WINDOW_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.TxFrameEDEFERCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_COLLISIONS, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.TxFrameCollisionCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_TX_FIFO_ER, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.TxFrameUnderrunCount = result; + g_ops->control(g_ops->priv, sceInetNDCC_GET_RX_DROPPED, &result, sizeof(result)); + ((struct NetManEthStatus *)output)->stats.RxAllocFail = result; + result = 0; + break; + default: + result = -1; + } + + return result; +} + +int sceInetRegisterNetDevice(sceInetDevOps_t *ops) +{ + struct NetManNetIF device; + if (g_ops != NULL) + { + return -1; + } + strcpy(device.name, ops->module_name); + device.init = &NetDevAdaptorStart; + device.deinit = &NetDevAdaptorStop; + device.xmit = &NetDevAdaptorXmit; + device.ioctl = &NetDevAdaptorIoctl; + if (NetManRegisterNetIF(&device) >= 0) + { + g_ops = ops; + } + return (g_ops != NULL) ? 0 : -1; +} + +int sceInetUnregisterNetDevice(sceInetDevOps_t *ops) +{ + struct NetManNetIF device; + if (g_ops != ops) + { + return -1; + } + strcpy(device.name, ops->module_name); + NetManUnregisterNetIF(device.name); + return 0; +} + +void *sceInetAllocMem(sceInetDevOps_t *ops, int siz) +{ + // TODO: Currently stubbed + return NULL; +} + +void sceInetFreeMem(sceInetDevOps_t *ops, void *ptr) +{ + // TODO: Currently stubbed +} + +void sceInetPktEnQ(sceInetPktQ_t *que, sceInetPkt_t *pkt) +{ + NetManNetProtStackEnQRxPacket(pkt->m_reserved1); +} + +sceInetPkt_t *sceInetPktDeQ(sceInetPktQ_t *que) +{ + static sceInetPkt_t pkt; + void *data; + int len; + memset(&pkt, 0, sizeof(pkt)); + + data = NULL; + len = NetManTxPacketNext(&data); + pkt.rp = data; + pkt.wp = (void *)(((u8 *)data) + len); + return len ? &pkt : NULL; +} + +unsigned int sceInetRand(void) +{ + // TODO: Currently stubbed + return 0; +} + +int sceInetPrintf(const char *fmt, ...) +{ + // TODO: Currently stubbed + return 0; +} + +sceInetPkt_t *sceInetAllocPkt(sceInetDevOps_t *ops, int siz) +{ + static sceInetPkt_t pkt; + void *payload; + void *pbuf; + + (void)ops; + + memset(&pkt, 0, sizeof(pkt)); + pbuf = NetManNetProtStackAllocRxPacket(siz, &payload); + pkt.wp = payload; + pkt.m_reserved1 = pbuf; + return pbuf ? &pkt : NULL; +} + +void sceInetFreePkt(sceInetDevOps_t *ops, sceInetPkt_t *pkt) +{ + (void)ops; + (void)pkt; + + NetManTxPacketDeQ(); +} diff --git a/iop/network/netman/src/netman.c b/iop/network/netman/src/netman.c index 0152e980d9c..ae8848bea88 100644 --- a/iop/network/netman/src/netman.c +++ b/iop/network/netman/src/netman.c @@ -25,6 +25,7 @@ static int NetManIOSemaID; IRX_ID("Network_Manager", 2, 1); extern struct irx_export_table _exp_netman; +extern struct irx_export_table _exp_netdev; int _start(int argc, char *argv[]){ iop_sema_t sema; @@ -32,19 +33,21 @@ int _start(int argc, char *argv[]){ (void)argc; (void)argv; - if(RegisterLibraryEntries(&_exp_netman) == 0){ - sema.attr = 0; - sema.option = 0; - sema.initial = 1; - sema.max = 1; - NetManIOSemaID = CreateSema(&sema); - - NetmanInitRPCServer(); - - return MODULE_RESIDENT_END; + if(RegisterLibraryEntries(&_exp_netman) != 0){ + return MODULE_NO_RESIDENT_END; } + if(RegisterLibraryEntries(&_exp_netdev) != 0){ + return MODULE_NO_RESIDENT_END; + } + sema.attr = 0; + sema.option = 0; + sema.initial = 1; + sema.max = 1; + NetManIOSemaID = CreateSema(&sema); + + NetmanInitRPCServer(); - return MODULE_NO_RESIDENT_END; + return MODULE_RESIDENT_END; } void *malloc(int size){ diff --git a/iop/network/smap-netdev/Makefile b/iop/network/smap-netdev/Makefile new file mode 100644 index 00000000000..79ee706d3cb --- /dev/null +++ b/iop/network/smap-netdev/Makefile @@ -0,0 +1,18 @@ +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. + +IOP_BIN_ALTNAMES = + +IOP_SRC_DIR = $(PS2SDKSRC)/iop/network/smap/src/ +IOP_INC_DIR = $(PS2SDKSRC)/iop/network/smap/include/ + +SMAP_NETMAN ?= 0 +SMAP_PS2IP ?= 0 +SMAP_NETDEV ?= 1 + +include $(PS2SDKSRC)/iop/network/smap/Makefile diff --git a/iop/network/smap/Makefile b/iop/network/smap/Makefile index e2746a1a33f..f4ad5e97196 100644 --- a/iop/network/smap/Makefile +++ b/iop/network/smap/Makefile @@ -15,6 +15,9 @@ SMAP_NETMAN ?= 1 # Build against the ps2ip library. SMAP_PS2IP ?= 0 +# Build against the netdev interface. +SMAP_NETDEV ?= 0 + # Enable the modular interface. SMAP_MODULAR ?= 0 @@ -50,6 +53,11 @@ IOP_CFLAGS += -DBUILDING_SMAP_PS2IP=1 IOP_IMPORT_INCS += tcpip/tcpip endif +ifneq (x$(SMAP_NETDEV),x0) +IOP_CFLAGS += -DBUILDING_SMAP_NETDEV=1 +IOP_IMPORT_INCS += network/netman +endif + ifneq (x$(SMAP_MODULAR),x0) IOP_CFLAGS += -DBUILDING_SMAP_MODULAR=1 endif diff --git a/iop/network/smap/src/exports.tab b/iop/network/smap/src/exports.tab index 78e426b9f72..63b6f591345 100644 --- a/iop/network/smap/src/exports.tab +++ b/iop/network/smap/src/exports.tab @@ -1,4 +1,5 @@ -#ifdef BUILDING_SMAP_NETMAN + +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) DECLARE_EXPORT_TABLE(smap, 1, 1) DECLARE_EXPORT(_retonly) DECLARE_EXPORT(_retonly) diff --git a/iop/network/smap/src/imports.lst b/iop/network/smap/src/imports.lst index ac17ea7e16d..af520b8c0e7 100644 --- a/iop/network/smap/src/imports.lst +++ b/iop/network/smap/src/imports.lst @@ -9,6 +9,9 @@ I_SetAlarm I_CancelAlarm #endif I_USec2SysClock +#ifdef BUILDING_SMAP_NETDEV +I_ChangeThreadPriority +#endif thbase_IMPORTS_end stdio_IMPORTS_start @@ -67,6 +70,18 @@ I_tcpip_callback_with_block ps2ip_IMPORTS_end #endif +#ifdef BUILDING_SMAP_NETDEV +netdev_IMPORTS_start +I_sceInetRegisterNetDevice +I_sceInetUnregisterNetDevice +I_sceInetPktEnQ +I_sceInetPktDeQ +I_sceInetPrintf +I_sceInetAllocPkt +I_sceInetFreePkt +netdev_IMPORTS_end +#endif + thevent_IMPORTS_start I_CreateEventFlag I_WaitEventFlag diff --git a/iop/network/smap/src/include/ipstack.h b/iop/network/smap/src/include/ipstack.h index 5ed6951eee4..b80e98934ad 100644 --- a/iop/network/smap/src/include/ipstack.h +++ b/iop/network/smap/src/include/ipstack.h @@ -2,11 +2,11 @@ #ifndef IPSTACK_H #define IPSTACK_H -extern int SMAPCommonTxPacketNext(struct SmapDriverData *SmapDrivPrivData, void **data); -extern void SMAPCommonTxPacketDeQ(struct SmapDriverData *SmapDrivPrivData, void **data); +extern int SMAPCommonTxPacketNext(struct SmapDriverData *SmapDrivPrivData, void **data, void **pbuf); +extern void SMAPCommonTxPacketDeQ(struct SmapDriverData *SmapDrivPrivData, void **data, void **pbuf); extern void SMapCommonLinkStateDown(struct SmapDriverData *SmapDrivPrivData); extern void SMapCommonLinkStateUp(struct SmapDriverData *SmapDrivPrivData); extern void *SMapCommonStackAllocRxPacket(struct SmapDriverData *SmapDrivPrivData, u16 LengthRounded, void **payload); -extern void SMapStackEnQRxPacket(struct SmapDriverData *SmapDrivPrivData, void *pbuf); +extern void SMapStackEnQRxPacket(struct SmapDriverData *SmapDrivPrivData, void *pbuf, u16 length); #endif diff --git a/iop/network/smap/src/include/irx_imports.h b/iop/network/smap/src/include/irx_imports.h index 0b83c601a91..55359889856 100644 --- a/iop/network/smap/src/include/irx_imports.h +++ b/iop/network/smap/src/include/irx_imports.h @@ -7,6 +7,9 @@ #include #include #include +#ifdef BUILDING_SMAP_NETDEV +#include +#endif #ifdef BUILDING_SMAP_NETMAN #include #endif diff --git a/iop/network/smap/src/include/main.h b/iop/network/smap/src/include/main.h index 284eaf50136..8107d18b5f3 100644 --- a/iop/network/smap/src/include/main.h +++ b/iop/network/smap/src/include/main.h @@ -10,12 +10,55 @@ #ifdef BUILDING_SMAP_PS2IP #include #endif +#ifdef BUILDING_SMAP_NETDEV +#include +#endif #ifdef BUILDING_SMAP_MODULAR #include #endif -// In the SONY original, all the calls to DEBUG_PRINTF() were to sceInetPrintf(). -#define DEBUG_PRINTF(args...) printf("SMAP: "args) +#ifndef BUILDING_SMAP_NETDEV +#define sceInetPrintf(...) printf(__VA_ARGS__) +#endif + +#define DEBUG_PRINTF(args...) sceInetPrintf("SMAP: "args) + +#ifdef BUILDING_SMAP_NETDEV +struct RuntimeStats_NetDev +{ + u32 m_RxErrorVarious[16]; + u32 m_TxErrorVarious[16]; + u32 m_Rx_Packets; + u32 m_Tx_Packets; + u32 m_Rx_Bytes; + u32 m_Tx_Bytes; + u32 m_Rx_Errors; + u32 m_Tx_Errors; + u32 m_Rx_Dropped; + u32 m_Tx_Dropped; + u32 m_Rx_Broadcast_Packets; + u32 m_Tx_Broadcast_Packets; + u32 m_Rx_Broadcast_Bytes; + u32 m_Tx_Broadcast_Bytes; + u32 m_Rx_Multicast_Packets; + u32 m_Tx_Multicast_Packets; + u32 m_Rx_Multicast_Bytes; + u32 m_Tx_Multicast_Bytes; + u32 m_Multicast; + u32 m_Collisions; + u32 m_Rx_Length_Er; + u32 m_Rx_Over_Er; + u32 m_Rx_Crc_Er; + u32 m_Rx_Frame_Er; + u32 m_Rx_Fifo_Er; + u32 m_Rx_Missed_Er; + u32 m_Tx_Aborted_Er; + u32 m_Tx_Carrier_Er; + u32 m_Tx_Fifo_Er; + u32 m_Tx_Heartbeat_Er; + u32 m_Tx_Window_Er; +}; +#endif // This struct needs to be the exact same layout as struct NetManEthRuntimeStats! struct RuntimeStats @@ -47,7 +90,7 @@ struct SmapDriverData void *packetToSend; int Dev9IntrEventFlag; int IntrHandlerThreadID; - unsigned char SmapDriverStarted; // SMAP driver is started. + unsigned char SmapDriverStarting; // SMAP driver is starting. unsigned char SmapIsInitialized; // SMAP driver is initialized (software) unsigned char NetDevStopFlag; unsigned char EnableLinkCheckTimer; @@ -58,9 +101,15 @@ struct SmapDriverData iop_sys_clock_t RxIntrPollingTimer; #endif struct RuntimeStats RuntimeStats; +#ifdef BUILDING_SMAP_NETDEV + struct RuntimeStats_NetDev RuntimeStats_NetDev; +#endif #ifdef BUILDING_SMAP_NETMAN int NetIFID; #endif +#ifdef BUILDING_SMAP_NETDEV + sceInetDevOps_t m_devops; +#endif #ifdef BUILDING_SMAP_MODULAR const SmapModularHookTable_t *HookTable[1]; #endif @@ -76,11 +125,12 @@ struct SmapDriverData /* Function prototypes */ extern int DisplayBanner(void); extern int smap_init(int argc, char *argv[]); +#ifdef BUILDING_SMAP_NETDEV +extern int smap_deinit(void); +#endif #ifdef BUILDING_SMAP_PS2IP extern int SMAPInitStart(void); #endif -extern int SMAPStart(void); -extern void SMAPStop(void); extern void SMAPXmit(void); extern int SMAPGetMACAddress(u8 *buffer); #ifdef BUILDING_SMAP_PS2IP diff --git a/iop/network/smap/src/ipstack.c b/iop/network/smap/src/ipstack.c index cc19a83111e..be99c033e0c 100644 --- a/iop/network/smap/src/ipstack.c +++ b/iop/network/smap/src/ipstack.c @@ -2,7 +2,11 @@ #include "main.h" #include "ipstack.h" -int SMAPCommonTxPacketNext(struct SmapDriverData *SmapDrivPrivData, void **data) +#ifdef BUILDING_SMAP_NETDEV +#include +#endif + +int SMAPCommonTxPacketNext(struct SmapDriverData *SmapDrivPrivData, void **data, void **pbuf) { #ifdef BUILDING_SMAP_MODULAR { @@ -20,15 +24,49 @@ int SMAPCommonTxPacketNext(struct SmapDriverData *SmapDrivPrivData, void **data) } #endif #if defined(BUILDING_SMAP_NETMAN) + (void)SmapDrivPrivData; + (void)pbuf; return NetManTxPacketNext(data); #elif defined(BUILDING_SMAP_PS2IP) + (void)SmapDrivPrivData; + (void)pbuf; return SMapTxPacketNext(data); +#elif defined(BUILDING_SMAP_NETDEV) + while (1) { + sceInetPkt_t *pkt; + u8 *rp; + unsigned int length; + pkt = sceInetPktDeQ(&SmapDrivPrivData->m_devops.sndq); + if (pkt == NULL) { + return 0; + } + rp = pkt->rp; + length = pkt->wp - rp; + if (length == 0 || ((uiptr)rp & 3) != 0) { + sceInetPrintf("smap: dropped\n"); + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Dropped += 1; + +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Bytes += length; + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Packets += 1; +#endif + + sceInetFreePkt(&SmapDrivPrivData->m_devops, pkt); + continue; + } + *pbuf = pkt; + *data = rp; + return length; + } #else + (void)SmapDrivPrivData; + (void)data; + (void)pbuf; return 0; #endif } -void SMAPCommonTxPacketDeQ(struct SmapDriverData *SmapDrivPrivData, void **data) +void SMAPCommonTxPacketDeQ(struct SmapDriverData *SmapDrivPrivData, void **data, void **pbuf) { #ifdef BUILDING_SMAP_MODULAR { @@ -45,9 +83,18 @@ void SMAPCommonTxPacketDeQ(struct SmapDriverData *SmapDrivPrivData, void **data) (void)data; #endif #if defined(BUILDING_SMAP_NETMAN) + (void)SmapDrivPrivData; + (void)pbuf; NetManTxPacketDeQ(); #elif defined(BUILDING_SMAP_PS2IP) + (void)SmapDrivPrivData; + (void)pbuf; SMapTxPacketDeQ(); +#elif defined(BUILDING_SMAP_NETDEV) + sceInetFreePkt(&SmapDrivPrivData->m_devops, *pbuf); +#else + (void)SmapDrivPrivData; + (void)pbuf; #endif } @@ -96,6 +143,8 @@ void SMapCommonLinkStateUp(struct SmapDriverData *SmapDrivPrivData) (void)SmapDrivPrivData; PS2IPLinkStateUp(); +#elif defined(BUILDING_SMAP_NETDEV) + SetEventFlag(SmapDrivPrivData->m_devops.evfid, sceInetDevEFP_StartDone); #else (void)SmapDrivPrivData; #endif @@ -120,8 +169,10 @@ void *SMapCommonStackAllocRxPacket(struct SmapDriverData *SmapDrivPrivData, u16 } #endif #if defined(BUILDING_SMAP_NETMAN) + (void)SmapDrivPrivData; pbuf = NetManNetProtStackAllocRxPacket(LengthRounded, payload); #elif defined(BUILDING_SMAP_PS2IP) + (void)SmapDrivPrivData; struct pbuf *pbuf_struct; pbuf_struct = pbuf_alloc(PBUF_RAW, LengthRounded, PBUF_POOL); @@ -130,7 +181,15 @@ void *SMapCommonStackAllocRxPacket(struct SmapDriverData *SmapDrivPrivData, u16 if (pbuf_struct != NULL && payload != NULL) { *payload = pbuf_struct->payload; } +#elif defined(BUILDING_SMAP_NETDEV) + sceInetPkt_t *pkt; + pkt = sceInetAllocPkt(&SmapDrivPrivData->m_devops, LengthRounded); + if (pkt != NULL && payload != NULL) { + *payload = pkt->wp; + } + pbuf = pkt; #else + (void)SmapDrivPrivData; (void)LengthRounded; if (payload != NULL) { *payload = NULL; @@ -140,7 +199,7 @@ void *SMapCommonStackAllocRxPacket(struct SmapDriverData *SmapDrivPrivData, u16 return pbuf; } -void SMapStackEnQRxPacket(struct SmapDriverData *SmapDrivPrivData, void *pbuf) +void SMapStackEnQRxPacket(struct SmapDriverData *SmapDrivPrivData, void *pbuf, u16 length) { #ifdef BUILDING_SMAP_MODULAR { @@ -155,10 +214,24 @@ void SMapStackEnQRxPacket(struct SmapDriverData *SmapDrivPrivData, void *pbuf) } #endif #if defined(BUILDING_SMAP_NETMAN) + (void)SmapDrivPrivData; + (void)length; NetManNetProtStackEnQRxPacket(pbuf); #elif defined(BUILDING_SMAP_PS2IP) + (void)SmapDrivPrivData; + (void)length; SMapLowLevelInput(pbuf); +#elif defined(BUILDING_SMAP_NETDEV) + { + sceInetPkt_t *pkt; + + pkt = (sceInetPkt_t *)pbuf; + pkt->wp = &pkt->rp[length]; + sceInetPktEnQ(&SmapDrivPrivData->m_devops.rcvq, pkt); + } #else + (void)SmapDrivPrivData; + (void)length; (void)pbuf; #endif } diff --git a/iop/network/smap/src/main.c b/iop/network/smap/src/main.c index cc48d26d815..59d68b30aaf 100644 --- a/iop/network/smap/src/main.c +++ b/iop/network/smap/src/main.c @@ -143,7 +143,7 @@ SMapIFInit(NetIF *pNetIF) #ifdef PRE_LWIP_130_COMPAT pNetIF->output = &SMapOutput; // For LWIP versions before v1.3.0. #else - pNetIF->output = ðarp_output; // For LWIP 1.3.0 and later. + pNetIF->output = ðarp_output; // For LWIP 1.3.0 and later. #endif pNetIF->linkoutput = &SMapLowLevelOutput; pNetIF->hwaddr_len = NETIF_MAX_HWADDR_LEN; @@ -269,7 +269,7 @@ void PS2IPLinkStateDown(void) } #endif -#ifdef BUILDING_SMAP_NETMAN +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) // While the header of the export table is small, the large size of the export table (as a whole) places it in data instead of sdata. extern struct irx_export_table _exp_smap __attribute__((section("data"))); #endif @@ -287,11 +287,24 @@ int _start(int argc, char *argv[]) int numArgs; char **pArgv; #endif -#ifdef BUILDING_SMAP_NETMAN +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) int result; #endif -#ifdef BUILDING_SMAP_NETMAN +#ifdef BUILDING_SMAP_NETDEV + if (argc < 0) { + result = smap_deinit(); + if (result == MODULE_NO_RESIDENT_END) { +#ifdef BUILDING_SMAP_MODULAR + ReleaseLibraryEntries(&_exp_smapmodu); +#endif + ReleaseLibraryEntries(&_exp_smap); + } + return result; + } +#endif + +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) if (RegisterLibraryEntries(&_exp_smap) != 0) { DEBUG_PRINTF("module already loaded\n"); return MODULE_NO_RESIDENT_END; @@ -324,6 +337,8 @@ int _start(int argc, char *argv[]) return MODULE_NO_RESIDENT_END; } */ + (void)argc; + (void)argv; #ifdef BUILDING_SMAP_PS2IP // Parse IP args. DEBUG_PRINTF("argc %d\n", argc); @@ -348,7 +363,7 @@ int _start(int argc, char *argv[]) } #endif -#ifdef BUILDING_SMAP_NETMAN +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) if ((result = smap_init(argc, argv)) < 0) { DEBUG_PRINTF("smap_init -> %d\n", result); ReleaseLibraryEntries(&_exp_smap); diff --git a/iop/network/smap/src/smap.c b/iop/network/smap/src/smap.c index c53bf7373ac..f6641d9a4e0 100644 --- a/iop/network/smap/src/smap.c +++ b/iop/network/smap/src/smap.c @@ -88,7 +88,7 @@ static void _smap_write_phy(volatile u8 *emac3_regbase, unsigned int address, u1 } if (i >= 100) - printf("smap: %s: > %u ms\n", "_smap_write_phy", i); + sceInetPrintf("smap: %s: > %u ms\n", "_smap_write_phy", i); } static u16 _smap_read_phy(volatile u8 *emac3_regbase, unsigned int address) @@ -118,7 +118,7 @@ static u16 _smap_read_phy(volatile u8 *emac3_regbase, unsigned int address) } while (i < 100); if (i >= 100) - printf("SMAP: %s: > %u ms\n", "_smap_read_phy", i); + sceInetPrintf("SMAP: %s: > %u ms\n", "_smap_read_phy", i); return result; } @@ -197,6 +197,10 @@ static int InitPHY(struct SmapDriverData *SmapDrivPrivData) SmapDrivPrivData->LinkStatus = 1; } else { if (!EnablePinStrapConfig) { + unsigned int SmapConfiguration_old; + u16 anar_old; + + SmapConfiguration_old = SmapConfiguration; _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, 0); value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMSR); if (!(value & 0x4000)) @@ -208,11 +212,12 @@ static int InitPHY(struct SmapDriverData *SmapDrivPrivData) if (!(value & 0x0800)) SmapConfiguration = SmapConfiguration & 0xFFFFFFDF; /* 10Base-TX HDX */ - DEBUG_PRINTF("no strap mode (conf=0x%x, bmsr=0x%x)\n", SmapConfiguration, value); + DEBUG_PRINTF("no strap mode (conf=0x%x->0x%x, bmsr=0x%x)\n", SmapConfiguration_old, SmapConfiguration, value); - value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR); - value = (SmapConfiguration & 0x5E0) | (value & 0x1F); - DEBUG_PRINTF("anar=0x%x\n", value); + value = _smap_read_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR); + anar_old = value; + value = (SmapConfiguration & 0x5E0) | (value & 0x1F); + DEBUG_PRINTF("anar=0x%x->0x%x\n", anar_old, value); _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_ANAR, value); _smap_write_phy(SmapDrivPrivData->emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_ANEN | SMAP_PHY_BMCR_RSAN); } else { @@ -394,18 +399,41 @@ static int HandleTxIntr(struct SmapDriverData *SmapDrivPrivData) if (!(ctrl_stat & SMAP_BD_TX_READY)) { if (ctrl_stat & (SMAP_BD_TX_UNDERRUN | SMAP_BD_TX_LCOLL | SMAP_BD_TX_ECOLL | SMAP_BD_TX_EDEFER | SMAP_BD_TX_LOSSCR)) { for (i = 0; i < 16; i++) - if ((ctrl_stat >> i) & 1) + if ((ctrl_stat >> i) & 1) { SmapDrivPrivData->RuntimeStats.TxErrorCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_TxErrorVarious[i] += 1; +#endif + } SmapDrivPrivData->RuntimeStats.TxDroppedFrameCount++; - if (ctrl_stat & SMAP_BD_TX_LOSSCR) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Errors += 1; +#endif + if (ctrl_stat & SMAP_BD_TX_LOSSCR) { SmapDrivPrivData->RuntimeStats.TxFrameLOSSCRCount++; - if (ctrl_stat & SMAP_BD_TX_EDEFER) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Carrier_Er += 1; +#endif + } + if (ctrl_stat & SMAP_BD_TX_EDEFER) { SmapDrivPrivData->RuntimeStats.TxFrameEDEFERCount++; - if (ctrl_stat & (SMAP_BD_TX_SCOLL | SMAP_BD_TX_MCOLL | SMAP_BD_TX_LCOLL | SMAP_BD_TX_ECOLL)) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Window_Er += 1; +#endif + } + if (ctrl_stat & (SMAP_BD_TX_SCOLL | SMAP_BD_TX_MCOLL | SMAP_BD_TX_LCOLL | SMAP_BD_TX_ECOLL)) { SmapDrivPrivData->RuntimeStats.TxFrameCollisionCount++; - if (ctrl_stat & SMAP_BD_TX_UNDERRUN) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Collisions += 1; +#endif + } + if (ctrl_stat & SMAP_BD_TX_UNDERRUN) { SmapDrivPrivData->RuntimeStats.TxFrameUnderrunCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Fifo_Er += 1; +#endif + } } } else break; @@ -419,6 +447,10 @@ static int HandleTxIntr(struct SmapDriverData *SmapDrivPrivData) return result; } +#ifdef BUILDING_SMAP_NETDEV +static void ClearPacketQueue(struct SmapDriverData *SmapDrivPrivData); +#endif + // Checks the status of the Ethernet link static void CheckLinkStatus(struct SmapDriverData *SmapDrivPrivData) { @@ -427,6 +459,9 @@ static void CheckLinkStatus(struct SmapDriverData *SmapDrivPrivData) SmapDrivPrivData->LinkStatus = 0; SMapCommonLinkStateDown(SmapDrivPrivData); InitPHY(SmapDrivPrivData); +#ifdef BUILDING_SMAP_NETDEV + ClearPacketQueue(SmapDrivPrivData); +#endif // Link established if (SmapDrivPrivData->LinkStatus) @@ -453,6 +488,14 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData) counter = 3; emac3_regbase = SmapDrivPrivData->emac3_regbase; smap_regbase = SmapDrivPrivData->smap_regbase; + + SmapDrivPrivData->TxBufferSpaceAvailable = SMAP_TX_BUFSIZE; + SmapDrivPrivData->NumPacketsInTx = 0; + SmapDrivPrivData->TxBDIndex = 0; + SmapDrivPrivData->TxDNVBDIndex = 0; + SmapDrivPrivData->RxBDIndex = 0; + SmapDrivPrivData->packetToSend = NULL; + while (1) { int result; @@ -465,27 +508,29 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData) if (SmapDrivPrivData->SmapIsInitialized) { SpdIntrDisable(DEV9_SMAP_INTR_MASK2); SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, 0); - SmapDrivPrivData->NetDevStopFlag = 0; - SmapDrivPrivData->LinkStatus = 0; - SmapDrivPrivData->SmapIsInitialized = 0; - SmapDrivPrivData->SmapDriverStarted = 0; + SmapDrivPrivData->NetDevStopFlag = 0; + SmapDrivPrivData->LinkStatus = 0; + SmapDrivPrivData->SmapIsInitialized = 0; + SmapDrivPrivData->SmapDriverStarting = 0; SMapCommonLinkStateDown(SmapDrivPrivData); } } if (EFBits & SMAP_EVENT_START) { if (!SmapDrivPrivData->SmapIsInitialized) { - SmapDrivPrivData->SmapDriverStarted = 1; + SmapDrivPrivData->SmapDriverStarting = 1; SpdIntrEnable(DEV9_SMAP_INTR_MASK2); if ((result = InitPHY(SmapDrivPrivData)) != 0) break; if (SmapDrivPrivData->NetDevStopFlag) { - SmapDrivPrivData->NetDevStopFlag = 0; + SmapDrivPrivData->NetDevStopFlag = 0; + SmapDrivPrivData->SmapDriverStarting = 0; continue; } SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, SMAP_E3_TXMAC_ENABLE | SMAP_E3_RXMAC_ENABLE); DelayThread(10000); - SmapDrivPrivData->SmapIsInitialized = 1; + SmapDrivPrivData->SmapIsInitialized = 1; + SmapDrivPrivData->SmapDriverStarting = 0; SMapCommonLinkStateUp(SmapDrivPrivData); @@ -517,6 +562,9 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData) if (IntrReg & SMAP_INTR_RXDNV) { SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_RXDNV; SmapDrivPrivData->RuntimeStats.RxFrameOverrunCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Over_Er += 1; +#endif } if (IntrReg & SMAP_INTR_TXDNV) { SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_TXDNV; @@ -594,6 +642,7 @@ static int Dev9IntrCb(int flag) static void Dev9PreDmaCbHandler(int bcr, int dir) { + // cppcheck-suppress constVariablePointer volatile u8 *smap_regbase; u16 SliceCount; @@ -610,6 +659,7 @@ static void Dev9PreDmaCbHandler(int bcr, int dir) static void Dev9PostDmaCbHandler(int bcr, int dir) { + // cppcheck-suppress constVariablePointer volatile u8 *smap_regbase; (void)bcr; @@ -626,6 +676,7 @@ static void Dev9PostDmaCbHandler(int bcr, int dir) // For the initial startup, as legacy programs expect the Ethernet interface to be ready once SMAP finishes initialization. int SMAPInitStart(void) { + // cppcheck-suppress constVariablePointer volatile u8 *emac3_regbase; #if USE_GP_REGISTER @@ -662,15 +713,29 @@ int SMAPInitStart(void) } #endif -int SMAPStart(void) +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) +#ifdef BUILDING_SMAP_NETDEV +static int SMAPStart(void *priv, int flags) +#else +static int SMAPStart(void) +#endif { + struct SmapDriverData *SmapDrivPrivData; #if USE_GP_REGISTER void *OldGP; OldGP = SetModuleGP(); #endif - SetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_START); +#ifdef BUILDING_SMAP_NETDEV + (void)flags; + + SmapDrivPrivData = (struct SmapDriverData *)priv; +#else + SmapDrivPrivData = &SmapDriverData; +#endif + + SetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_START); #if USE_GP_REGISTER SetGP(OldGP); @@ -679,61 +744,108 @@ int SMAPStart(void) return 0; } -void SMAPStop(void) +#ifdef BUILDING_SMAP_NETDEV +static int SMAPStop(void *priv, int flags) +#else +static void SMAPStop(void) +#endif { + struct SmapDriverData *SmapDrivPrivData; #if USE_GP_REGISTER void *OldGP; OldGP = SetModuleGP(); #endif - SetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_STOP); - SmapDriverData.NetDevStopFlag = 1; +#ifdef BUILDING_SMAP_NETDEV + (void)flags; + + SmapDrivPrivData = (struct SmapDriverData *)priv; +#else + SmapDrivPrivData = &SmapDriverData; +#endif + + SetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_STOP); + SmapDrivPrivData->NetDevStopFlag = 1; #if USE_GP_REGISTER SetGP(OldGP); #endif + +#ifdef BUILDING_SMAP_NETDEV + return 0; +#endif } +#endif static void ClearPacketQueue(struct SmapDriverData *SmapDrivPrivData) { int OldState; - void *pkt; + void *data; + void *pbuf; + data = NULL; CpuSuspendIntr(&OldState); - pkt = SmapDrivPrivData->packetToSend; + pbuf = SmapDrivPrivData->packetToSend; SmapDrivPrivData->packetToSend = NULL; CpuResumeIntr(OldState); - if (pkt != NULL) { - while (SMAPCommonTxPacketNext(SmapDrivPrivData, &pkt) > 0) - SMAPCommonTxPacketDeQ(SmapDrivPrivData, &pkt); + while (pbuf != NULL) { +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Dropped += 1; +#endif + if (SMAPCommonTxPacketNext(SmapDrivPrivData, &data, &pbuf) <= 0) + break; + SMAPCommonTxPacketDeQ(SmapDrivPrivData, &data, &pbuf); } } +#ifdef BUILDING_SMAP_NETDEV +static int SMAPXmit_NetDev(void *priv, int flags) +#else void SMAPXmit(void) +#endif { + struct SmapDriverData *SmapDrivPrivData; #if USE_GP_REGISTER void *OldGP; OldGP = SetModuleGP(); #endif +#ifdef BUILDING_SMAP_NETDEV + (void)flags; + + SmapDrivPrivData = (struct SmapDriverData *)priv; +#else + SmapDrivPrivData = &SmapDriverData; +#endif + if (SmapDriverData.LinkStatus) { if (QueryIntrContext()) - iSetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_XMIT); + iSetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_XMIT); else - SetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_XMIT); + SetEventFlag(SmapDrivPrivData->Dev9IntrEventFlag, SMAP_EVENT_XMIT); } else { // No link. Clear the packet queue. - ClearPacketQueue(&SmapDriverData); + ClearPacketQueue(SmapDrivPrivData); } #if USE_GP_REGISTER SetGP(OldGP); #endif +#ifdef BUILDING_SMAP_NETDEV + return 0; +#endif } +#ifdef BUILDING_SMAP_NETDEV +void SMAPXmit(void) +{ + SMAPXmit_NetDev(&SmapDriverData, 0); +} +#endif + #ifdef BUILDING_SMAP_NETMAN static int SMAPGetLinkMode(void) { @@ -813,16 +925,258 @@ static inline int SMAPGetLinkStatus(void) { return ((SmapDriverData.SmapIsInitialized && SmapDriverData.LinkStatus) ? NETMAN_NETIF_ETH_LINK_STATE_UP : NETMAN_NETIF_ETH_LINK_STATE_DOWN); } +#endif -int SMAPIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length) +#ifdef BUILDING_SMAP_NETDEV +static int do_set_multicast_list_helper(const struct SmapDriverData *SmapDrivPrivData, u8 *in_out_ptr, int in_out_len) +{ + // cppcheck-suppress constVariablePointer + volatile u8 *emac3_regbase; + int i; + u16 group_hash[4]; + + emac3_regbase = SmapDrivPrivData->emac3_regbase; + bzero(group_hash, sizeof(group_hash)); + if (in_out_len >= 0) { + int length_div_6; + + length_div_6 = in_out_len / 6; + if (in_out_len != 6 * length_div_6) { + return -512; + } + if (in_out_ptr) { + int k; + + for (k = 0; k < length_div_6; k += 1) { + if ((*in_out_ptr & 1) != 0) { + unsigned int cur_group_1; + unsigned int cur_group_2; + + cur_group_1 = (unsigned int)-1; + for (i = 0; i < 4; i += 1) { + u8 cur_item; + int j; + + cur_item = *in_out_ptr++; + // This is crc32 + for (j = 0; j < 6; j += 1) { + cur_group_2 = cur_group_1 << 1; + if (((((cur_group_1 & 0x80000000) != 0) ^ cur_item) & 1) != 0) + cur_group_2 ^= 0x4C11DB7u; + cur_group_1 = cur_group_2; + cur_item >>= 1; + } + } + group_hash[cur_group_2 >> 30] |= 1 << ((cur_group_2 >> 26) & 0xF); + } else { + in_out_ptr += 6; + } + } + } + } else { + if (in_out_ptr) + return -512; + for (i = 0; i < 4; i += 1) { + group_hash[i] = -1; + } + } + SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH1, group_hash[3]); + SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH2, group_hash[2]); + SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH3, group_hash[1]); + SMAP_EMAC3_SET32(SMAP_R_EMAC3_GROUP_HASH4, group_hash[0]); + return 0; +} +#endif + +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) +#ifdef BUILDING_SMAP_NETDEV +static int SMAPIoctl(void *priv, int command, void *in_out_ptr, int in_out_len) +#else +static int SMAPIoctl(unsigned int command, void *args, unsigned int args_len, void *output, unsigned int length) +#endif { int result; +#ifdef BUILDING_SMAP_NETDEV + struct SmapDriverData *SmapDrivPrivData; + const void *tmpoutptr; + int bufasint; +#endif #if USE_GP_REGISTER void *OldGP; OldGP = SetModuleGP(); #endif +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData = (struct SmapDriverData *)priv; + bufasint = 0; + result = -512; + tmpoutptr = NULL; + switch (command) { + case sceInetNDCC_GET_IF_TYPE: + result = sceInetNDIFT_ETHERNET; + break; + case sceInetNDCC_GET_NEGO_STATUS: { + result = 0; + if ((int)(SmapDrivPrivData->LinkStatus) > 0) + result = SmapDrivPrivData->LinkMode; + break; + } + case sceInetNDCC_GET_LINK_STATUS: + result = SmapDrivPrivData->LinkStatus; + break; + case sceInetNDCC_GET_THPRI: + result = ThreadPriority; + break; + case sceInetNDCC_SET_THPRI: { + if (in_out_ptr && in_out_len == 4) { + result = -403; + memcpy(&bufasint, in_out_ptr, 4); + if ((unsigned int)(bufasint - 9) < 0x73) { + ThreadPriority = bufasint; + result = ChangeThreadPriority(SmapDrivPrivData->IntrHandlerThreadID, bufasint); + } + } + break; + } + case sceInetNDCC_GET_NEGO_MODE: { + bufasint = 0; + if (EnableAutoNegotiation != 0) + bufasint |= sceInetNDNEGO_AUTO; + if ((SmapConfiguration & 0x400) != 0) + bufasint |= sceInetNDNEGO_PAUSE; + if ((SmapConfiguration & 0x100) != 0) + bufasint |= sceInetNDNEGO_TX_FD; + if ((SmapConfiguration & 0x80) != 0) + bufasint |= sceInetNDNEGO_TX; + if ((SmapConfiguration & 0x40) != 0) + bufasint |= sceInetNDNEGO_10_FD; + if ((SmapConfiguration & 0x20) != 0) + bufasint |= sceInetNDNEGO_10; + tmpoutptr = &bufasint; + break; + } + case sceInetNDCC_SET_NEGO_MODE: { + if (in_out_ptr && in_out_len == 4) { + int tmpconfig; + + tmpconfig = 0; + memcpy(&bufasint, in_out_ptr, 4); + EnableAutoNegotiation = ((bufasint & sceInetNDNEGO_AUTO) != 0 ? 1 : 0); + if ((bufasint & sceInetNDNEGO_PAUSE) != 0) + tmpconfig |= 0x400; + if ((bufasint & sceInetNDNEGO_TX_FD) != 0) + tmpconfig |= 0x100; + if ((bufasint & sceInetNDNEGO_TX) != 0) + tmpconfig |= 0x80; + if ((bufasint & sceInetNDNEGO_10_FD) != 0) + tmpconfig |= 0x40; + if ((bufasint & sceInetNDNEGO_10) != 0) + tmpconfig |= 0x20; + SmapConfiguration = tmpconfig; + result = 0; + } + break; + } + case sceInetNDCC_GET_MULTICAST: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Multicast; + break; + case sceInetNDCC_GET_COLLISIONS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Collisions; + break; + case sceInetNDCC_GET_RX_LENGTH_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Length_Er; + break; + case sceInetNDCC_GET_RX_OVER_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Over_Er; + break; + case sceInetNDCC_GET_RX_CRC_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Crc_Er; + break; + case sceInetNDCC_GET_RX_FRAME_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Frame_Er; + break; + case sceInetNDCC_GET_RX_FIFO_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Fifo_Er; + break; + case sceInetNDCC_GET_RX_MISSED_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Missed_Er; + break; + case sceInetNDCC_GET_TX_ABORTED_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Aborted_Er; + break; + case sceInetNDCC_GET_TX_CARRIER_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Carrier_Er; + break; + case sceInetNDCC_GET_TX_FIFO_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Fifo_Er; + break; + case sceInetNDCC_GET_TX_HEARTBEAT_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Heartbeat_Er; + break; + case sceInetNDCC_GET_TX_WINDOW_ER: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Window_Er; + break; + case sceInetNDCC_GET_RX_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Packets; + break; + case sceInetNDCC_GET_TX_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Packets; + break; + case sceInetNDCC_GET_RX_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Bytes; + break; + case sceInetNDCC_GET_TX_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Bytes; + break; + case sceInetNDCC_GET_RX_ERRORS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Errors; + break; + case sceInetNDCC_GET_TX_ERRORS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Errors; + break; + case sceInetNDCC_GET_RX_DROPPED: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Dropped; + break; + case sceInetNDCC_GET_TX_DROPPED: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Dropped; + break; + case sceInetNDCC_GET_RX_BROADCAST_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Packets; + break; + case sceInetNDCC_GET_TX_BROADCAST_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Packets; + break; + case sceInetNDCC_GET_RX_BROADCAST_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Bytes; + break; + case sceInetNDCC_GET_TX_BROADCAST_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Bytes; + break; + case sceInetNDCC_GET_RX_MULTICAST_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Packets; + break; + case sceInetNDCC_GET_TX_MULTICAST_PACKETS: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Packets; + break; + case sceInetNDCC_GET_RX_MULTICAST_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Bytes; + break; + case sceInetNDCC_GET_TX_MULTICAST_BYTES: + tmpoutptr = &SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Bytes; + break; + case sceInetNDCC_SET_MULTICAST_LIST: + result = do_set_multicast_list_helper(SmapDrivPrivData, in_out_ptr, in_out_len); + break; + default: + break; + } + + if (tmpoutptr && in_out_ptr && in_out_len == 4) { + memcpy(in_out_ptr, tmpoutptr, in_out_len); + result = 0; + } +#else (void)args_len; (void)length; @@ -878,6 +1232,7 @@ int SMAPIoctl(unsigned int command, void *args, unsigned int args_len, void *out default: result = -1; } +#endif #if USE_GP_REGISTER SetGP(OldGP); @@ -912,11 +1267,9 @@ void SMAPOutputDebugInformation(void) rx_bd[i].pointer != 0 || i == bdidx) { if (i == bdidx) - DEBUG_PRINTF() - (" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x <--\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer); + DEBUG_PRINTF(" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x <--\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer); else - DEBUG_PRINTF() - (" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer); + DEBUG_PRINTF(" - rx_bd[%d]: 0x%x / 0x%x / %d / 0x%x\n", i, rx_bd[i].ctrl_stat, rx_bd[i].reserved, rx_bd[i].length, rx_bd[i].pointer); } } @@ -974,6 +1327,11 @@ static inline int SetupNetDev(void) int result; iop_event_t EventFlagData; iop_thread_t ThreadData; +#ifdef BUILDING_SMAP_NETDEV + u32 mac_address_lo, mac_address_hi; + // cppcheck-suppress constVariablePointer + volatile u8 *emac3_regbase; +#endif #ifdef BUILDING_SMAP_NETMAN static struct NetManNetIF device = { "SMAP", @@ -987,6 +1345,34 @@ static inline int SetupNetDev(void) }; #endif +#ifdef BUILDING_SMAP_NETDEV + emac3_regbase = SmapDriverData.emac3_regbase; + + SmapDriverData.m_devops.module_name = "smap"; + SmapDriverData.m_devops.vendor_name = "SCE"; + SmapDriverData.m_devops.device_name = "Ethernet (Network Adaptor)"; + SmapDriverData.m_devops.bus_type = sceInetBus_NIC; + SmapDriverData.m_devops.prot_ver = sceInetDevProtVer; + SmapDriverData.m_devops.flags = sceInetDevF_ARP | sceInetDevF_Multicast | sceInetDevF_NIC; + SmapDriverData.m_devops.start = &SMAPStart; + SmapDriverData.m_devops.stop = &SMAPStop; + SmapDriverData.m_devops.xmit = &SMAPXmit_NetDev; + SmapDriverData.m_devops.impl_ver = 0; + SmapDriverData.m_devops.priv = &SmapDriverData; + SmapDriverData.m_devops.control = &SMAPIoctl; + SmapDriverData.m_devops.mtu = 1500; + + mac_address_hi = SMAP_EMAC3_GET32(SMAP_R_EMAC3_ADDR_HI); + mac_address_lo = SMAP_EMAC3_GET32(SMAP_R_EMAC3_ADDR_LO); + + SmapDriverData.m_devops.hw_addr[0] = mac_address_hi >> 8; + SmapDriverData.m_devops.hw_addr[1] = mac_address_hi; + SmapDriverData.m_devops.hw_addr[2] = mac_address_lo >> 24; + SmapDriverData.m_devops.hw_addr[3] = mac_address_lo >> 16; + SmapDriverData.m_devops.hw_addr[4] = mac_address_lo >> 8; + SmapDriverData.m_devops.hw_addr[5] = mac_address_lo; +#endif + EventFlagData.attr = 0; EventFlagData.option = 0; EventFlagData.bits = 0; @@ -1008,7 +1394,7 @@ static inline int SetupNetDev(void) } if ((result = StartThread(SmapDriverData.IntrHandlerThreadID, &SmapDriverData)) < 0) { - printf("smap: StartThread -> %d\n", result); + sceInetPrintf("smap: StartThread -> %d\n", result); DeleteThread(SmapDriverData.IntrHandlerThreadID); DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag); return result; @@ -1016,7 +1402,17 @@ static inline int SetupNetDev(void) #ifdef BUILDING_SMAP_NETMAN if ((SmapDriverData.NetIFID = NetManRegisterNetIF(&device)) < 0) { - printf("smap: NetManRegisterNetIF -> %d\n", result); + sceInetPrintf("smap: NetManRegisterNetIF -> %d\n", result); + TerminateThread(SmapDriverData.IntrHandlerThreadID); + DeleteThread(SmapDriverData.IntrHandlerThreadID); + DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag); + return -6; + } +#endif + +#ifdef BUILDING_SMAP_NETDEV + if ((result = sceInetRegisterNetDevice(&SmapDriverData.m_devops)) < 0) { + sceInetPrintf("smap: sceInetRegisterNetDevice -> %d\n", result); TerminateThread(SmapDriverData.IntrHandlerThreadID); DeleteThread(SmapDriverData.IntrHandlerThreadID); DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag); @@ -1068,7 +1464,7 @@ static int ParseSmapConfiguration(const char *cmd, unsigned int *configuration) return 0; fail_end: - printf("smap: %s: %s - invalid digit\n", "scan_number", CmdStart); + sceInetPrintf("smap: %s: %s - invalid digit\n", "scan_number", CmdStart); return -1; } @@ -1085,10 +1481,11 @@ int smap_init(int argc, char *argv[]) USE_SMAP_RX_BD; checksum16 = 0; -#ifdef BUILDING_SMAP_NETMAN +#if defined(BUILDING_SMAP_NETMAN) || defined(BUILDING_SMAP_NETDEV) argc--; argv++; #endif + SmapDriverData.LinkStatus = -1; while (argc > 0) { if (strcmp("-help", *argv) == 0) { return DisplayHelpMessage(); @@ -1193,8 +1590,6 @@ int smap_init(int argc, char *argv[]) rx_bd[i].pointer = 0; } - SmapDriverData.TxBufferSpaceAvailable = SMAP_TX_BUFSIZE; - SMAP_REG16(SMAP_R_INTR_CLR) = DEV9_SMAP_ALL_INTR_MASK; /* Retrieve the MAC address and verify it's integrity. */ @@ -1246,9 +1641,43 @@ int smap_init(int argc, char *argv[]) return SetupNetDev(); } +#ifdef BUILDING_SMAP_NETDEV +int smap_deinit(void) +{ + int i; + // cppcheck-suppress constVariablePointer + volatile u8 *emac3_regbase; + + if ((SmapDriverData.SmapDriverStarting || SmapDriverData.SmapIsInitialized) && !SmapDriverData.NetDevStopFlag) { + sceInetPrintf("smap: can't unload (busy)\n"); + return 2; + } + + emac3_regbase = SmapDriverData.emac3_regbase; + + sceInetUnregisterNetDevice(&SmapDriverData.m_devops); + TerminateThread(SmapDriverData.IntrHandlerThreadID); + DeleteThread(SmapDriverData.IntrHandlerThreadID); + DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag); + if (SmapDriverData.packetToSend) + sceInetFreePkt(&SmapDriverData.m_devops, (sceInetPkt_t *)SmapDriverData.packetToSend); + if (SmapDriverData.EnableLinkCheckTimer) + CancelAlarm((unsigned int (*)(void *))LinkCheckTimerCB, &SmapDriverData); + dev9RegisterPreDmaCb(1, NULL); + dev9RegisterPostDmaCb(1, NULL); + for (i = 2; i < 7; i++) { + dev9RegisterIntrCb(i, NULL); + } + dev9IntrDisable(DEV9_SMAP_INTR_MASK2); + SMAP_EMAC3_SET32(SMAP_R_EMAC3_MODE0, 0); + return 1; +} +#endif + int SMAPGetMACAddress(u8 *buffer) { u32 mac_address_lo, mac_address_hi; + // cppcheck-suppress constVariablePointer volatile u8 *emac3_regbase; int OldState; diff --git a/iop/network/smap/src/xfer.c b/iop/network/smap/src/xfer.c index e35ce4611ec..5699cff5216 100644 --- a/iop/network/smap/src/xfer.c +++ b/iop/network/smap/src/xfer.c @@ -78,6 +78,7 @@ int HandleRxIntr(struct SmapDriverData *SmapDrivPrivData) USE_SMAP_RX_BD; int NumPacketsReceived, i; volatile smap_bd_t *PktBdPtr; + // cppcheck-suppress constVariablePointer volatile u8 *smap_regbase; u16 ctrl_stat, length, pointer, LengthRounded; @@ -97,19 +98,42 @@ int HandleRxIntr(struct SmapDriverData *SmapDrivPrivData) if (ctrl_stat & (SMAP_BD_RX_INRANGE | SMAP_BD_RX_OUTRANGE | SMAP_BD_RX_FRMTOOLONG | SMAP_BD_RX_BADFCS | SMAP_BD_RX_ALIGNERR | SMAP_BD_RX_SHORTEVNT | SMAP_BD_RX_RUNTFRM | SMAP_BD_RX_OVERRUN)) { for (i = 0; i < 16; i++) - if ((ctrl_stat >> i) & 1) + if ((ctrl_stat >> i) & 1) { SmapDrivPrivData->RuntimeStats.RxErrorCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_RxErrorVarious[i] += 1; +#endif + } SmapDrivPrivData->RuntimeStats.RxDroppedFrameCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Errors += 1; +#endif - if (ctrl_stat & SMAP_BD_RX_OVERRUN) + if (ctrl_stat & SMAP_BD_RX_OVERRUN) { SmapDrivPrivData->RuntimeStats.RxFrameOverrunCount++; - if (ctrl_stat & (SMAP_BD_RX_INRANGE | SMAP_BD_RX_OUTRANGE | SMAP_BD_RX_FRMTOOLONG | SMAP_BD_RX_SHORTEVNT | SMAP_BD_RX_RUNTFRM)) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Over_Er += 1; +#endif + } + if (ctrl_stat & (SMAP_BD_RX_INRANGE | SMAP_BD_RX_OUTRANGE | SMAP_BD_RX_FRMTOOLONG | SMAP_BD_RX_SHORTEVNT | SMAP_BD_RX_RUNTFRM)) { SmapDrivPrivData->RuntimeStats.RxFrameBadLengthCount++; - if (ctrl_stat & SMAP_BD_RX_BADFCS) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Length_Er += 1; +#endif + } + if (ctrl_stat & SMAP_BD_RX_BADFCS) { SmapDrivPrivData->RuntimeStats.RxFrameBadFCSCount++; - if (ctrl_stat & SMAP_BD_RX_ALIGNERR) +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Crc_Er += 1; +#endif + } + if (ctrl_stat & SMAP_BD_RX_ALIGNERR) { SmapDrivPrivData->RuntimeStats.RxFrameBadAlignmentCount++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Frame_Er += 1; +#endif + } // Original did this whenever a frame is dropped. SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded; @@ -118,10 +142,27 @@ int HandleRxIntr(struct SmapDriverData *SmapDrivPrivData) if ((pbuf = SMapCommonStackAllocRxPacket(SmapDrivPrivData, LengthRounded, &payload)) != NULL) { CopyFromFIFO(SmapDrivPrivData->smap_regbase, payload, length, pointer); - SMapStackEnQRxPacket(SmapDrivPrivData, pbuf); +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Packets += 1; + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Bytes += length; + if ((*((u8 *)payload) & 1) != 0) { + SmapDrivPrivData->RuntimeStats_NetDev.m_Multicast += 1; + if (*(u32 *)payload == (u32)-1 && *((u16 *)payload + 2) == 0xFFFF) { + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Packets += 1; + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Bytes += length; + } else { + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Packets += 1; + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Bytes += length; + } + } +#endif + SMapStackEnQRxPacket(SmapDrivPrivData, pbuf, length); NumPacketsReceived++; } else { SmapDrivPrivData->RuntimeStats.RxAllocFail++; +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Dropped += 1; +#endif // Original did this whenever a frame is dropped. SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded; } @@ -134,6 +175,12 @@ int HandleRxIntr(struct SmapDriverData *SmapDrivPrivData) break; } +#ifdef BUILDING_SMAP_NETDEV + if (NumPacketsReceived) { + SetEventFlag(SmapDrivPrivData->m_devops.evfid, sceInetDevEFP_Recv); + } +#endif + return NumPacketsReceived; } @@ -141,50 +188,65 @@ int HandleTxReqs(struct SmapDriverData *SmapDrivPrivData) { int result; void *data; + void *pbuf; USE_SMAP_TX_BD; volatile smap_bd_t *BD_ptr; u16 BD_data_ptr; unsigned int SizeRounded; + volatile u8 *smap_regbase; - result = 0; + result = 0; + smap_regbase = SmapDrivPrivData->smap_regbase; while (1) { int length; data = NULL; - if ((length = SMAPCommonTxPacketNext(SmapDrivPrivData, &data)) < 1) { + if ((length = SMAPCommonTxPacketNext(SmapDrivPrivData, &data, &pbuf)) < 1) { return result; } - SmapDrivPrivData->packetToSend = data; + SmapDrivPrivData->packetToSend = pbuf; + + if (SmapDrivPrivData->NumPacketsInTx >= SMAP_BD_MAX_ENTRY) { + return result; // Queue full + } + SizeRounded = (length + 3) & ~3; - if (SmapDrivPrivData->NumPacketsInTx < SMAP_BD_MAX_ENTRY) { - { - SizeRounded = (length + 3) & ~3; + if (SmapDrivPrivData->TxBufferSpaceAvailable < SizeRounded) { + return result; // Out of FIFO space + } - if (SmapDrivPrivData->TxBufferSpaceAvailable >= SizeRounded) { - volatile u8 *smap_regbase; +#ifdef BUILDING_SMAP_NETDEV + if ((*((u8 *)data) & 1) != 0) { + if (*(u32 *)data == (u32)-1 && *((u16 *)data + 2) == 0xFFFF) { + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Packets += 1; + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Bytes += length; + } else { + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Packets += 1; + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Bytes += length; + } + } +#endif - smap_regbase = SmapDrivPrivData->smap_regbase; + BD_data_ptr = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE; + BD_ptr = &tx_bd[SmapDrivPrivData->TxBDIndex % SMAP_BD_MAX_ENTRY]; - BD_data_ptr = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE; - BD_ptr = &tx_bd[SmapDrivPrivData->TxBDIndex % SMAP_BD_MAX_ENTRY]; + CopyToFIFO(smap_regbase, data, length); - CopyToFIFO(SmapDrivPrivData->smap_regbase, data, length); + result++; + BD_ptr->length = length; + BD_ptr->pointer = BD_data_ptr; + SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0; + BD_ptr->ctrl_stat = SMAP_BD_TX_READY | SMAP_BD_TX_GENFCS | SMAP_BD_TX_GENPAD; + SmapDrivPrivData->TxBDIndex++; + SmapDrivPrivData->NumPacketsInTx++; + SmapDrivPrivData->TxBufferSpaceAvailable -= SizeRounded; - result++; - BD_ptr->length = length; - BD_ptr->pointer = BD_data_ptr; - SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0; - BD_ptr->ctrl_stat = SMAP_BD_TX_READY | SMAP_BD_TX_GENFCS | SMAP_BD_TX_GENPAD; - SmapDrivPrivData->TxBDIndex++; - SmapDrivPrivData->NumPacketsInTx++; - SmapDrivPrivData->TxBufferSpaceAvailable -= SizeRounded; - } else - return result; // Out of FIFO space - } - } else - return result; // Queue full +#ifdef BUILDING_SMAP_NETDEV + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Bytes += length; + SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Packets += 1; +#endif SmapDrivPrivData->packetToSend = NULL; - SMAPCommonTxPacketDeQ(SmapDrivPrivData, &data); + SMAPCommonTxPacketDeQ(SmapDrivPrivData, &data, &pbuf); } }