PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
xfer.c
1
2#include <errno.h>
3#include <stdio.h>
4#include <dmacman.h>
5#include <dev9.h>
6#include <intrman.h>
7#include <loadcore.h>
8#include <modload.h>
9#include <stdio.h>
10#include <sysclib.h>
11#include <thbase.h>
12#include <thevent.h>
13#include <thsemap.h>
14#include <irx.h>
15
16#include <smapregs.h>
17#include <speedregs.h>
18
19#include "main.h"
20
21#include "xfer.h"
22#include "ipstack.h"
23
24static int SmapDmaTransfer(volatile u8 *smap_regbase, void *buffer, unsigned int size, int direction)
25{
26 unsigned int NumBlocks;
27 int result;
28
29 (void)smap_regbase;
30
31 /* Non-Sony: the original block size was (32*4 = 128) bytes.
32 However, that resulted in slightly lower performance due to the IOP needing to copy more data. */
33 if ((NumBlocks = size >> 6) > 0) {
34 if (SpdDmaTransfer(1, buffer, NumBlocks << 16 | 0x10, direction) >= 0) {
35 result = NumBlocks << 6;
36 } else
37 result = 0;
38 } else
39 result = 0;
40
41 return result;
42}
43
44static inline void CopyFromFIFO(volatile u8 *smap_regbase, void *buffer, unsigned int length, u16 RxBdPtr)
45{
46 int i, result;
47
48 if (buffer == NULL) {
49 return;
50 }
51
52 SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = RxBdPtr;
53
54 result = SmapDmaTransfer(smap_regbase, buffer, length, DMAC_TO_MEM);
55
56 for (i = result; (unsigned int)i < length; i += 4) {
57 ((u32 *)buffer)[i / 4] = SMAP_REG32(SMAP_R_RXFIFO_DATA);
58 }
59}
60
61static inline void CopyToFIFO(volatile u8 *smap_regbase, const void *buffer, unsigned int length)
62{
63 int i, result;
64
65 if (buffer == NULL) {
66 return;
67 }
68
69 result = SmapDmaTransfer(smap_regbase, (void *)buffer, length, DMAC_FROM_MEM);
70
71 for (i = result; (unsigned int)i < length; i += 4) {
72 SMAP_REG32(SMAP_R_TXFIFO_DATA) = ((u32 *)buffer)[i / 4];
73 }
74}
75
76int HandleRxIntr(struct SmapDriverData *SmapDrivPrivData)
77{
78 USE_SMAP_RX_BD;
79 int NumPacketsReceived, i;
80 volatile smap_bd_t *PktBdPtr;
81 // cppcheck-suppress constVariablePointer
82 volatile u8 *smap_regbase;
83 u16 ctrl_stat, length, pointer, LengthRounded;
84
85 smap_regbase = SmapDrivPrivData->smap_regbase;
86
87 NumPacketsReceived = 0;
88
89 /* Non-Sony: Workaround for the hardware BUG whereby the Rx FIFO of the MAL becomes unresponsive or loses frames when under load.
90 Check that there are frames to process, before accessing the BD registers. */
91 while (SMAP_REG8(SMAP_R_RXFIFO_FRAME_CNT) > 0) {
92 PktBdPtr = &rx_bd[SmapDrivPrivData->RxBDIndex % SMAP_BD_MAX_ENTRY];
93 ctrl_stat = PktBdPtr->ctrl_stat;
94 if (!(ctrl_stat & SMAP_BD_RX_EMPTY)) {
95 length = PktBdPtr->length;
96 LengthRounded = (length + 3) & ~3;
97 pointer = PktBdPtr->pointer;
98
100 for (i = 0; i < 16; i++)
101 if ((ctrl_stat >> i) & 1) {
102 SmapDrivPrivData->RuntimeStats.RxErrorCount++;
103#ifdef BUILDING_SMAP_NETDEV
104 SmapDrivPrivData->RuntimeStats_NetDev.m_RxErrorVarious[i] += 1;
105#endif
106 }
107
108 SmapDrivPrivData->RuntimeStats.RxDroppedFrameCount++;
109#ifdef BUILDING_SMAP_NETDEV
110 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Errors += 1;
111#endif
112
113 if (ctrl_stat & SMAP_BD_RX_OVERRUN) {
114 SmapDrivPrivData->RuntimeStats.RxFrameOverrunCount++;
115#ifdef BUILDING_SMAP_NETDEV
116 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Over_Er += 1;
117#endif
118 }
120 SmapDrivPrivData->RuntimeStats.RxFrameBadLengthCount++;
121#ifdef BUILDING_SMAP_NETDEV
122 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Length_Er += 1;
123#endif
124 }
125 if (ctrl_stat & SMAP_BD_RX_BADFCS) {
126 SmapDrivPrivData->RuntimeStats.RxFrameBadFCSCount++;
127#ifdef BUILDING_SMAP_NETDEV
128 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Crc_Er += 1;
129#endif
130 }
131 if (ctrl_stat & SMAP_BD_RX_ALIGNERR) {
132 SmapDrivPrivData->RuntimeStats.RxFrameBadAlignmentCount++;
133#ifdef BUILDING_SMAP_NETDEV
134 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Frame_Er += 1;
135#endif
136 }
137
138 // Original did this whenever a frame is dropped.
139 SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded;
140 } else {
141 void *pbuf, *payload;
142
143 if ((pbuf = SMapCommonStackAllocRxPacket(SmapDrivPrivData, LengthRounded, &payload)) != NULL) {
144 CopyFromFIFO(SmapDrivPrivData->smap_regbase, payload, length, pointer);
145#ifdef BUILDING_SMAP_NETDEV
146 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Packets += 1;
147 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Bytes += length;
148 if ((*((u8 *)payload) & 1) != 0) {
149 SmapDrivPrivData->RuntimeStats_NetDev.m_Multicast += 1;
150 if (*(u32 *)payload == (u32)-1 && *((u16 *)payload + 2) == 0xFFFF) {
151 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Packets += 1;
152 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Broadcast_Bytes += length;
153 } else {
154 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Packets += 1;
155 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Multicast_Bytes += length;
156 }
157 }
158#endif
159 SMapStackEnQRxPacket(SmapDrivPrivData, pbuf, length);
160 NumPacketsReceived++;
161 } else {
162 SmapDrivPrivData->RuntimeStats.RxAllocFail++;
163#ifdef BUILDING_SMAP_NETDEV
164 SmapDrivPrivData->RuntimeStats_NetDev.m_Rx_Dropped += 1;
165#endif
166 // Original did this whenever a frame is dropped.
167 SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded;
168 }
169 }
170
171 SMAP_REG8(SMAP_R_RXFIFO_FRAME_DEC) = 0;
172 PktBdPtr->ctrl_stat = SMAP_BD_RX_EMPTY;
173 SmapDrivPrivData->RxBDIndex++;
174 } else
175 break;
176 }
177
178#ifdef BUILDING_SMAP_NETDEV
179 if (NumPacketsReceived) {
180 SetEventFlag(SmapDrivPrivData->m_devops.evfid, sceInetDevEFP_Recv);
181 }
182#endif
183
184 return NumPacketsReceived;
185}
186
187int HandleTxReqs(struct SmapDriverData *SmapDrivPrivData)
188{
189 int result;
190 void *data;
191 void *pbuf;
192 USE_SMAP_TX_BD;
193 volatile smap_bd_t *BD_ptr;
194 u16 BD_data_ptr;
195 unsigned int SizeRounded;
196 volatile u8 *smap_regbase;
197
198 result = 0;
199 smap_regbase = SmapDrivPrivData->smap_regbase;
200 while (1) {
201 int length;
202
203 data = NULL;
204 if ((length = SMAPCommonTxPacketNext(SmapDrivPrivData, &data, &pbuf)) < 1) {
205 return result;
206 }
207 SmapDrivPrivData->packetToSend = pbuf;
208
209 if (SmapDrivPrivData->NumPacketsInTx >= SMAP_BD_MAX_ENTRY) {
210 return result; // Queue full
211 }
212 SizeRounded = (length + 3) & ~3;
213
214 if (SmapDrivPrivData->TxBufferSpaceAvailable < SizeRounded) {
215 return result; // Out of FIFO space
216 }
217
218#ifdef BUILDING_SMAP_NETDEV
219 if ((*((u8 *)data) & 1) != 0) {
220 if (*(u32 *)data == (u32)-1 && *((u16 *)data + 2) == 0xFFFF) {
221 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Packets += 1;
222 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Broadcast_Bytes += length;
223 } else {
224 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Packets += 1;
225 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Multicast_Bytes += length;
226 }
227 }
228#endif
229
230 BD_data_ptr = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE;
231 BD_ptr = &tx_bd[SmapDrivPrivData->TxBDIndex % SMAP_BD_MAX_ENTRY];
232
233 CopyToFIFO(smap_regbase, data, length);
234
235 result++;
236 BD_ptr->length = length;
237 BD_ptr->pointer = BD_data_ptr;
238 SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0;
240 SmapDrivPrivData->TxBDIndex++;
241 SmapDrivPrivData->NumPacketsInTx++;
242 SmapDrivPrivData->TxBufferSpaceAvailable -= SizeRounded;
243
244#ifdef BUILDING_SMAP_NETDEV
245 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Bytes += length;
246 SmapDrivPrivData->RuntimeStats_NetDev.m_Tx_Packets += 1;
247#endif
248
249 SmapDrivPrivData->packetToSend = NULL;
250 SMAPCommonTxPacketDeQ(SmapDrivPrivData, &data, &pbuf);
251 }
252}
#define SMAP_BD_RX_OVERRUN
Definition smapregs.h:362
#define SMAP_BD_TX_GENFCS
Definition smapregs.h:315
#define SMAP_BD_RX_BADFCS
Definition smapregs.h:374
#define SMAP_BD_RX_SHORTEVNT
Definition smapregs.h:370
#define SMAP_BD_TX_READY
Definition smapregs.h:313
#define SMAP_BD_RX_EMPTY
Definition smapregs.h:356
#define SMAP_BD_RX_FRMTOOLONG
Definition smapregs.h:376
vu16 length
Definition smapregs.h:290
#define SMAP_BD_RX_INRANGE
Definition smapregs.h:380
#define SMAP_BD_RX_ALIGNERR
Definition smapregs.h:372
#define SMAP_BD_RX_RUNTFRM
Definition smapregs.h:368
#define SMAP_BD_TX_GENPAD
Definition smapregs.h:317
#define SMAP_BD_RX_OUTRANGE
Definition smapregs.h:378
Definition tcpip.h:230