Skip to content

Commit

Permalink
Reverted the use of TXEND back to the use of TXDNV (like SONY), plus …
Browse files Browse the repository at this point in the history
…updated comments.
  • Loading branch information
sp193 committed May 2, 2016
1 parent 2f2d09c commit fda1552
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 101 deletions.
9 changes: 0 additions & 9 deletions iop/network/smap/src/include/common.h

This file was deleted.

33 changes: 21 additions & 12 deletions iop/network/smap/src/include/main.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "common.h"
//In the SONY original, all the calls to DEBUG_PRINTF() were to sceInetPrintf().
#define DEBUG_PRINTF(args...) printf(args)

#define MAX_FRAME_SIZE 1518

/*
Sorry, but even I can't explain the syntax used here. :(
Expand All @@ -13,16 +16,16 @@
__asm volatile("move $gp, %0" :: "r"(_ori_gp) : "gp")

struct RuntimeStats{
unsigned int RxDroppedFrameCount;
unsigned short int RxFrameOverrunCount;
unsigned short int RxFrameBadLengthCount;
unsigned short int RxFrameBadFCSCount;
unsigned short int RxFrameBadAlignmentCount;
unsigned int TxDroppedFrameCount;
unsigned short int TxFrameLOSSCRCount;
unsigned short int TxFrameEDEFERCount;
unsigned short int TxFrameCollisionCount;
unsigned short int TxFrameUnderrunCount;
u32 RxDroppedFrameCount;
u16 RxFrameOverrunCount;
u16 RxFrameBadLengthCount;
u16 RxFrameBadFCSCount;
u16 RxFrameBadAlignmentCount;
u32 TxDroppedFrameCount;
u16 TxFrameLOSSCRCount;
u16 TxFrameEDEFERCount;
u16 TxFrameCollisionCount;
u16 TxFrameUnderrunCount;
};

struct SmapDriverData{
Expand All @@ -37,7 +40,6 @@ struct SmapDriverData{
int Dev9IntrEventFlag;
int TxEndEventFlag;
int IntrHandlerThreadID;
int TxHandlerThreadID;
int NetIFID;
unsigned char SmapIsInitialized; //SMAP driver is initialized (software)
unsigned char NetDevStopFlag;
Expand All @@ -47,6 +49,13 @@ struct SmapDriverData{
iop_sys_clock_t LinkCheckTimer;
};

/* Event flag bits */
#define SMAP_EVENT_START 0x01
#define SMAP_EVENT_STOP 0x02
#define SMAP_EVENT_INTR 0x04
#define SMAP_EVENT_XMIT 0x08
#define SMAP_EVENT_LINK_CHECK 0x10

/* Function prototypes */
int smap_init(int argc, char *argv[]);
int SMAPStart(void);
Expand Down
128 changes: 52 additions & 76 deletions iop/network/smap/src/smap.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
3. XMIT event copies the frames to the Tx buffer and sets up the BDs.
4. Tx DNV handler is called (always, regardless of what event it is being handled!).
5. Interrupts are re-enabled, except for TXDNV.
6. If there are frames to transmit, write to TX_GNP_0
7. Enable TXDNV interrupt.
6. If there are frames to transmit, write to TX_GNP_0 and enable the TXDNV interrupt
The TXDNV interrupt is hence always disabled, but only enabled when a frame(s) is sent.
Perhaps there is a lack of a check on the TXEND interrupt because it is polling on the TX BDs before every transmission.
Expand All @@ -39,28 +38,20 @@
there is no valid frame to transmit, hence this design by SONY.
Homebrew:
1. TXEND interrupt is enabled.
2. Network stack calls SMAPSendPacket().
3. If there is either insufficient space or no BD available, wait.
4. Frame is copied into the Tx buffer and a BD is set up.
5. TX_GNP_0 is written to.
TXDNV is never used and TXEND remains active since the activation of the interface (with SMAPStart). */
1. Network stack calls SMAPSendPacket().
2. If there is either insufficient space or no BD available, wait.
3. Frame is copied into the Tx buffer and a BD is set up.
4. SMAPSendPacket issues the XMIT event (for the main thread)
5. Tx DNV handler is called (always, regardless of what event it is being handled!).
6. Interrupts are re-enabled, except for TXDNV.
7. If there are frames to transmit, write to TX_GNP_0 and enable the TXDNV interrupt */

