Some refactoring of DEC21x4x driver.

git-svn-id: svn://kolibrios.org@3201 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-01-27 20:13:23 +00:00
parent a8ad5846a9
commit a52b2728a7

View File

@ -18,14 +18,21 @@
format MS COFF format MS COFF
API_VERSION = 0x01000100 API_VERSION = 0x01000100
DRIVER_VERSION = 5 DRIVER_VERSION = 5
MAX_DEVICES = 16 MAX_DEVICES = 16
DEBUG = 1 RX_DES_COUNT = 4 ; no of RX descriptors, must be power of 2
__DEBUG__ = 1 RX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK
__DEBUG_LEVEL__ = 1
TX_DES_COUNT = 4 ; no of TX descriptors, must be power of 2
TX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, used for memory allocation only
DEBUG = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
include 'proc32.inc' include 'proc32.inc'
include 'imports.inc' include 'imports.inc'
@ -61,127 +68,128 @@ end virtual
;------------------------------------------- ;-------------------------------------------
; configuration registers ; configuration registers
;------------------------------------------- ;-------------------------------------------
CFCS = 4 ; configuration and status register CFCS = 4 ; configuration and status register
CSR0 = 0x00 ; Bus mode CSR0 = 0x00 ; Bus mode
CSR1 = 0x08 ; Transmit Poll Command CSR1 = 0x08 ; Transmit Poll Command
CSR2 = 0x10 ; Receive Poll Command CSR2 = 0x10 ; Receive Poll Command
CSR3 = 0x18 ; Receive list base address CSR3 = 0x18 ; Receive list base address
CSR4 = 0x20 ; Transmit list base address CSR4 = 0x20 ; Transmit list base address
CSR5 = 0x28 ; Status CSR5 = 0x28 ; Status
CSR6 = 0x30 ; Operation mode CSR6 = 0x30 ; Operation mode
CSR7 = 0x38 ; Interrupt enable CSR7 = 0x38 ; Interrupt enable
CSR8 = 0x40 ; Missed frames and overflow counter CSR8 = 0x40 ; Missed frames and overflow counter
CSR9 = 0x48 ; Boot ROM, serial ROM, and MII management CSR9 = 0x48 ; Boot ROM, serial ROM, and MII management
CSR10 = 0x50 ; Boot ROM programming address CSR10 = 0x50 ; Boot ROM programming address
CSR11 = 0x58 ; General-purpose timer CSR11 = 0x58 ; General-purpose timer
CSR12 = 0x60 ; General-purpose port CSR12 = 0x60 ; General-purpose port
CSR13 = 0x68 CSR13 = 0x68
CSR14 = 0x70 CSR14 = 0x70
CSR15 = 0x78 ; Watchdog timer CSR15 = 0x78 ; Watchdog timer
;--------bits/commands of CSR0------------------- ;--------bits/commands of CSR0-------------------
CSR0_RESET = 1b CSR0_RESET = 1b
CSR0_WIE = 1 SHL 24 ; Write and Invalidate Enable CSR0_WIE = 1 shl 24 ; Write and Invalidate Enable
CSR0_RLE = 1 SHL 23 ; PCI Read Line Enable CSR0_RLE = 1 shl 23 ; PCI Read Line Enable
CSR0_RML = 1 SHL 21 ; PCI Read Multiple CSR0_RML = 1 shl 21 ; PCI Read Multiple
CSR0_CACHEALIGN_NONE = 00b SHL 14 CSR0_CACHEALIGN_NONE = 00b shl 14
CSR0_CACHEALIGN_32 = 01b SHL 14 CSR0_CACHEALIGN_32 = 01b shl 14
CSR0_CACHEALIGN_64 = 10b SHL 14 CSR0_CACHEALIGN_64 = 10b shl 14
CSR0_CACHEALIGN_128 = 11b SHL 14 CSR0_CACHEALIGN_128 = 11b shl 14
; using values from linux driver.. :P ; using values from linux driver..
CSR0_DEFAULT = CSR0_WIE+CSR0_RLE+CSR0_RML+CSR0_CACHEALIGN_NONE ;32 CSR0_DEFAULT = CSR0_WIE + CSR0_RLE + CSR0_RML + CSR0_CACHEALIGN_NONE
;------- CSR5 -STATUS- bits -------------------------------- ;------- CSR5 -STATUS- bits --------------------------------
CSR5_TI = 1 SHL 0 ; Transmit interupt - frame transmition completed CSR5_TI = 1 shl 0 ; Transmit interupt - frame transmition completed
CSR5_TPS = 1 SHL 1 ; Transmit process stopped CSR5_TPS = 1 shl 1 ; Transmit process stopped
CSR5_TU = 1 SHL 2 ; Transmit Buffer unavailable CSR5_TU = 1 shl 2 ; Transmit Buffer unavailable
CSR5_TJT = 1 SHL 3 ; Transmit Jabber Timeout (transmitter had been excessively active) CSR5_TJT = 1 shl 3 ; Transmit Jabber Timeout (transmitter had been excessively active)
CSR5_UNF = 1 SHL 5 ; Transmit underflow - FIFO underflow CSR5_UNF = 1 shl 5 ; Transmit underflow - FIFO underflow
CSR5_RI = 1 SHL 6 ; Receive Interrupt CSR5_RI = 1 shl 6 ; Receive Interrupt
CSR5_RU = 1 SHL 7 ; Receive Buffer unavailable CSR5_RU = 1 shl 7 ; Receive Buffer unavailable
CSR5_RPS = 1 SHL 8 ; Receive Process stopped CSR5_RPS = 1 shl 8 ; Receive Process stopped
CSR5_RWT = 1 SHL 9 ; Receive Watchdow Timeout CSR5_RWT = 1 shl 9 ; Receive Watchdow Timeout
CSR5_ETI = 1 SHL 10 ; Early transmit Interrupt CSR5_ETI = 1 shl 10 ; Early transmit Interrupt
CSR5_GTE = 1 SHL 11 ; General Purpose Timer Expired CSR5_GTE = 1 shl 11 ; General Purpose Timer Expired
CSR5_FBE = 1 SHL 13 ; Fatal bus error CSR5_FBE = 1 shl 13 ; Fatal bus error
CSR5_ERI = 1 SHL 14 ; Early receive Interrupt CSR5_ERI = 1 shl 14 ; Early receive Interrupt
CSR5_AIS = 1 SHL 15 ; Abnormal interrupt summary CSR5_AIS = 1 shl 15 ; Abnormal interrupt summary
CSR5_NIS = 1 SHL 16 ; normal interrupt summary CSR5_NIS = 1 shl 16 ; normal interrupt summary
CSR5_RS_SH = 1 SHL 17 ; Receive process state -shift CSR5_RS_SH = 17 ; Receive process state -shift
CSR5_RS_MASK = 111b ; -mask CSR5_RS_MASK = 111b ; -mask
CSR5_TS_SH = 1 SHL 20 ; Transmit process state -shift CSR5_TS_SH = 20 ; Transmit process state -shift
CSR5_TS_MASK = 111b ; -mask CSR5_TS_MASK = 111b ; -mask
CSR5_EB_SH = 1 SHL 23 ; Error bits -shift CSR5_EB_SH = 23 ; Error bits -shift
CSR5_EB_MASK = 111b ; Error bits -mask CSR5_EB_MASK = 111b ; Error bits -mask
;CSR5 TS values ;CSR5 TS values
CSR5_TS_STOPPED = 000b CSR5_TS_STOPPED = 000b
CSR5_TS_RUNNING_FETCHING_DESC = 001b CSR5_TS_RUNNING_FETCHING_DESC = 001b
CSR5_TS_RUNNING_WAITING_TX = 010b CSR5_TS_RUNNING_WAITING_TX = 010b
CSR5_TS_RUNNING_READING_BUFF = 011b CSR5_TS_RUNNING_READING_BUFF = 011b
CSR5_TS_RUNNING_SETUP_PCKT = 101b CSR5_TS_RUNNING_SETUP_PCKT = 101b
CSR5_TS_SUSPENDED = 110b CSR5_TS_SUSPENDED = 110b
CSR5_TS_RUNNING_CLOSING_DESC = 111b CSR5_TS_RUNNING_CLOSING_DESC = 111b
;------- CSR6 -OPERATION MODE- bits -------------------------------- ;------- CSR6 -OPERATION MODE- bits --------------------------------
CSR6_HP = 1 SHL 0 ; Hash/Perfect Receive Filtering mode CSR6_HP = 1 shl 0 ; Hash/Perfect Receive Filtering mode
CSR6_SR = 1 SHL 1 ; Start/Stop receive CSR6_SR = 1 shl 1 ; Start/Stop receive
CSR6_HO = 1 SHL 2 ; Hash only Filtering mode CSR6_HO = 1 shl 2 ; Hash only Filtering mode
CSR6_PB = 1 SHL 3 ; Pass bad frames CSR6_PB = 1 shl 3 ; Pass bad frames
CSR6_IF = 1 SHL 4 ; Inverse filtering CSR6_IF = 1 shl 4 ; Inverse filtering
CSR6_SB = 1 SHL 5 ; Start/Stop backoff counter CSR6_SB = 1 shl 5 ; Start/Stop backoff counter
CSR6_PR = 1 SHL 6 ; Promiscuos mode -default after reset CSR6_PR = 1 shl 6 ; Promiscuos mode -default after reset
CSR6_PM = 1 SHL 7 ; Pass all multicast CSR6_PM = 1 shl 7 ; Pass all multicast
CSR6_F = 1 SHL 9 ; Full Duplex mode CSR6_F = 1 shl 9 ; Full Duplex mode
CSR6_OM_SH = 1 SHL 10 ; Operating Mode -shift CSR6_OM_SH = 10 ; Operating Mode -shift
CSR6_OM_MASK = 11b ; -mask CSR6_OM_MASK = 11b ; -mask
CSR6_FC = 1 SHL 12 ; Force Collision Mode CSR6_FC = 1 shl 12 ; Force Collision Mode
CSR6_ST = 1 SHL 13 ; Start/Stop Transmission Command CSR6_ST = 1 shl 13 ; Start/Stop Transmission Command
CSR6_TR_SH = 1 SHL 14 ; Threshold Control -shift CSR6_TR_SH = 14 ; Threshold Control -shift
CSR6_TR_MASK = 11b ; -mask CSR6_TR_MASK = 11b ; -mask
CSR6_CA = 1 SHL 17 ; Capture Effect Enable CSR6_CA = 1 shl 17 ; Capture Effect Enable
CSR6_PS = 1 SHL 18 ; Port select SRL / MII/SYM CSR6_PS = 1 shl 18 ; Port select SRL / MII/SYM
CSR6_HBD = 1 SHL 19 ; Heartbeat Disable CSR6_HBD = 1 shl 19 ; Heartbeat Disable
CSR6_SF = 1 SHL 21 ; Store and Forward -transmit full packet only CSR6_SF = 1 shl 21 ; Store and Forward -transmit full packet only
CSR6_TTM = 1 SHL 22 ; Transmit Threshold Mode - CSR6_TTM = 1 shl 22 ; Transmit Threshold Mode -
CSR6_PCS = 1 SHL 23 ; PCS active and MII/SYM port operates in symbol mode CSR6_PCS = 1 shl 23 ; PCS active and MII/SYM port operates in symbol mode
CSR6_SCR = 1 SHL 24 ; Scrambler Mode CSR6_SCR = 1 shl 24 ; Scrambler Mode
CSR6_MBO = 1 SHL 25 ; Must Be One CSR6_MBO = 1 shl 25 ; Must Be One
CSR6_RA = 1 SHL 30 ; Receive All CSR6_RA = 1 shl 30 ; Receive All
CSR6_SC = 1 SHL 31 ; Special Capture Effect Enable CSR6_SC = 1 shl 31 ; Special Capture Effect Enable
;------- CSR7 -INTERRUPT ENABLE- bits -------------------------------- ;------- CSR7 -INTERRUPT ENABLE- bits --------------------------------
CSR7_TI = 1 SHL 0 ; transmit Interrupt Enable (set with CSR7<16> & CSR5<0> ) CSR7_TI = 1 shl 0 ; transmit Interrupt Enable (set with CSR7<16> & CSR5<0> )
CSR7_TS = 1 SHL 1 ; transmit Stopped Enable (set with CSR7<15> & CSR5<1> ) CSR7_TS = 1 shl 1 ; transmit Stopped Enable (set with CSR7<15> & CSR5<1> )
CSR7_TU = 1 SHL 2 ; transmit buffer underrun Enable (set with CSR7<16> & CSR5<2> ) CSR7_TU = 1 shl 2 ; transmit buffer underrun Enable (set with CSR7<16> & CSR5<2> )
CSR7_TJ = 1 SHL 3 ; transmit jabber timeout enable (set with CSR7<15> & CSR5<3> ) CSR7_TJ = 1 shl 3 ; transmit jabber timeout enable (set with CSR7<15> & CSR5<3> )
CSR7_UN = 1 SHL 5 ; underflow Interrupt enable (set with CSR7<15> & CSR5<5> ) CSR7_UN = 1 shl 5 ; underflow Interrupt enable (set with CSR7<15> & CSR5<5> )
CSR7_RI = 1 SHL 6 ; receive Interrupt enable (set with CSR7<16> & CSR5<5> ) CSR7_RI = 1 shl 6 ; receive Interrupt enable (set with CSR7<16> & CSR5<5> )
CSR7_RU = 1 SHL 7 ; receive buffer unavailable enable (set with CSR7<15> & CSR5<7> ) CSR7_RU = 1 shl 7 ; receive buffer unavailable enable (set with CSR7<15> & CSR5<7> )
CSR7_RS = 1 SHL 8 ; Receive stopped enable (set with CSR7<15> & CSR5<8> ) CSR7_RS = 1 shl 8 ; Receive stopped enable (set with CSR7<15> & CSR5<8> )
CSR7_RW = 1 SHL 9 ; receive watchdog timeout enable (set with CSR7<15> & CSR5<9> ) CSR7_RW = 1 shl 9 ; receive watchdog timeout enable (set with CSR7<15> & CSR5<9> )
CSR7_ETE = 1 SHL 10 ; Early transmit Interrupt enable (set with CSR7<15> & CSR5<10> ) CSR7_ETE = 1 shl 10 ; Early transmit Interrupt enable (set with CSR7<15> & CSR5<10> )
CSR7_GPT = 1 SHL 11 ; general purpose timer enable (set with CSR7<15> & CSR5<11> ) CSR7_GPT = 1 shl 11 ; general purpose timer enable (set with CSR7<15> & CSR5<11> )
CSR7_FBE = 1 SHL 13 ; Fatal bus error enable (set with CSR7<15> & CSR5<13> ) CSR7_FBE = 1 shl 13 ; Fatal bus error enable (set with CSR7<15> & CSR5<13> )
CSR7_ERE = 1 SHL 14 ; Early receive enable (set with CSR7<16> & CSR5<14> ) CSR7_ERE = 1 shl 14 ; Early receive enable (set with CSR7<16> & CSR5<14> )
CSR7_AI = 1 SHL 15 ; Abnormal Interrupt Summary Enable (enables CSR5<0,3,7,8,9,10,13>) CSR7_AI = 1 shl 15 ; Abnormal Interrupt Summary Enable (enables CSR5<0,3,7,8,9,10,13>)
CSR7_NI = 1 SHL 16 ; Normal Interrup Enable (enables CSR5<0,2,6,11,14>) CSR7_NI = 1 shl 16 ; Normal Interrup Enable (enables CSR5<0,2,6,11,14>)
CSR7_DEFAULT = CSR7_TI+CSR7_TS+CSR7_RI+CSR7_RS+CSR7_TU+CSR7_TJ+CSR7_UN+\
CSR7_RU+CSR7_RW+CSR7_FBE+CSR7_AI+CSR7_NI CSR7_DEFAULT = CSR7_TI + CSR7_TS + CSR7_RI + CSR7_RS + CSR7_TU + CSR7_TJ + CSR7_UN + \
CSR7_RU + CSR7_RW + CSR7_FBE + CSR7_AI + CSR7_NI
;----------- descriptor structure --------------------- ;----------- descriptor structure ---------------------
struc DES { struc DES {
.DES0 DD ? ; bit 31 is 'own' and rest is 'status' .status dd ? ; bit 31 is 'own' and rest is 'status'
.DES1 DD ? ; control bits + bytes-count buffer 1 + bytes-count buffer 2 .length dd ? ; control bits + bytes-count buffer 1 + bytes-count buffer 2
.DES2 DD ? ; pointer to buffer1 .buffer1 dd ? ; pointer to buffer1
.DES3 DD ? ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure .buffer2 dd ? ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure
.realaddr dd ? .virtaddr dd ?
.size = 64 .size = 64 ; 64, for alignment purposes
} }
virtual at 0 virtual at 0
@ -189,83 +197,78 @@ virtual at 0
end virtual end virtual
;common to Rx and Tx ;common to Rx and Tx
DES0_OWN = 1 SHL 31 ; if set, the NIC controls the descriptor, otherwise driver 'owns' the descriptors DES0_OWN = 1 shl 31 ; if set, the NIC controls the descriptor, otherwise driver 'owns' the descriptors
;receive ;receive
RDES0_ZER = 1 SHL 0 ; must be 0 if legal length :D RDES0_ZER = 1 shl 0 ; must be 0 if legal length :D
RDES0_CE = 1 SHL 1 ; CRC error, valid only on last desc (RDES0<8>=1) RDES0_CE = 1 shl 1 ; CRC error, valid only on last desc (RDES0<8>=1)
RDES0_DB = 1 SHL 2 ; dribbling bit - not multiple of 8 bits, valid only on last desc (RDES0<8>=1) RDES0_DB = 1 shl 2 ; dribbling bit - not multiple of 8 bits, valid only on last desc (RDES0<8>=1)
RDES0_RE = 1 SHL 3 ; Report on MII error.. i dont realy know what this means :P RDES0_RE = 1 shl 3 ; Report on MII error.. i dont realy know what this means :P
RDES0_RW = 1 SHL 4 ; received watchdog timer expiration - must set CSR5<9>, valid only on last desc (RDES0<8>=1) RDES0_RW = 1 shl 4 ; received watchdog timer expiration - must set CSR5<9>, valid only on last desc (RDES0<8>=1)
RDES0_FT = 1 SHL 5 ; frame type: 0->IEEE802.0 (len<1500) 1-> ETHERNET frame (len>1500), valid only on last desc (RDES0<8>=1) RDES0_FT = 1 shl 5 ; frame type: 0->IEEE802.0 (len<1500) 1-> ETHERNET frame (len>1500), valid only on last desc (RDES0<8>=1)
RDES0_CS = 1 SHL 6 ; Collision seen, valid only on last desc (RDES0<8>=1) RDES0_CS = 1 shl 6 ; Collision seen, valid only on last desc (RDES0<8>=1)
RDES0_TL = 1 SHL 7 ; Too long(>1518)-NOT AN ERROR, valid only on last desc (RDES0<8>=1) RDES0_TL = 1 shl 7 ; Too long(>1518)-NOT AN ERROR, valid only on last desc (RDES0<8>=1)
RDES0_LS = 1 SHL 8 ; Last descriptor of current frame RDES0_LS = 1 shl 8 ; Last descriptor of current frame
RDES0_FS = 1 SHL 9 ; First descriptor of current frame RDES0_FS = 1 shl 9 ; First descriptor of current frame
RDES0_MF = 1 SHL 10 ; Multicast frame, valid only on last desc (RDES0<8>=1) RDES0_MF = 1 shl 10 ; Multicast frame, valid only on last desc (RDES0<8>=1)
RDES0_RF = 1 SHL 11 ; Runt frame, valid only on last desc (RDES0<8>=1) and id overflow RDES0_RF = 1 shl 11 ; Runt frame, valid only on last desc (RDES0<8>=1) and id overflow
RDES0_DT_SERIAL = 00b SHL 12 ; Data type-Serial recv frame, valid only on last desc (RDES0<8>=1) RDES0_DT_SERIAL = 00b shl 12 ; Data type-Serial recv frame, valid only on last desc (RDES0<8>=1)
RDES0_DT_INTERNAL = 01b SHL 12 ; Data type-Internal loopback recv frame, valid only on last desc (RDES0<8>=1) RDES0_DT_INTERNAL = 01b shl 12 ; Data type-Internal loopback recv frame, valid only on last desc (RDES0<8>=1)
RDES0_DT_EXTERNAL = 11b SHL 12 ; Data type-External loopback recv frame, valid only on last desc (RDES0<8>=1) RDES0_DT_EXTERNAL = 11b shl 12 ; Data type-External loopback recv frame, valid only on last desc (RDES0<8>=1)
RDES0_DE = 1 SHL 14 ; Descriptor error - cant own a new desc and frame doesnt fit, valid only on last desc (RDES0<8>=1) RDES0_DE = 1 shl 14 ; Descriptor error - cant own a new desc and frame doesnt fit, valid only on last desc (RDES0<8>=1)
RDES0_ES = 1 SHL 15 ; Error Summmary - bits 1+6+11+14, valid only on last desc (RDES0<8>=1) RDES0_ES = 1 shl 15 ; Error Summmary - bits 1+6+11+14, valid only on last desc (RDES0<8>=1)
RDES0_FL_SH = 16 ; Field length shift, valid only on last desc (RDES0<8>=1) RDES0_FL_SH = 16 ; Field length shift, valid only on last desc (RDES0<8>=1)
RDES0_FL_MASK = 11111111111111b ; Field length mask (+CRC), valid only on last desc (RDES0<8>=1) RDES0_FL_MASK = 11111111111111b ; Field length mask (+CRC), valid only on last desc (RDES0<8>=1)
RDES0_FF = 1 SHL 30 ; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1) RDES0_FF = 1 shl 30 ; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1)
RDES1_RBS1_MASK = 11111111111b ; firsd buffer size MASK RDES1_RBS1_MASK = 11111111111b ; first buffer size MASK
RDES1_RBS2_SH = 1 SHL 11 ; second buffer size SHIFT RDES1_RBS2_SH = 11 ; second buffer size SHIFT
RDES1_RBS2_MASK = 11111111111b ; second buffer size MASK RDES1_RBS2_MASK = 11111111111b ; second buffer size MASK
RDES1_RCH = 1 SHL 24 ; Second address chained - second address (buffer) is next desc address RDES1_RCH = 1 shl 24 ; Second address chained - second address (buffer) is next desc address
RDES1_RER = 1 SHL 25 ; Receive End of Ring - final descriptor, NIC must return to first desc RDES1_RER = 1 shl 25 ; Receive End of Ring - final descriptor, NIC must return to first desc
;transmition ;transmition
TDES0_DE = 1 SHL 0 ; Deffered TDES0_DE = 1 shl 0 ; Deffered
TDES0_UF = 1 SHL 1 ; Underflow error TDES0_UF = 1 shl 1 ; Underflow error
TDES0_LF = 1 SHL 2 ; Link fail report (only if CSR6<23>=1) TDES0_LF = 1 shl 2 ; Link fail report (only if CSR6<23>=1)
TDES0_CC_SH = 3 ; Collision Count shift - no of collision before transmition TDES0_CC_SH = 3 ; Collision Count shift - no of collision before transmition
TDES0_CC_MASK = 1111b ; Collision Count mask TDES0_CC_MASK = 1111b ; Collision Count mask
TDES0_HF = 1 SHL 7 ; Heartbeat fail TDES0_HF = 1 shl 7 ; Heartbeat fail
TDES0_EC = 1 SHL 8 ; Excessive Collisions - >16 collisions TDES0_EC = 1 shl 8 ; Excessive Collisions - >16 collisions
TDES0_LC = 1 SHL 9 ; Late collision TDES0_LC = 1 shl 9 ; Late collision
TDES0_NC = 1 SHL 10 ; No carrier TDES0_NC = 1 shl 10 ; No carrier
TDES0_LO = 1 SHL 11 ; Loss of carrier TDES0_LO = 1 shl 11 ; Loss of carrier
TDES0_TO = 1 SHL 14 ; Transmit Jabber Timeout TDES0_TO = 1 shl 14 ; Transmit Jabber Timeout
TDES0_ES = 1 SHL 15 ; Error summary TDES0<1+8+9+10+11+14>=1 TDES0_ES = 1 shl 15 ; Error summary TDES0<1+8+9+10+11+14>=1
TDES1_TBS1_MASK = 11111111111b ; Buffer 1 size mask TDES1_TBS1_MASK = 11111111111b ; Buffer 1 size mask
TDES1_TBS2_SH = 11 ; Buffer 2 size shift TDES1_TBS2_SH = 11 ; Buffer 2 size shift
TDES1_TBS2_MASK = 11111111111b ; Buffer 2 size mask TDES1_TBS2_MASK = 11111111111b ; Buffer 2 size mask
TDES1_FT0 = 1 SHL 22 ; Filtering type 0 TDES1_FT0 = 1 shl 22 ; Filtering type 0
TDES1_DPD = 1 SHL 23 ; Disabled padding for packets <64bytes, no padding TDES1_DPD = 1 shl 23 ; Disabled padding for packets <64bytes, no padding
TDES1_TCH = 1 SHL 24 ; Second address chained - second buffer pointer is to next desc TDES1_TCH = 1 shl 24 ; Second address chained - second buffer pointer is to next desc
TDES1_TER = 1 SHL 25 ; Transmit end of ring - final descriptor TDES1_TER = 1 shl 25 ; Transmit end of ring - final descriptor
TDES1_AC = 1 SHL 26 ; Add CRC disable -pretty obvious TDES1_AC = 1 shl 26 ; Add CRC disable -pretty obvious
TDES1_SET = 1 SHL 27 ; Setup packet TDES1_SET = 1 shl 27 ; Setup packet
TDES1_FT1 = 1 SHL 28 ; Filtering type 1 TDES1_FT1 = 1 shl 28 ; Filtering type 1
TDES1_FS = 1 SHL 29 ; First segment - buffer is first segment of frame TDES1_FS = 1 shl 29 ; First segment - buffer is first segment of frame
TDES1_LS = 1 SHL 30 ; Last segment TDES1_LS = 1 shl 30 ; Last segment
TDES1_IC = 1 SHL 31 ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1 TDES1_IC = 1 shl 31 ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1
MAX_ETH_FRAME_SIZE = 1514 MAX_ETH_FRAME_SIZE = 1514
RX_DES_COUNT = 4 ; no of RX descriptors, must be power of 2 RX_MEM_TOTAL_SIZE = RX_DES_COUNT*(DES.size+RX_BUFF_SIZE)
RX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK TX_MEM_TOTAL_SIZE = TX_DES_COUNT*(DES.size+TX_BUFF_SIZE)
TX_DES_COUNT = 4 ; no of TX descriptors, must be power of 2
TX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, used for memory allocation only
RX_MEM_TOTAL_SIZE = RX_DES_COUNT*(DES.size+RX_BUFF_SIZE)
TX_MEM_TOTAL_SIZE = TX_DES_COUNT*(DES.size+TX_BUFF_SIZE)
;============================================================================= ;=============================================================================
; serial ROM operations ; serial ROM operations
;============================================================================= ;=============================================================================
CSR9_SR = 1 SHL 11 ; SROM Select CSR9_SR = 1 shl 11 ; SROM Select
CSR9_RD = 1 SHL 14 ; ROM Read Operation CSR9_RD = 1 shl 14 ; ROM Read Operation
CSR9_SROM_DO = 1 SHL 3 ; Data Out for SROM CSR9_SROM_DO = 1 shl 3 ; Data Out for SROM
CSR9_SROM_DI = 1 SHL 2 ; Data In to SROM CSR9_SROM_DI = 1 shl 2 ; Data In to SROM
CSR9_SROM_CK = 1 SHL 1 ; clock for SROM CSR9_SROM_CK = 1 shl 1 ; clock for SROM
CSR9_SROM_CS = 1 SHL 0 ; chip select.. always needed CSR9_SROM_CS = 1 shl 0 ; chip select.. always needed
; assume dx is CSR9 ; assume dx is CSR9
macro SROM_Delay { macro SROM_Delay {
@ -298,8 +301,8 @@ macro Bit_Set a_bit {
macro Bit_Clear a_bit { macro Bit_Clear a_bit {
in eax, dx in eax, dx
and eax, NOT (a_bit) and eax, not (a_bit)
out dx , eax out dx, eax
} }
@ -411,9 +414,9 @@ proc service_proc stdcall, ioctl:dword
; save the pci bus and device numbers ; save the pci bus and device numbers
mov eax, [IOCTL.input] mov eax, [IOCTL.input]
mov cl , [eax+1] mov cl, [eax+1]
mov [device.pci_bus], cl mov [device.pci_bus], cl
mov cl , [eax+2] mov cl, [eax+2]
mov [device.pci_dev], cl mov [device.pci_dev], cl
; Now, it's time to find the base io addres of the PCI device ; Now, it's time to find the base io addres of the PCI device
@ -527,13 +530,11 @@ probe:
movzx eax, [device.pci_bus] movzx eax, [device.pci_bus]
movzx ecx, [device.pci_dev] movzx ecx, [device.pci_dev]
stdcall PciRead32, eax ,ecx ,0 ; get device/vendor id stdcall PciRead32, eax ,ecx ,0 ; get device/vendor id
DEBUGF 1,"Vendor id: 0x%x\n", ax DEBUGF 1,"Vendor id: 0x%x\n", ax
cmp ax, 0x1011 cmp ax, 0x1011
jne .notfound jne .notfound
shr eax, 16 shr eax, 16
DEBUGF 1,"Vendor ok!, device id: 0x%x\n", ax ; TODO: use another method to detect chip! DEBUGF 1,"Vendor ok!, device id: 0x%x\n", ax ; TODO: use another method to detect chip!
cmp ax, 0x0009 cmp ax, 0x0009
@ -579,7 +580,7 @@ reset:
status status
set_io CSR0 set_io CSR0
mov eax, CSR0_RESET mov eax, CSR0_RESET
out dx , eax out dx, eax
; wait at least 50 PCI cycles ; wait at least 50 PCI cycles
mov esi, 1000 mov esi, 1000
@ -592,7 +593,7 @@ reset:
status status
set_io CSR0 set_io CSR0
mov eax, CSR0_DEFAULT mov eax, CSR0_DEFAULT
out dx , eax out dx, eax
; wait at least 50 PCI cycles ; wait at least 50 PCI cycles
@ -620,87 +621,7 @@ reset:
set_io 0 set_io 0
status status
;------------------------------------------ call init_ring
; Setup RX descriptors (use chained method)
mov eax, [device.rx_p_des]
call GetPgAddr
mov edx, eax
lea esi, [eax + RX_DES_COUNT*(DES.size)] ; jump over RX descriptors
mov eax, [device.rx_p_des]
add eax, RX_DES_COUNT*(DES.size) ; jump over RX descriptors
mov edi, [device.rx_p_des]
mov ecx, RX_DES_COUNT
push edx ;;
.loop_rx_des:
add edx, DES.size
mov [edi + DES.DES0], DES0_OWN ; hardware owns buffer
mov [edi + DES.DES1], 1984 + RDES1_RCH ; only size of first buffer, chained buffers
mov [edi + DES.DES2], esi ; hw buffer address
mov [edi + DES.DES3], edx ; pointer to next descriptor
mov [edi + DES.realaddr], eax ; virtual buffer address
DEBUGF 1,"RX desc %u, buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", ecx, esi, edx, eax, edi
add esi, RX_BUFF_SIZE
add eax, RX_BUFF_SIZE
add edi, DES.size
dec ecx
jnz .loop_rx_des
; set last descriptor as LAST
sub edi, DES.size
or [edi + DES.DES1], RDES1_RER ; EndOfRing
pop edx
mov [edi + DES.DES3], edx
;---------------------
; Setup TX descriptors
mov eax, [device.tx_p_des]
call GetPgAddr
mov edx, eax
lea esi, [eax + TX_DES_COUNT*(DES.size)] ; jump over TX descriptors
mov eax, [device.tx_p_des]
add eax, TX_DES_COUNT*(DES.size) ; jump over TX descriptors
mov edi, [device.tx_p_des]
mov ecx, TX_DES_COUNT
push edx
.loop_tx_des:
add edx, DES.size
mov [edi + DES.DES0], 0 ; owned by driver
mov [edi + DES.DES1], TDES1_TCH ; chained method
mov [edi + DES.DES2], esi ; pointer to buffer
mov [edi + DES.DES3], edx ; pointer to next descr
mov [edi + DES.realaddr], eax
DEBUGF 1,"TX desc %u, buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", ecx, esi, edx, eax, edi
add esi, TX_BUFF_SIZE
add eax, TX_BUFF_SIZE
add edi, DES.size
dec ecx
jnz .loop_tx_des
; set last descriptor as LAST
sub edi, DES.size
or [edi + DES.DES1], TDES1_TER ; EndOfRing
pop edx
mov [edi + DES.DES3], edx
;------------------
; Reset descriptors
mov [device.tx_wr_des], 0
mov [device.tx_rd_des], 0
mov [device.rx_crt_des], 0
mov [device.tx_free_des], TX_DES_COUNT
;-------------------------------------------- ;--------------------------------------------
; setup CSR3 & CSR4 (pointers to descriptors) ; setup CSR3 & CSR4 (pointers to descriptors)
@ -709,15 +630,15 @@ reset:
status status
set_io CSR3 set_io CSR3
mov eax, [device.rx_p_des] mov eax, [device.rx_p_des]
call GetPgAddr GetRealAddr
DEBUGF 1,"RX descriptor base address: %x\n", eax DEBUGF 1,"RX descriptor base address: %x\n", eax
out dx , eax out dx, eax
set_io CSR4 set_io CSR4
mov eax, [device.tx_p_des] mov eax, [device.tx_p_des]
call GetPgAddr GetRealAddr
DEBUGF 1,"TX descriptor base address: %x\n", eax DEBUGF 1,"TX descriptor base address: %x\n", eax
out dx , eax out dx, eax
;------------------------------------------------------- ;-------------------------------------------------------
; setup interrupt mask register -expect IRQs from now on ; setup interrupt mask register -expect IRQs from now on
@ -726,7 +647,7 @@ reset:
DEBUGF 1,"Enabling interrupts\n" DEBUGF 1,"Enabling interrupts\n"
set_io CSR7 set_io CSR7
mov eax, CSR7_DEFAULT mov eax, CSR7_DEFAULT
out dx , eax out dx, eax
status status
;---------- ;----------
@ -744,7 +665,6 @@ reset:
call start_link call start_link
; wait a bit ; wait a bit
mov esi, 3000 mov esi, 3000
call Sleep call Sleep
@ -769,6 +689,85 @@ reset:
ret ret
align 4
init_ring:
;------------------------------------------
; Setup RX descriptors (use chained method)
mov eax, [device.rx_p_des]
GetRealAddr
mov edx, eax
push eax
lea esi, [eax + RX_DES_COUNT*(DES.size)] ; jump over RX descriptors
mov eax, [device.rx_p_des]
add eax, RX_DES_COUNT*(DES.size) ; jump over RX descriptors
mov edi, [device.rx_p_des]
mov ecx, RX_DES_COUNT
.loop_rx_des:
add edx, DES.size
mov [edi + DES.status], DES0_OWN ; hardware owns buffer
mov [edi + DES.length], 1984 + RDES1_RCH ; only size of first buffer, chained buffers
mov [edi + DES.buffer1], esi ; hw buffer address
mov [edi + DES.buffer2], edx ; pointer to next descriptor
mov [edi + DES.virtaddr], eax ; virtual buffer address
DEBUGF 1,"RX desc: buff addr: %x, next desc: %x, real buff addr: %x, real descr addr: %x \n", esi, edx, eax, edi
add esi, RX_BUFF_SIZE
add eax, RX_BUFF_SIZE
add edi, DES.size
dec ecx
jnz .loop_rx_des
; set last descriptor as LAST
sub edi, DES.size
or [edi + DES.length], RDES1_RER ; EndOfRing
pop [edi + DES.buffer2] ; point it to the first descriptor
;---------------------
; Setup TX descriptors
mov eax, [device.tx_p_des]
GetRealAddr
mov edx, eax
push eax
lea esi, [eax + TX_DES_COUNT*(DES.size)] ; jump over TX descriptors
mov eax, [device.tx_p_des]
add eax, TX_DES_COUNT*(DES.size) ; jump over TX descriptors
mov edi, [device.tx_p_des]
mov ecx, TX_DES_COUNT
.loop_tx_des:
add edx, DES.size
mov [edi + DES.status], 0 ; owned by driver
mov [edi + DES.length], TDES1_TCH ; chained method
mov [edi + DES.buffer1], esi ; pointer to buffer
mov [edi + DES.buffer2], edx ; pointer to next descr
mov [edi + DES.virtaddr], eax
DEBUGF 1,"TX desc: buff addr: %x, next desc: %x, virt buff addr: %x, virt descr addr: %x \n", esi, edx, eax, edi
add esi, TX_BUFF_SIZE
add eax, TX_BUFF_SIZE
add edi, DES.size
dec ecx
jnz .loop_tx_des
; set last descriptor as LAST
sub edi, DES.size
or [edi + DES.length], TDES1_TER ; EndOfRing
pop [edi + DES.buffer2] ; point it to the first descriptor
;------------------
; Reset descriptors
mov [device.tx_wr_des], 0
mov [device.tx_rd_des], 0
mov [device.rx_crt_des], 0
mov [device.tx_free_des], TX_DES_COUNT
ret
align 4 align 4
start_link: start_link:
@ -813,7 +812,7 @@ Send_Setup_Packet:
; and go to next descriptor for real setup packet... ;; TODO: check if 2 descriptors are available ; and go to next descriptor for real setup packet... ;; TODO: check if 2 descriptors are available
; cmp [device.tx_packets], 0 ; cmp [device.tx_packets], 0
; je .not_first ; je .first
; ;
; and [edi+DES.des1], 0 ; and [edi+DES.des1], 0
; mov [edi+DES.des0], DES0_OWN ; mov [edi+DES.des0], DES0_OWN
@ -835,21 +834,20 @@ Send_Setup_Packet:
; mul edx ; mul edx
; add edi, eax ; add edi, eax
.not_first: .first:
push edi push edi
; copy setup packet to current descriptor ; copy setup packet to current descriptor
mov edi, [edi+DES.realaddr] mov edi, [edi + DES.virtaddr]
; copy once the address ; copy the address once
lea esi, [device.mac] lea esi, [device.mac]
DEBUGF 1,"copying packet to %x from %x\n", edi, esi DEBUGF 1,"copying packet to %x from %x\n", edi, esi
mov ecx, 3 ; mac is 6 bytes thus 3 words mov ecx, 3 ; mac is 6 bytes thus 3 words
.loop: .loop:
DEBUGF 1,"%x ", [esi]:4 DEBUGF 1,"%x ", [esi]:4
movsw movsw
dec esi inc edi
dec esi inc edi
movsw
dec ecx dec ecx
jnz .loop jnz .loop
@ -864,13 +862,13 @@ Send_Setup_Packet:
; setup descriptor ; setup descriptor
DEBUGF 1,"setting up descriptor\n" DEBUGF 1,"setting up descriptor\n"
mov [edi + DES.DES1], TDES1_IC + TDES1_SET + TDES1_TCH + 192 ; size must be EXACTLY 192 bytes mov [edi + DES.length], TDES1_IC + TDES1_SET + TDES1_TCH + 192 ; size must be EXACTLY 192 bytes
mov [edi + DES.DES0], DES0_OWN mov [edi + DES.status], DES0_OWN
DEBUGF 1,"TDES0: %x\n", [edi + DES.DES0]:8 DEBUGF 1,"status: %x\n", [edi + DES.status]:8
DEBUGF 1,"TDES1: %x\n", [edi + DES.DES1]:8 DEBUGF 1,"length: %x\n", [edi + DES.length]:8
DEBUGF 1,"TDES2: %x\n", [edi + DES.DES2]:8 DEBUGF 1,"buffer1: %x\n", [edi + DES.buffer1]:8
DEBUGF 1,"TDES3: %x\n", [edi + DES.DES3]:8 DEBUGF 1,"buffer2: %x\n", [edi + DES.buffer2]:8
; go to next descriptor ; go to next descriptor
inc [device.tx_wr_des] inc [device.tx_wr_des]
@ -895,10 +893,10 @@ Send_Setup_Packet:
.already_started: .already_started:
; if already started, issue a Transmit Poll command ; if already started, issue a Transmit Poll command
set_io CSR1 set_io CSR1
mov eax, 0 xor eax, eax
DEBUGF 1,"Issuing transmit poll command\n" DEBUGF 1,"Issuing transmit poll command\n"
.do_it: .do_it:
out dx , eax out dx, eax
status status
DEBUGF 1,"Sending setup packet, completed!\n" DEBUGF 1,"Sending setup packet, completed!\n"
@ -940,21 +938,21 @@ transmit:
mov edx, DES.size mov edx, DES.size
mul edx mul edx
add eax, [device.tx_p_des] add eax, [device.tx_p_des]
mov edi, [eax+DES.realaddr] ; pointer to buffer mov edi, [eax + DES.virtaddr] ; pointer to buffer
mov esi, [esp+4] mov esi, [esp+4]
mov ecx, [esp+8] mov ecx, [esp+8]
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb rep movsb
; set packet size ; set packet size
mov ecx, [eax+DES.DES1] mov ecx, [eax+DES.length]
and ecx, TDES1_TER ; preserve 'End of Ring' bit and ecx, TDES1_TER ; preserve 'End of Ring' bit
or ecx, [esp+8] ; set size or ecx, [esp+8] ; set size
or ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH ; first descr, last descr, interrupt on complete, chained modus or ecx, TDES1_FS or TDES1_LS or TDES1_IC or TDES1_TCH ; first descr, last descr, interrupt on complete, chained modus
mov [eax+DES.DES1], ecx mov [eax+DES.length], ecx
; set descriptor info ; set descriptor info
mov [eax+DES.DES0], DES0_OWN ; say it is now owned by the 21x4x mov [eax+DES.status], DES0_OWN ; say it is now owned by the 21x4x
; start tx ; start tx
set_io 0 set_io 0
@ -1043,7 +1041,7 @@ int_handler:
;---------------------------------- ;----------------------------------
; TX ok? ; TX ok?
test eax, CSR5_TI test ax, CSR5_TI
jz .not_tx jz .not_tx
push ax esi ecx push ax esi ecx
@ -1063,7 +1061,7 @@ int_handler:
cmp [device.tx_free_des], TX_DES_COUNT cmp [device.tx_free_des], TX_DES_COUNT
jz .end_tx jz .end_tx
mov eax, [edi+DES.DES0] mov eax, [edi+DES.status]
; we stop at first desc that is owned be NIC ; we stop at first desc that is owned be NIC
test eax, DES0_OWN test eax, DES0_OWN
@ -1101,22 +1099,25 @@ int_handler:
;---------------------------------- ;----------------------------------
; RX irq ; RX irq
.not_tx: .not_tx:
test eax, CSR5_RI test ax, CSR5_RI
jz .not_rx jz .not_rx
push ax esi ecx push ax esi ecx
DEBUGF 1,"RX ok!\n" DEBUGF 1,"RX ok!\n"
;go to current descriptor
mov edi, [device.rx_p_des]
push ebx
.rx_loop:
pop ebx
; get current descriptor
mov edi, [device.rx_p_des]
mov eax, [device.rx_crt_des] mov eax, [device.rx_crt_des]
mov edx, DES.size mov edx, DES.size
mul edx mul edx
add edi, eax add edi, eax
.loop_rx_start_of_packet: ; now check status
mov eax, [edi+DES.DES0] mov eax, [edi + DES.status]
test eax, DES0_OWN test eax, DES0_OWN
jnz .end_rx ; current desc is busy, nothing to do jnz .end_rx ; current desc is busy, nothing to do
@ -1127,41 +1128,30 @@ int_handler:
test eax, RDES0_LS ; if not last desc of packet, error for now test eax, RDES0_LS ; if not last desc of packet, error for now
jz .end_rx jz .end_rx
; .IF ZERO?
; ODS2 <"Net_Interrupt: packet > 1 descriptor, not supported yet :P">
; jmp @@end_rx
; .ENDIF
test eax, RDES0_ES test eax, RDES0_ES
jnz .end_rx jnz .end_rx
; .IF !ZERO? mov esi, [edi + DES.virtaddr]
; ODS2 <"Net_Interrupt: RX error"> mov ecx, [edi + DES.status]
; jmp @@end_rx
; .ENDIF
mov esi, [edi+DES.realaddr]
mov ecx, [edi+DES.DES0]
shr ecx, RDES0_FL_SH shr ecx, RDES0_FL_SH
and ecx, RDES0_FL_MASK and ecx, RDES0_FL_MASK
sub ecx, 4 ; crc sub ecx, 4 ; crc, we dont need it
DEBUGF 1,"Received packet!, size=%u, addr:%x\n", ecx, esi DEBUGF 1,"Received packet!, size=%u, addr:%x\n", ecx, esi
push esi edi ecx push esi edi ecx
stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into
pop ecx edi esi pop ecx edi esi
test eax, eax test eax, eax
jz .fail jz .fail
push edi push ebx
push dword .continue_rx push dword .rx_loop
push ecx eax push ecx eax
mov edi, eax mov edi, eax
; update statistics ; update statistics
inc [device.packets_rx] inc [device.packets_rx]
add dword [device.bytes_rx], ecx add dword [device.bytes_rx], ecx
adc dword [device.bytes_rx + 4], 0 adc dword [device.bytes_rx + 4], 0
@ -1176,26 +1166,17 @@ int_handler:
.nw: .nw:
rep movsd rep movsd
jmp Eth_input mov [edi + DES.status], DES0_OWN ; free descriptor
.continue_rx:
pop edi
; free descriptor
mov [edi+DES.DES0], DES0_OWN
; next descriptor inc [device.rx_crt_des] ; next descriptor
add edi, DES.size
inc [device.rx_crt_des]
and [device.rx_crt_des], RX_DES_COUNT-1 and [device.rx_crt_des], RX_DES_COUNT-1
jmp .loop_rx_start_of_packet jmp Eth_input
.end_rx: .end_rx:
.fail: .fail:
pop ecx esi ax pop ecx esi ax
.not_rx: .not_rx:
jmp .continue jmp .continue