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 volatile u8 *smap_regbase;
82 u16 ctrl_stat, length, pointer, LengthRounded;
83
84 smap_regbase = SmapDrivPrivData->smap_regbase;
85
86 NumPacketsReceived = 0;
87
88 /* Non-Sony: Workaround for the hardware BUG whereby the Rx FIFO of the MAL becomes unresponsive or loses frames when under load.
89 Check that there are frames to process, before accessing the BD registers. */
90 while (SMAP_REG8(SMAP_R_RXFIFO_FRAME_CNT) > 0) {
91 PktBdPtr = &rx_bd[SmapDrivPrivData->RxBDIndex % SMAP_BD_MAX_ENTRY];
92 ctrl_stat = PktBdPtr->ctrl_stat;
93 if (!(ctrl_stat & SMAP_BD_RX_EMPTY)) {
94 length = PktBdPtr->length;
95 LengthRounded = (length + 3) & ~3;
96 pointer = PktBdPtr->pointer;
97
99 for (i = 0; i < 16; i++)
100 if ((ctrl_stat >> i) & 1)
101 SmapDrivPrivData->RuntimeStats.RxErrorCount++;
102
103 SmapDrivPrivData->RuntimeStats.RxDroppedFrameCount++;
104
105 if (ctrl_stat & SMAP_BD_RX_OVERRUN)
106 SmapDrivPrivData->RuntimeStats.RxFrameOverrunCount++;
108 SmapDrivPrivData->RuntimeStats.RxFrameBadLengthCount++;
109 if (ctrl_stat & SMAP_BD_RX_BADFCS)
110 SmapDrivPrivData->RuntimeStats.RxFrameBadFCSCount++;
111 if (ctrl_stat & SMAP_BD_RX_ALIGNERR)
112 SmapDrivPrivData->RuntimeStats.RxFrameBadAlignmentCount++;
113
114 // Original did this whenever a frame is dropped.
115 SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded;
116 } else {
117 void *pbuf, *payload;
118
119 if ((pbuf = SMapCommonStackAllocRxPacket(SmapDrivPrivData, LengthRounded, &payload)) != NULL) {
120 CopyFromFIFO(SmapDrivPrivData->smap_regbase, payload, length, pointer);
121 SMapStackEnQRxPacket(SmapDrivPrivData, pbuf);
122 NumPacketsReceived++;
123 } else {
124 SmapDrivPrivData->RuntimeStats.RxAllocFail++;
125 // Original did this whenever a frame is dropped.
126 SMAP_REG16(SMAP_R_RXFIFO_RD_PTR) = pointer + LengthRounded;
127 }
128 }
129
130 SMAP_REG8(SMAP_R_RXFIFO_FRAME_DEC) = 0;
131 PktBdPtr->ctrl_stat = SMAP_BD_RX_EMPTY;
132 SmapDrivPrivData->RxBDIndex++;
133 } else
134 break;
135 }
136
137 return NumPacketsReceived;
138}
139
140int HandleTxReqs(struct SmapDriverData *SmapDrivPrivData)
141{
142 int result;
143 void *data;
144 USE_SMAP_TX_BD;
145 volatile smap_bd_t *BD_ptr;
146 u16 BD_data_ptr;
147 unsigned int SizeRounded;
148
149 result = 0;
150 while (1) {
151 int length;
152
153 data = NULL;
154 if ((length = SMAPCommonTxPacketNext(SmapDrivPrivData, &data)) < 1) {
155 return result;
156 }
157 SmapDrivPrivData->packetToSend = data;
158
159 if (SmapDrivPrivData->NumPacketsInTx < SMAP_BD_MAX_ENTRY) {
160 {
161 SizeRounded = (length + 3) & ~3;
162
163 if (SmapDrivPrivData->TxBufferSpaceAvailable >= SizeRounded) {
164 volatile u8 *smap_regbase;
165
166 smap_regbase = SmapDrivPrivData->smap_regbase;
167
168 BD_data_ptr = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE;
169 BD_ptr = &tx_bd[SmapDrivPrivData->TxBDIndex % SMAP_BD_MAX_ENTRY];
170
171 CopyToFIFO(SmapDrivPrivData->smap_regbase, data, length);
172
173 result++;
174 BD_ptr->length = length;
175 BD_ptr->pointer = BD_data_ptr;
176 SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0;
178 SmapDrivPrivData->TxBDIndex++;
179 SmapDrivPrivData->NumPacketsInTx++;
180 SmapDrivPrivData->TxBufferSpaceAvailable -= SizeRounded;
181 } else
182 return result; // Out of FIFO space
183 }
184 } else
185 return result; // Queue full
186
187 SmapDrivPrivData->packetToSend = NULL;
188 SMAPCommonTxPacketDeQ(SmapDrivPrivData, &data);
189 }
190}
#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:200