From a52b2728a762631fa4539fad16e65cc37c062364 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sun, 27 Jan 2013 20:13:23 +0000 Subject: [PATCH] Some refactoring of DEC21x4x driver. git-svn-id: svn://kolibrios.org@3201 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/drivers/dec21x4x.asm | 643 +++++++++++------------ 1 file changed, 312 insertions(+), 331 deletions(-) diff --git a/kernel/branches/net/drivers/dec21x4x.asm b/kernel/branches/net/drivers/dec21x4x.asm index 3b778de46c..b67716f616 100644 --- a/kernel/branches/net/drivers/dec21x4x.asm +++ b/kernel/branches/net/drivers/dec21x4x.asm @@ -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