#define DEV9_SMAP_ALL_INTR_MASK (SMAP_INTR_EMAC3|SMAP_INTR_RXEND|SMAP_INTR_TXEND|SMAP_INTR_RXDNV|SMAP_INTR_TXDNV)
/* Unlike the SONY original, the EMAC3 and RXDNV interrupts are not handled. They didn't even do anything useful in the SONY original.
The SONY original didn't use TXEND. */
#define DEV9_SMAP_INTR_MASK (SMAP_INTR_RXEND|SMAP_INTR_TXEND)
//Unlike the SONY original, the EMAC3 and RXDNV interrupts are not handled. They didn't even do anything useful in the SONY original.
#define DEV9_SMAP_INTR_MASK (SMAP_INTR_RXEND|SMAP_INTR_TXDNV)
//The Tx interrupt events are handled separately
#define DEV9_SMAP_INTR_MASK2 (SMAP_INTR_RXEND)

/* Event flag bits */
#define SMAP_EVENT_START 0x01
#define SMAP_EVENT_STOP 0x02
#define SMAP_EVENT_INTR 0x04
#define SMAP_EVENT_XMIT 0x08 //In the SONY original, this is set to kickstart the transmission of a frame. Not used in this driver.
#define SMAP_EVENT_LINK_CHECK 0x10

struct SmapDriverData SmapDriverData;

const char VersionString[]="Version 2.25.0";
Expand Down Expand Up @@ -368,10 +359,10 @@ static int HandleTxIntr(struct SmapDriverData *SmapDrivPrivData){
result++;
SmapDrivPrivData->TxDNVBDIndex++;
}while(SmapDrivPrivData->NumPacketsInTx>0);
}

//Not done in the SONY original (see SMAPSendPacket for more details).
SetEventFlag(SmapDrivPrivData->TxEndEventFlag, 1);
//Not done in the SONY original (see SMAPSendPacket for more details).
SetEventFlag(SmapDrivPrivData->TxEndEventFlag, 1);
}

