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
API_VERSION = 0x01000100
DRIVER_VERSION = 5
API_VERSION = 0x01000100
DRIVER_VERSION = 5
MAX_DEVICES = 16
MAX_DEVICES = 16
DEBUG = 1
__DEBUG__ = 1
__DEBUG_LEVEL__ = 1
RX_DES_COUNT = 4 ; no of RX descriptors, must be power of 2
RX_BUFF_SIZE = 2048 ; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK
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 'imports.inc'
@ -61,127 +68,128 @@ end virtual
;-------------------------------------------
; configuration registers
;-------------------------------------------
CFCS = 4 ; configuration and status register
CFCS = 4 ; configuration and status register
CSR0 = 0x00 ; Bus mode
CSR1 = 0x08 ; Transmit Poll Command
CSR2 = 0x10 ; Receive Poll Command
CSR3 = 0x18 ; Receive list base address
CSR4 = 0x20 ; Transmit list base address
CSR5 = 0x28 ; Status
CSR6 = 0x30 ; Operation mode
CSR7 = 0x38 ; Interrupt enable
CSR8 = 0x40 ; Missed frames and overflow counter
CSR9 = 0x48 ; Boot ROM, serial ROM, and MII management
CSR10 = 0x50 ; Boot ROM programming address
CSR11 = 0x58 ; General-purpose timer
CSR12 = 0x60 ; General-purpose port
CSR13 = 0x68
CSR14 = 0x70
CSR15 = 0x78 ; Watchdog timer
CSR0 = 0x00 ; Bus mode
CSR1 = 0x08 ; Transmit Poll Command
CSR2 = 0x10 ; Receive Poll Command
CSR3 = 0x18 ; Receive list base address
CSR4 = 0x20 ; Transmit list base address
CSR5 = 0x28 ; Status
CSR6 = 0x30 ; Operation mode
CSR7 = 0x38 ; Interrupt enable
CSR8 = 0x40 ; Missed frames and overflow counter
CSR9 = 0x48 ; Boot ROM, serial ROM, and MII management
CSR10 = 0x50 ; Boot ROM programming address
CSR11 = 0x58 ; General-purpose timer
CSR12 = 0x60 ; General-purpose port
CSR13 = 0x68
CSR14 = 0x70
CSR15 = 0x78 ; Watchdog timer
;--------bits/commands of CSR0-------------------
CSR0_RESET = 1b
CSR0_RESET = 1b
CSR0_WIE = 1 SHL 24 ; Write and Invalidate Enable
CSR0_RLE = 1 SHL 23 ; PCI Read Line Enable
CSR0_RML = 1 SHL 21 ; PCI Read Multiple
CSR0_WIE = 1 shl 24 ; Write and Invalidate Enable
CSR0_RLE = 1 shl 23 ; PCI Read Line Enable
CSR0_RML = 1 shl 21 ; PCI Read Multiple
CSR0_CACHEALIGN_NONE = 00b SHL 14
CSR0_CACHEALIGN_32 = 01b SHL 14
CSR0_CACHEALIGN_64 = 10b SHL 14
CSR0_CACHEALIGN_128 = 11b SHL 14
CSR0_CACHEALIGN_NONE = 00b shl 14
CSR0_CACHEALIGN_32 = 01b shl 14
CSR0_CACHEALIGN_64 = 10b shl 14
CSR0_CACHEALIGN_128 = 11b shl 14
; using values from linux driver.. :P
CSR0_DEFAULT = CSR0_WIE+CSR0_RLE+CSR0_RML+CSR0_CACHEALIGN_NONE ;32
; using values from linux driver..
CSR0_DEFAULT = CSR0_WIE + CSR0_RLE + CSR0_RML + CSR0_CACHEALIGN_NONE
;------- CSR5 -STATUS- bits --------------------------------
CSR5_TI = 1 SHL 0 ; Transmit interupt - frame transmition completed
CSR5_TPS = 1 SHL 1 ; Transmit process stopped
CSR5_TU = 1 SHL 2 ; Transmit Buffer unavailable
CSR5_TJT = 1 SHL 3 ; Transmit Jabber Timeout (transmitter had been excessively active)
CSR5_UNF = 1 SHL 5 ; Transmit underflow - FIFO underflow
CSR5_RI = 1 SHL 6 ; Receive Interrupt
CSR5_RU = 1 SHL 7 ; Receive Buffer unavailable
CSR5_RPS = 1 SHL 8 ; Receive Process stopped
CSR5_RWT = 1 SHL 9 ; Receive Watchdow Timeout
CSR5_ETI = 1 SHL 10 ; Early transmit Interrupt
CSR5_GTE = 1 SHL 11 ; General Purpose Timer Expired
CSR5_FBE = 1 SHL 13 ; Fatal bus error
CSR5_ERI = 1 SHL 14 ; Early receive Interrupt
CSR5_AIS = 1 SHL 15 ; Abnormal interrupt summary
CSR5_NIS = 1 SHL 16 ; normal interrupt summary
CSR5_RS_SH = 1 SHL 17 ; Receive process state -shift
CSR5_RS_MASK = 111b ; -mask
CSR5_TS_SH = 1 SHL 20 ; Transmit process state -shift
CSR5_TS_MASK = 111b ; -mask
CSR5_EB_SH = 1 SHL 23 ; Error bits -shift
CSR5_EB_MASK = 111b ; Error bits -mask
CSR5_TI = 1 shl 0 ; Transmit interupt - frame transmition completed
CSR5_TPS = 1 shl 1 ; Transmit process stopped
CSR5_TU = 1 shl 2 ; Transmit Buffer unavailable
CSR5_TJT = 1 shl 3 ; Transmit Jabber Timeout (transmitter had been excessively active)
CSR5_UNF = 1 shl 5 ; Transmit underflow - FIFO underflow
CSR5_RI = 1 shl 6 ; Receive Interrupt
CSR5_RU = 1 shl 7 ; Receive Buffer unavailable
CSR5_RPS = 1 shl 8 ; Receive Process stopped
CSR5_RWT = 1 shl 9 ; Receive Watchdow Timeout
CSR5_ETI = 1 shl 10 ; Early transmit Interrupt
CSR5_GTE = 1 shl 11 ; General Purpose Timer Expired
CSR5_FBE = 1 shl 13 ; Fatal bus error
CSR5_ERI = 1 shl 14 ; Early receive Interrupt
CSR5_AIS = 1 shl 15 ; Abnormal interrupt summary
CSR5_NIS = 1 shl 16 ; normal interrupt summary
CSR5_RS_SH = 17 ; Receive process state -shift
CSR5_RS_MASK = 111b ; -mask
CSR5_TS_SH = 20 ; Transmit process state -shift
CSR5_TS_MASK = 111b ; -mask
CSR5_EB_SH = 23 ; Error bits -shift
CSR5_EB_MASK = 111b ; Error bits -mask
;CSR5 TS values
CSR5_TS_STOPPED = 000b
CSR5_TS_RUNNING_FETCHING_DESC = 001b
CSR5_TS_RUNNING_WAITING_TX = 010b
CSR5_TS_RUNNING_READING_BUFF = 011b
CSR5_TS_RUNNING_SETUP_PCKT = 101b
CSR5_TS_SUSPENDED = 110b
CSR5_TS_RUNNING_CLOSING_DESC = 111b
CSR5_TS_STOPPED = 000b
CSR5_TS_RUNNING_FETCHING_DESC = 001b
CSR5_TS_RUNNING_WAITING_TX = 010b
CSR5_TS_RUNNING_READING_BUFF = 011b
CSR5_TS_RUNNING_SETUP_PCKT = 101b
CSR5_TS_SUSPENDED = 110b
CSR5_TS_RUNNING_CLOSING_DESC = 111b
;------- CSR6 -OPERATION MODE- bits --------------------------------
CSR6_HP = 1 SHL 0 ; Hash/Perfect Receive Filtering mode
CSR6_SR = 1 SHL 1 ; Start/Stop receive
CSR6_HO = 1 SHL 2 ; Hash only Filtering mode
CSR6_PB = 1 SHL 3 ; Pass bad frames
CSR6_IF = 1 SHL 4 ; Inverse filtering
CSR6_SB = 1 SHL 5 ; Start/Stop backoff counter
CSR6_PR = 1 SHL 6 ; Promiscuos mode -default after reset
CSR6_PM = 1 SHL 7 ; Pass all multicast
CSR6_F = 1 SHL 9 ; Full Duplex mode
CSR6_OM_SH = 1 SHL 10 ; Operating Mode -shift
CSR6_OM_MASK = 11b ; -mask
CSR6_FC = 1 SHL 12 ; Force Collision Mode
CSR6_ST = 1 SHL 13 ; Start/Stop Transmission Command
CSR6_TR_SH = 1 SHL 14 ; Threshold Control -shift
CSR6_TR_MASK = 11b ; -mask
CSR6_CA = 1 SHL 17 ; Capture Effect Enable
CSR6_PS = 1 SHL 18 ; Port select SRL / MII/SYM
CSR6_HBD = 1 SHL 19 ; Heartbeat Disable
CSR6_SF = 1 SHL 21 ; Store and Forward -transmit full packet only
CSR6_TTM = 1 SHL 22 ; Transmit Threshold Mode -
CSR6_PCS = 1 SHL 23 ; PCS active and MII/SYM port operates in symbol mode
CSR6_SCR = 1 SHL 24 ; Scrambler Mode
CSR6_MBO = 1 SHL 25 ; Must Be One
CSR6_RA = 1 SHL 30 ; Receive All
CSR6_SC = 1 SHL 31 ; Special Capture Effect Enable
CSR6_HP = 1 shl 0 ; Hash/Perfect Receive Filtering mode
CSR6_SR = 1 shl 1 ; Start/Stop receive
CSR6_HO = 1 shl 2 ; Hash only Filtering mode
CSR6_PB = 1 shl 3 ; Pass bad frames
CSR6_IF = 1 shl 4 ; Inverse filtering
CSR6_SB = 1 shl 5 ; Start/Stop backoff counter
CSR6_PR = 1 shl 6 ; Promiscuos mode -default after reset
CSR6_PM = 1 shl 7 ; Pass all multicast
CSR6_F = 1 shl 9 ; Full Duplex mode
CSR6_OM_SH = 10 ; Operating Mode -shift
CSR6_OM_MASK = 11b ; -mask
CSR6_FC = 1 shl 12 ; Force Collision Mode
CSR6_ST = 1 shl 13 ; Start/Stop Transmission Command
CSR6_TR_SH = 14 ; Threshold Control -shift
CSR6_TR_MASK = 11b ; -mask
CSR6_CA = 1 shl 17 ; Capture Effect Enable
CSR6_PS = 1 shl 18 ; Port select SRL / MII/SYM
CSR6_HBD = 1 shl 19 ; Heartbeat Disable
CSR6_SF = 1 shl 21 ; Store and Forward -transmit full packet only
CSR6_TTM = 1 shl 22 ; Transmit Threshold Mode -
CSR6_PCS = 1 shl 23 ; PCS active and MII/SYM port operates in symbol mode
CSR6_SCR = 1 shl 24 ; Scrambler Mode
CSR6_MBO = 1 shl 25 ; Must Be One
CSR6_RA = 1 shl 30 ; Receive All
CSR6_SC = 1 shl 31 ; Special Capture Effect Enable
;------- CSR7 -INTERRUPT ENABLE- bits --------------------------------
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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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
;----------- descriptor structure ---------------------
struc DES {
.DES0 DD ? ; bit 31 is 'own' and rest is 'status'
.DES1 DD ? ; control bits + bytes-count buffer 1 + bytes-count buffer 2
.DES2 DD ? ; pointer to buffer1
.DES3 DD ? ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure
.realaddr dd ?
.size = 64
struc DES {
.status dd ? ; bit 31 is 'own' and rest is 'status'
.length dd ? ; control bits + bytes-count buffer 1 + bytes-count buffer 2
.buffer1 dd ? ; pointer to buffer1
.buffer2 dd ? ; pointer to buffer2 or in this case to next descriptor, as we use a chained structure
.virtaddr dd ?
.size = 64 ; 64, for alignment purposes
}
virtual at 0
@ -189,83 +197,78 @@ virtual at 0
end virtual
;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
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_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_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_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_LS = 1 SHL 8 ; Last 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_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_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_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_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_FF = 1 SHL 30 ; Filtering fail-frame failed address recognition test(must CSR6<30>=1), valid only on last desc (RDES0<8>=1)
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_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_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_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_LS = 1 shl 8 ; Last 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_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_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_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_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_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_RBS2_SH = 1 SHL 11 ; second buffer size SHIFT
RDES1_RBS2_MASK = 11111111111b ; second buffer size MASK
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_RBS1_MASK = 11111111111b ; first buffer size MASK
RDES1_RBS2_SH = 11 ; second buffer size SHIFT
RDES1_RBS2_MASK = 11111111111b ; second buffer size MASK
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
;transmition
TDES0_DE = 1 SHL 0 ; Deffered
TDES0_UF = 1 SHL 1 ; Underflow error
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_MASK = 1111b ; Collision Count mask
TDES0_HF = 1 SHL 7 ; Heartbeat fail
TDES0_EC = 1 SHL 8 ; Excessive Collisions - >16 collisions
TDES0_LC = 1 SHL 9 ; Late collision
TDES0_NC = 1 SHL 10 ; No carrier
TDES0_LO = 1 SHL 11 ; Loss of carrier
TDES0_TO = 1 SHL 14 ; Transmit Jabber Timeout
TDES0_ES = 1 SHL 15 ; Error summary TDES0<1+8+9+10+11+14>=1
TDES0_DE = 1 shl 0 ; Deffered
TDES0_UF = 1 shl 1 ; Underflow error
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_MASK = 1111b ; Collision Count mask
TDES0_HF = 1 shl 7 ; Heartbeat fail
TDES0_EC = 1 shl 8 ; Excessive Collisions - >16 collisions
TDES0_LC = 1 shl 9 ; Late collision
TDES0_NC = 1 shl 10 ; No carrier
TDES0_LO = 1 shl 11 ; Loss of carrier
TDES0_TO = 1 shl 14 ; Transmit Jabber Timeout
TDES0_ES = 1 shl 15 ; Error summary TDES0<1+8+9+10+11+14>=1
TDES1_TBS1_MASK = 11111111111b ; Buffer 1 size mask
TDES1_TBS2_SH = 11 ; Buffer 2 size shift
TDES1_TBS2_MASK = 11111111111b ; Buffer 2 size mask
TDES1_FT0 = 1 SHL 22 ; Filtering type 0
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_TER = 1 SHL 25 ; Transmit end of ring - final descriptor
TDES1_AC = 1 SHL 26 ; Add CRC disable -pretty obvious
TDES1_SET = 1 SHL 27 ; Setup packet
TDES1_FT1 = 1 SHL 28 ; Filtering type 1
TDES1_FS = 1 SHL 29 ; First segment - buffer is first segment of frame
TDES1_LS = 1 SHL 30 ; Last segment
TDES1_IC = 1 SHL 31 ; Interupt on completion (CSR5<0>=1) valid when TDES1<30>=1
TDES1_TBS1_MASK = 11111111111b ; Buffer 1 size mask
TDES1_TBS2_SH = 11 ; Buffer 2 size shift
TDES1_TBS2_MASK = 11111111111b ; Buffer 2 size mask
TDES1_FT0 = 1 shl 22 ; Filtering type 0
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_TER = 1 shl 25 ; Transmit end of ring - final descriptor
TDES1_AC = 1 shl 26 ; Add CRC disable -pretty obvious
TDES1_SET = 1 shl 27 ; Setup packet
TDES1_FT1 = 1 shl 28 ; Filtering type 1
TDES1_FS = 1 shl 29 ; First segment - buffer is first segment of frame
TDES1_LS = 1 shl 30 ; Last segment
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_BUFF_SIZE = 2048 ; size of buffer for each descriptor, must be multiple of 4 and <= 2048 TDES1_TBS1_MASK
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)
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
;=============================================================================
CSR9_SR = 1 SHL 11 ; SROM Select
CSR9_RD = 1 SHL 14 ; ROM Read Operation
CSR9_SROM_DO = 1 SHL 3 ; Data Out for SROM
CSR9_SROM_DI = 1 SHL 2 ; Data In to SROM
CSR9_SROM_CK = 1 SHL 1 ; clock for SROM
CSR9_SROM_CS = 1 SHL 0 ; chip select.. always needed
CSR9_SR = 1 shl 11 ; SROM Select
CSR9_RD = 1 shl 14 ; ROM Read Operation
CSR9_SROM_DO = 1 shl 3 ; Data Out for SROM
CSR9_SROM_DI = 1 shl 2 ; Data In to SROM
CSR9_SROM_CK = 1 shl 1 ; clock for SROM
CSR9_SROM_CS = 1 shl 0 ; chip select.. always needed
; assume dx is CSR9
macro SROM_Delay {
@ -298,8 +301,8 @@ macro Bit_Set a_bit {
macro Bit_Clear a_bit {
in eax, dx
and eax, NOT (a_bit)
out dx , eax
and eax, not (a_bit)
out dx, eax
}
@ -411,9 +414,9 @@ proc service_proc stdcall, ioctl:dword
; save the pci bus and device numbers
mov eax, [IOCTL.input]
mov cl , [eax+1]
mov cl, [eax+1]
mov [device.pci_bus], cl
mov cl , [eax+2]
mov cl, [eax+2]
mov [device.pci_dev], cl
; 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 ecx, [device.pci_dev]
stdcall PciRead32, eax ,ecx ,0 ; get device/vendor id
DEBUGF 1,"Vendor id: 0x%x\n", ax
cmp ax, 0x1011
jne .notfound
shr eax, 16
DEBUGF 1,"Vendor ok!, device id: 0x%x\n", ax ; TODO: use another method to detect chip!
cmp ax, 0x0009
@ -579,7 +580,7 @@ reset:
status
set_io CSR0
mov eax, CSR0_RESET
out dx , eax
out dx, eax
; wait at least 50 PCI cycles
mov esi, 1000
@ -592,7 +593,7 @@ reset:
status
set_io CSR0
mov eax, CSR0_DEFAULT
out dx , eax
out dx, eax
; wait at least 50 PCI cycles
@ -620,87 +621,7 @@ reset:
set_io 0
status
;------------------------------------------
; 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
call init_ring
;--------------------------------------------
; setup CSR3 & CSR4 (pointers to descriptors)
@ -709,15 +630,15 @@ reset:
status
set_io CSR3
mov eax, [device.rx_p_des]
call GetPgAddr
GetRealAddr
DEBUGF 1,"RX descriptor base address: %x\n", eax
out dx , eax
out dx, eax
set_io CSR4
mov eax, [device.tx_p_des]
call GetPgAddr
GetRealAddr
DEBUGF 1,"TX descriptor base address: %x\n", eax
out dx , eax
out dx, eax
;-------------------------------------------------------
; setup interrupt mask register -expect IRQs from now on
@ -726,7 +647,7 @@ reset:
DEBUGF 1,"Enabling interrupts\n"
set_io CSR7
mov eax, CSR7_DEFAULT
out dx , eax
out dx, eax
status
;----------
@ -744,7 +665,6 @@ reset:
call start_link
; wait a bit
mov esi, 3000
call Sleep
@ -769,6 +689,85 @@ reset:
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
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
; cmp [device.tx_packets], 0
; je .not_first
; je .first
;
; and [edi+DES.des1], 0
; mov [edi+DES.des0], DES0_OWN
@ -835,21 +834,20 @@ Send_Setup_Packet:
; mul edx
; add edi, eax
.not_first:
.first:
push edi
; copy setup packet to current descriptor
mov edi, [edi+DES.realaddr]
; copy once the address
mov edi, [edi + DES.virtaddr]
; copy the address once
lea esi, [device.mac]
DEBUGF 1,"copying packet to %x from %x\n", edi, esi
mov ecx, 3 ; mac is 6 bytes thus 3 words
.loop:
.loop:
DEBUGF 1,"%x ", [esi]:4
movsw
dec esi
dec esi
movsw
inc edi
inc edi
dec ecx
jnz .loop
@ -864,13 +862,13 @@ Send_Setup_Packet:
; setup descriptor
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.DES0], DES0_OWN
mov [edi + DES.length], TDES1_IC + TDES1_SET + TDES1_TCH + 192 ; size must be EXACTLY 192 bytes
mov [edi + DES.status], DES0_OWN
DEBUGF 1,"TDES0: %x\n", [edi + DES.DES0]:8
DEBUGF 1,"TDES1: %x\n", [edi + DES.DES1]:8
DEBUGF 1,"TDES2: %x\n", [edi + DES.DES2]:8
DEBUGF 1,"TDES3: %x\n", [edi + DES.DES3]:8
DEBUGF 1,"status: %x\n", [edi + DES.status]:8
DEBUGF 1,"length: %x\n", [edi + DES.length]:8
DEBUGF 1,"buffer1: %x\n", [edi + DES.buffer1]:8
DEBUGF 1,"buffer2: %x\n", [edi + DES.buffer2]:8
; go to next descriptor
inc [device.tx_wr_des]
@ -895,10 +893,10 @@ Send_Setup_Packet:
.already_started:
; if already started, issue a Transmit Poll command
set_io CSR1
mov eax, 0
xor eax, eax
DEBUGF 1,"Issuing transmit poll command\n"
.do_it:
out dx , eax
out dx, eax
status
DEBUGF 1,"Sending setup packet, completed!\n"
@ -940,21 +938,21 @@ transmit:
mov edx, DES.size
mul edx
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 ecx, [esp+8]
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
rep movsb
; set packet size
mov ecx, [eax+DES.DES1]
mov ecx, [eax+DES.length]
and ecx, TDES1_TER ; preserve 'End of Ring' bit
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
mov [eax+DES.DES1], ecx
mov [eax+DES.length], ecx
; 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
set_io 0
@ -1043,7 +1041,7 @@ int_handler:
;----------------------------------
; TX ok?
test eax, CSR5_TI
test ax, CSR5_TI
jz .not_tx
push ax esi ecx
@ -1063,7 +1061,7 @@ int_handler:
cmp [device.tx_free_des], TX_DES_COUNT
jz .end_tx
mov eax, [edi+DES.DES0]
mov eax, [edi+DES.status]
; we stop at first desc that is owned be NIC
test eax, DES0_OWN
@ -1101,22 +1099,25 @@ int_handler:
;----------------------------------
; RX irq
.not_tx:
test eax, CSR5_RI
test ax, CSR5_RI
jz .not_rx
push ax esi ecx
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 edx, DES.size
mul edx
add edi, eax
.loop_rx_start_of_packet:
mov eax, [edi+DES.DES0]
; now check status
mov eax, [edi + DES.status]
test eax, DES0_OWN
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
jz .end_rx
; .IF ZERO?
; ODS2 <"Net_Interrupt: packet > 1 descriptor, not supported yet :P">
; jmp @@end_rx
; .ENDIF
test eax, RDES0_ES
jnz .end_rx
; .IF !ZERO?
; ODS2 <"Net_Interrupt: RX error">
; jmp @@end_rx
; .ENDIF
mov esi, [edi+DES.realaddr]
mov ecx, [edi+DES.DES0]
mov esi, [edi + DES.virtaddr]
mov ecx, [edi + DES.status]
shr ecx, RDES0_FL_SH
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
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
test eax, eax
jz .fail
push edi
push dword .continue_rx
push ebx
push dword .rx_loop
push ecx eax
mov edi, eax
; update statistics
inc [device.packets_rx]
add dword [device.bytes_rx], ecx
adc dword [device.bytes_rx + 4], 0
@ -1176,26 +1166,17 @@ int_handler:
.nw:
rep movsd
jmp Eth_input
.continue_rx:
pop edi
; free descriptor
mov [edi+DES.DES0], DES0_OWN
mov [edi + DES.status], DES0_OWN ; free descriptor
; next descriptor
add edi, DES.size
inc [device.rx_crt_des]
inc [device.rx_crt_des] ; next descriptor
and [device.rx_crt_des], RX_DES_COUNT-1
jmp .loop_rx_start_of_packet
jmp Eth_input
.end_rx:
.fail:
.end_rx:
.fail:
pop ecx esi ax
.not_rx:
.not_rx:
jmp .continue