return result;
}
Expand Down Expand Up @@ -403,7 +394,7 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){

if(EFBits&SMAP_EVENT_STOP){
if(SmapDrivPrivData->SmapIsInitialized){
dev9IntrDisable(DEV9_SMAP_INTR_MASK);
dev9IntrDisable(DEV9_SMAP_INTR_MASK2);
SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, 0);
SmapDrivPrivData->NetDevStopFlag=0;
SmapDrivPrivData->LinkStatus=0;
Expand All @@ -413,7 +404,7 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){
}
if(EFBits&SMAP_EVENT_START){
if(!SmapDrivPrivData->SmapIsInitialized){
dev9IntrEnable(DEV9_SMAP_INTR_MASK);
dev9IntrEnable(DEV9_SMAP_INTR_MASK2);
if((result=InitPHY(SmapDrivPrivData))!=0) break;
if(SmapDrivPrivData->NetDevStopFlag){
SmapDrivPrivData->NetDevStopFlag=0;
Expand All @@ -437,11 +428,10 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){
if(SmapDrivPrivData->SmapIsInitialized){
ResetCounterFlag=0;
if(EFBits&SMAP_EVENT_INTR){
while((IntrReg=SPD_REG16(SPD_R_INTR_STAT)&DEV9_SMAP_INTR_MASK2)!=0){
while((IntrReg=SPD_REG16(SPD_R_INTR_STAT)&DEV9_SMAP_INTR_MASK)!=0){
/* Other interrupts that were handled in the SONY original:
1. EMAC3: nothing useful was done, other than just acknowledging the events.
2. RXDNV: nothing useful was done, other than logging the event (same field as the BD_RX_OVERRUN event).
3. TXDNV: as this is done in its own thread, don't handle it here.
Original order/priority:
1. EMAC3
2. RXEND
Expand All @@ -451,9 +441,16 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){
SMAP_REG16(SMAP_R_INTR_CLR)=SMAP_INTR_RXEND;
ResetCounterFlag=HandleRxIntr(SmapDrivPrivData);
}
if(IntrReg&SMAP_INTR_TXDNV){
SMAP_REG16(SMAP_R_INTR_CLR)=SMAP_INTR_TXDNV;
HandleTxIntr(SmapDrivPrivData);
}
}

//In the SONY original, this was outside of the interrupt event check.
/* In the SONY original, this was outside of the interrupt event check.
Don't waste time re-enabling interrupts, if they were never disabled.
TXDNV is not enabled here, but only when frames are transmitted. */
dev9IntrEnable(DEV9_SMAP_INTR_MASK2);
}

Expand All @@ -462,8 +459,18 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){
It used to copy the frames into the Tx buffer and set up the BDs.
Immediately after that, there was also a call to the TXDNV handler function too.
After which, the interrupts were re-enabled (see above).
If there were frames to send out, TX_GNP_0 was set before the TXDNV event was enabled. */
After which, the interrupts were re-enabled (see above). */
/* if(EFBits&NETDEV_EVENT_XMIT)
HandleTxReqs(SmapDrivPrivData); */
HandleTxIntr(SmapDrivPrivData);

//dev9IntrEnable(DEV9_SMAP_INTR_MASK2);

//If there are frames to send out, let Tx channel 0 know and enable TXDNV.
if(SmapDrivPrivData->NumPacketsInTx>0){
SMAP_EMAC3_SET(SMAP_R_EMAC3_TxMODE0, SMAP_E3_TX_GNP_0);
dev9IntrEnable(SMAP_INTR_TXDNV);
}

if(ResetCounterFlag){
counter=3;
Expand All @@ -481,28 +488,14 @@ static void IntrHandlerThread(struct SmapDriverData *SmapDrivPrivData){
static int Dev9IntrCb(int flag){
SaveGP();

/* This used to disable all interrupts (DEV9_SMAP_ALL_INTR_MASK).
In this driver, the Tx DNV event has its own thread, so do not disable that event here. */
dev9IntrDisable(DEV9_SMAP_INTR_MASK2);
dev9IntrDisable(DEV9_SMAP_ALL_INTR_MASK);
iSetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_INTR);

RestoreGP();

return 0;
}

/* The SONY original had this even handled within the interrupt-handling thread.
For performance, this is split off into its own thread (and hence interrupt handler). */
static int Dev9TxEndIntrHandler(int flag){
SaveGP();

dev9IntrDisable(SMAP_INTR_TXEND);
iWakeupThread(SmapDriverData.TxHandlerThreadID);
RestoreGP();

return 0;
}

static void Dev9PreDmaCbHandler(int bcr, int dir){
volatile u8 *smap_regbase;
unsigned short int SliceCount;
Expand Down Expand Up @@ -546,24 +539,6 @@ void SMAPStop(void){
RestoreGP();
}

static void TxHandlerThread(void *arg){
USE_SPD_REGS;
volatile u8 *smap_regbase;

smap_regbase=((struct SmapDriverData *)arg)->smap_regbase;
while(1){
SleepThread();

while(SPD_REG16(SPD_R_INTR_STAT)&SMAP_INTR_TXEND){
SMAP_REG16(SMAP_R_INTR_CLR)=SMAP_INTR_TXEND;

HandleTxIntr(arg);
}

dev9IntrEnable(SMAP_INTR_TXEND);
}
}

static inline int SMAPGetLinkMode(void){
unsigned short int value;
int result;
Expand Down Expand Up @@ -721,7 +696,6 @@ static inline int SetupNetDev(void){
//Not done in the SONY original (refer to SMAPSendPacket for more details).
if((result=SmapDriverData.TxEndEventFlag=CreateEventFlag(&EventFlagData))<0){
DEBUG_PRINTF("smap: CreateEventFlag -> %d\n", result);
DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag);
return -6;
}

Expand All @@ -732,24 +706,27 @@ static inline int SetupNetDev(void){
ThreadData.stacksize=ThreadStackSize;
if((result=SmapDriverData.IntrHandlerThreadID=CreateThread(&ThreadData))<0){
DEBUG_PRINTF("smap: CreateThread -> %d\n", result);
DeleteEventFlag(SmapDriverData.TxEndEventFlag);
DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag);
return result;
}

// Unlike the SONY implementation, the Tx event stuff is moved into a separate thread for performance.
ThreadData.priority=ThreadPriority;
ThreadData.thread=(void*)&TxHandlerThread;
if((result=SmapDriverData.TxHandlerThreadID=CreateThread(&ThreadData))<0){
DEBUG_PRINTF("smap: CreateThread -> %d\n", result);
if((result=StartThread(SmapDriverData.IntrHandlerThreadID, &SmapDriverData))<0){
printf("smap: StartThread -> %d\n", result);
DeleteThread(SmapDriverData.IntrHandlerThreadID);
DeleteEventFlag(SmapDriverData.TxEndEventFlag);
DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag);
return result;
}

// Checks removed as calls to StartThread() shouldn't fail.
StartThread(SmapDriverData.IntrHandlerThreadID, &SmapDriverData);
StartThread(SmapDriverData.TxHandlerThreadID, &SmapDriverData);

SmapDriverData.NetIFID=NetManRegisterNetIF(&device);
if((SmapDriverData.NetIFID=NetManRegisterNetIF(&device))<0){
printf("smap: NetManRegisterNetIF -> %d\n", result);
TerminateThread(SmapDriverData.IntrHandlerThreadID);
DeleteThread(SmapDriverData.IntrHandlerThreadID);
DeleteEventFlag(SmapDriverData.TxEndEventFlag);
DeleteEventFlag(SmapDriverData.Dev9IntrEventFlag);
return -6;
}

return 0;
}
Expand Down Expand Up @@ -955,9 +932,8 @@ int smap_init(int argc, char *argv[]){
SMAP_EMAC3_SET(SMAP_R_EMAC3_TX_THRESHOLD, 12<<SMAP_E3_TX_THRESHLD_BITSFT);
SMAP_EMAC3_SET(SMAP_R_EMAC3_RX_WATERMARK, 16<<SMAP_E3_RX_LO_WATER_BITSFT|128<<SMAP_E3_RX_HI_WATER_BITSFT);

//In the SONY original, Dev9IntrCb was installed for all events (2-7).
dev9RegisterIntrCb(4, &Dev9TxEndIntrHandler); /* TXEND */
dev9RegisterIntrCb(5, &Dev9IntrCb); /* RXEND */
//Register the interrupt handlers for all SMAP events.
for(i=2; i<7; i++) dev9RegisterIntrCb(i, &Dev9IntrCb);

dev9RegisterPreDmaCb(1, &Dev9PreDmaCbHandler);
dev9RegisterPostDmaCb(1, &Dev9PostDmaCbHandler);
Expand Down
5 changes: 1 addition & 4 deletions iop/network/smap/src/xfer.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ int SMAPSendPacket(const void *data, unsigned int length){
int result, i, OldState;
USE_SMAP_TX_BD;
volatile u8 *smap_regbase;
volatile u8 *emac3_regbase;
volatile smap_bd_t *BD_ptr;
u16 BD_data_ptr;
unsigned int SizeRounded;
Expand Down Expand Up @@ -146,9 +145,7 @@ int SMAPSendPacket(const void *data, unsigned int length){
SmapDriverData.TxBufferSpaceAvailable-=SizeRounded;
CpuResumeIntr(OldState);

//This used to be done in the XMIT event handler, in the SONY original.
emac3_regbase=SmapDriverData.emac3_regbase;
SMAP_EMAC3_SET(SMAP_R_EMAC3_TxMODE0, SMAP_E3_TX_GNP_0);
SetEventFlag(SmapDriverData.Dev9IntrEventFlag, SMAP_EVENT_XMIT);

result=1;
}
Expand Down

0 comments on commit fda1552

Please sign in to comment.