Subversion Repositories Kolibri OS

Rev

Rev 4629 | Rev 5074 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4629 Rev 4663
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  MTD80x driver for KolibriOS                                    ;;
6
;;  MTD80x driver for KolibriOS                                    ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Based on mtd80x.c from the etherboot project                   ;;
8
;;  Based on mtd80x.c from the etherboot project                   ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;  Written by hidnplayr@kolibrios.org                             ;;
10
;;  Written by hidnplayr@kolibrios.org                             ;;
11
;;                                                                 ;;
11
;;                                                                 ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
12
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;             Version 2, June 1991                                ;;
13
;;             Version 2, June 1991                                ;;
14
;;                                                                 ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
16
 
17
format PE DLL native
17
format PE DLL native
18
entry START
18
entry START
19
 
19
 
20
        CURRENT_API             = 0x0200
20
        CURRENT_API             = 0x0200
21
        COMPATIBLE_API          = 0x0100
21
        COMPATIBLE_API          = 0x0100
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
22
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
23
 
23
 
24
        MAX_DEVICES             = 16
24
        MAX_DEVICES             = 16
25
 
-
 
26
        DEBUG                   = 1
25
 
27
        __DEBUG__               = 1
26
        __DEBUG__               = 1
28
        __DEBUG_LEVEL__         = 2
27
        __DEBUG_LEVEL__         = 2
29
 
28
 
30
        NUM_TX_DESC             = 6
29
        NUM_TX_DESC             = 6
31
        NUM_RX_DESC             = 12
30
        NUM_RX_DESC             = 12
32
 
31
 
33
section '.flat' readable writable executable
32
section '.flat' readable writable executable
34
 
33
 
35
include '../proc32.inc'
34
include '../proc32.inc'
36
include '../struct.inc'
35
include '../struct.inc'
37
include '../macros.inc'
36
include '../macros.inc'
38
include '../fdo.inc'
37
include '../fdo.inc'
39
include '../netdrv_pe.inc'
38
include '../netdrv_pe.inc'
40
 
39
 
41
; for different PHY
40
; for different PHY
42
 
41
 
43
    MysonPHY            = 1
42
    MysonPHY            = 1
44
    AhdocPHY            = 2
43
    AhdocPHY            = 2
45
    SeeqPHY             = 3
44
    SeeqPHY             = 3
46
    MarvellPHY          = 4
45
    MarvellPHY          = 4
47
    Myson981            = 5
46
    Myson981            = 5
48
    LevelOnePHY         = 6
47
    LevelOnePHY         = 6
49
    OtherPHY            = 10
48
    OtherPHY            = 10
50
 
49
 
51
; Offsets to the Command and Status Registers.
50
; Offsets to the Command and Status Registers.
52
 
51
 
53
    PAR0                = 0x0           ; physical address 0-3
52
    PAR0                = 0x0           ; physical address 0-3
54
    PAR1                = 0x04          ; physical address 4-5
53
    PAR1                = 0x04          ; physical address 4-5
55
    MAR0                = 0x08          ; multicast address 0-3
54
    MAR0                = 0x08          ; multicast address 0-3
56
    MAR1                = 0x0C          ; multicast address 4-7
55
    MAR1                = 0x0C          ; multicast address 4-7
57
    FAR0                = 0x10          ; flow-control address 0-3
56
    FAR0                = 0x10          ; flow-control address 0-3
58
    FAR1                = 0x14          ; flow-control address 4-5
57
    FAR1                = 0x14          ; flow-control address 4-5
59
    TCRRCR              = 0x18          ; receive & transmit configuration
58
    TCRRCR              = 0x18          ; receive & transmit configuration
60
    BCR                 = 0x1C          ; bus command
59
    BCR                 = 0x1C          ; bus command
61
    TXPDR               = 0x20          ; transmit polling demand
60
    TXPDR               = 0x20          ; transmit polling demand
62
    RXPDR               = 0x24          ; receive polling demand
61
    RXPDR               = 0x24          ; receive polling demand
63
    RXCWP               = 0x28          ; receive current word pointer
62
    RXCWP               = 0x28          ; receive current word pointer
64
    TXLBA               = 0x2C          ; transmit list base address
63
    TXLBA               = 0x2C          ; transmit list base address
65
    RXLBA               = 0x30          ; receive list base address
64
    RXLBA               = 0x30          ; receive list base address
66
    ISR                 = 0x34          ; interrupt status
65
    ISR                 = 0x34          ; interrupt status
67
    IMR                 = 0x38          ; interrupt mask
66
    IMR                 = 0x38          ; interrupt mask
68
    FTH                 = 0x3C          ; flow control high/low threshold
67
    FTH                 = 0x3C          ; flow control high/low threshold
69
    MANAGEMENT          = 0x40          ; bootrom/eeprom and mii management
68
    MANAGEMENT          = 0x40          ; bootrom/eeprom and mii management
70
    TALLY               = 0x44          ; tally counters for crc and mpa
69
    TALLY               = 0x44          ; tally counters for crc and mpa
71
    TSR                 = 0x48          ; tally counter for transmit status
70
    TSR                 = 0x48          ; tally counter for transmit status
72
    BMCRSR              = 0x4c          ; basic mode control and status
71
    BMCRSR              = 0x4c          ; basic mode control and status
73
    PHYIDENTIFIER       = 0x50          ; phy identifier
72
    PHYIDENTIFIER       = 0x50          ; phy identifier
74
    ANARANLPAR          = 0x54          ; auto-negotiation advertisement and link partner ability
73
    ANARANLPAR          = 0x54          ; auto-negotiation advertisement and link partner ability
75
    ANEROCR             = 0x58          ; auto-negotiation expansion and pci conf.
74
    ANEROCR             = 0x58          ; auto-negotiation expansion and pci conf.
76
    BPREMRPSR           = 0x5c          ; bypass & receive error mask and phy status
75
    BPREMRPSR           = 0x5c          ; bypass & receive error mask and phy status
77
 
76
 
78
; Bits in the interrupt status/enable registers.
77
; Bits in the interrupt status/enable registers.
79
 
78
 
80
    RFCON               = 0x00020000    ; receive flow control xon packet
79
    RFCON               = 0x00020000    ; receive flow control xon packet
81
    RFCOFF              = 0x00010000    ; receive flow control xoff packet
80
    RFCOFF              = 0x00010000    ; receive flow control xoff packet
82
    LSCStatus           = 0x00008000    ; link status change
81
    LSCStatus           = 0x00008000    ; link status change
83
    ANCStatus           = 0x00004000    ; autonegotiation completed
82
    ANCStatus           = 0x00004000    ; autonegotiation completed
84
    FBE                 = 0x00002000    ; fatal bus error
83
    FBE                 = 0x00002000    ; fatal bus error
85
    FBEMask             = 0x00001800    ; mask bit12-11
84
    FBEMask             = 0x00001800    ; mask bit12-11
86
    ParityErr           = 0x00000000    ; parity error
85
    ParityErr           = 0x00000000    ; parity error
87
    TargetErr           = 0x00001000    ; target abort
86
    TargetErr           = 0x00001000    ; target abort
88
    MasterErr           = 0x00000800    ; master error
87
    MasterErr           = 0x00000800    ; master error
89
    TUNF                = 0x00000400    ; transmit underflow
88
    TUNF                = 0x00000400    ; transmit underflow
90
    ROVF                = 0x00000200    ; receive overflow
89
    ROVF                = 0x00000200    ; receive overflow
91
    ETI                 = 0x00000100    ; transmit early int
90
    ETI                 = 0x00000100    ; transmit early int
92
    ERI                 = 0x00000080    ; receive early int
91
    ERI                 = 0x00000080    ; receive early int
93
    CNTOVF              = 0x00000040    ; counter overflow
92
    CNTOVF              = 0x00000040    ; counter overflow
94
    RBU                 = 0x00000020    ; receive buffer unavailable
93
    RBU                 = 0x00000020    ; receive buffer unavailable
95
    TBU                 = 0x00000010    ; transmit buffer unavilable
94
    TBU                 = 0x00000010    ; transmit buffer unavilable
96
    TI                  = 0x00000008    ; transmit interrupt
95
    TI                  = 0x00000008    ; transmit interrupt
97
    RI                  = 0x00000004    ; receive interrupt
96
    RI                  = 0x00000004    ; receive interrupt
98
    RxErr               = 0x00000002    ; receive error
97
    RxErr               = 0x00000002    ; receive error
99
 
98
 
100
; Bits in the NetworkConfig register.
99
; Bits in the NetworkConfig register.
101
 
100
 
102
    RxModeMask          = 0xe0
101
    RxModeMask          = 0xe0
103
    AcceptAllPhys       = 0x80          ; promiscuous mode
102
    AcceptAllPhys       = 0x80          ; promiscuous mode
104
    AcceptBroadcast     = 0x40          ; accept broadcast
103
    AcceptBroadcast     = 0x40          ; accept broadcast
105
    AcceptMulticast     = 0x20          ; accept mutlicast
104
    AcceptMulticast     = 0x20          ; accept mutlicast
106
    AcceptRunt          = 0x08          ; receive runt pkt
105
    AcceptRunt          = 0x08          ; receive runt pkt
107
    ALP                 = 0x04          ; receive long pkt
106
    ALP                 = 0x04          ; receive long pkt
108
    AcceptErr           = 0x02          ; receive error pkt
107
    AcceptErr           = 0x02          ; receive error pkt
109
 
108
 
110
    AcceptMyPhys        = 0x00000000
109
    AcceptMyPhys        = 0x00000000
111
    RxEnable            = 0x00000001
110
    RxEnable            = 0x00000001
112
    RxFlowCtrl          = 0x00002000
111
    RxFlowCtrl          = 0x00002000
113
    TxEnable            = 0x00040000
112
    TxEnable            = 0x00040000
114
    TxModeFDX           = 0x00100000
113
    TxModeFDX           = 0x00100000
115
    TxThreshold         = 0x00e00000
114
    TxThreshold         = 0x00e00000
116
 
115
 
117
    PS1000              = 0x00010000
116
    PS1000              = 0x00010000
118
    PS10                = 0x00080000
117
    PS10                = 0x00080000
119
    FD                  = 0x00100000
118
    FD                  = 0x00100000
120
 
119
 
121
 
120
 
122
; Bits in network_desc.status
121
; Bits in network_desc.status
123
 
122
 
124
    RXOWN               = 0x80000000    ; own bit
123
    RXOWN               = 0x80000000    ; own bit
125
    FLNGMASK            = 0x0fff0000    ; frame length
124
    FLNGMASK            = 0x0fff0000    ; frame length
126
    FLNGShift           = 16
125
    FLNGShift           = 16
127
    MARSTATUS           = 0x00004000    ; multicast address received
126
    MARSTATUS           = 0x00004000    ; multicast address received
128
    BARSTATUS           = 0x00002000    ; broadcast address received
127
    BARSTATUS           = 0x00002000    ; broadcast address received
129
    PHYSTATUS           = 0x00001000    ; physical address received
128
    PHYSTATUS           = 0x00001000    ; physical address received
130
    RXFSD               = 0x00000800    ; first descriptor
129
    RXFSD               = 0x00000800    ; first descriptor
131
    RXLSD               = 0x00000400    ; last descriptor
130
    RXLSD               = 0x00000400    ; last descriptor
132
    ErrorSummary        = 0x80          ; error summary
131
    ErrorSummary        = 0x80          ; error summary
133
    RUNT                = 0x40          ; runt packet received
132
    RUNT                = 0x40          ; runt packet received
134
    LONG                = 0x20          ; long packet received
133
    LONG                = 0x20          ; long packet received
135
    FAE                 = 0x10          ; frame align error
134
    FAE                 = 0x10          ; frame align error
136
    CRC                 = 0x08          ; crc error
135
    CRC                 = 0x08          ; crc error
137
    RXER                = 0x04          ; receive error
136
    RXER                = 0x04          ; receive error
138
 
137
 
139
; rx_desc_control_bits
138
; rx_desc_control_bits
140
 
139
 
141
    RXIC                = 0x00800000    ; interrupt control
140
    RXIC                = 0x00800000    ; interrupt control
142
    RBSShift            = 0
141
    RBSShift            = 0
143
 
142
 
144
; tx_desc_status_bits
143
; tx_desc_status_bits
145
 
144
 
146
    TXOWN               = 0x80000000    ; own bit
145
    TXOWN               = 0x80000000    ; own bit
147
    JABTO               = 0x00004000    ; jabber timeout
146
    JABTO               = 0x00004000    ; jabber timeout
148
    CSL                 = 0x00002000    ; carrier sense lost
147
    CSL                 = 0x00002000    ; carrier sense lost
149
    LC                  = 0x00001000    ; late collision
148
    LC                  = 0x00001000    ; late collision
150
    EC                  = 0x00000800    ; excessive collision
149
    EC                  = 0x00000800    ; excessive collision
151
    UDF                 = 0x00000400    ; fifo underflow
150
    UDF                 = 0x00000400    ; fifo underflow
152
    DFR                 = 0x00000200    ; deferred
151
    DFR                 = 0x00000200    ; deferred
153
    HF                  = 0x00000100    ; heartbeat fail
152
    HF                  = 0x00000100    ; heartbeat fail
154
    NCRMask             = 0x000000ff    ; collision retry count
153
    NCRMask             = 0x000000ff    ; collision retry count
155
    NCRShift            = 0
154
    NCRShift            = 0
156
 
155
 
157
; tx_desc_control_bits
156
; tx_desc_control_bits
158
 
157
 
159
    TXIC                = 0x80000000    ; interrupt control
158
    TXIC                = 0x80000000    ; interrupt control
160
    ETIControl          = 0x40000000    ; early transmit interrupt
159
    ETIControl          = 0x40000000    ; early transmit interrupt
161
    TXLD                = 0x20000000    ; last descriptor
160
    TXLD                = 0x20000000    ; last descriptor
162
    TXFD                = 0x10000000    ; first descriptor
161
    TXFD                = 0x10000000    ; first descriptor
163
    CRCEnable           = 0x08000000    ; crc control
162
    CRCEnable           = 0x08000000    ; crc control
164
    PADEnable           = 0x04000000    ; padding control
163
    PADEnable           = 0x04000000    ; padding control
165
    RetryTxLC           = 0x02000000    ; retry late collision
164
    RetryTxLC           = 0x02000000    ; retry late collision
166
    PKTSMask            = 0x3ff800      ; packet size bit21-11
165
    PKTSMask            = 0x3ff800      ; packet size bit21-11
167
    PKTSShift           = 11
166
    PKTSShift           = 11
168
    TBSMask             = 0x000007ff    ; transmit buffer bit 10-0
167
    TBSMask             = 0x000007ff    ; transmit buffer bit 10-0
169
    TBSShift            = 0
168
    TBSShift            = 0
170
 
169
 
171
; BootROM/EEPROM/MII Management Register
170
; BootROM/EEPROM/MII Management Register
172
 
171
 
173
    MASK_MIIR_MII_READ  = 0x00000000
172
    MASK_MIIR_MII_READ  = 0x00000000
174
    MASK_MIIR_MII_WRITE = 0x00000008
173
    MASK_MIIR_MII_WRITE = 0x00000008
175
    MASK_MIIR_MII_MDO   = 0x00000004
174
    MASK_MIIR_MII_MDO   = 0x00000004
176
    MASK_MIIR_MII_MDI   = 0x00000002
175
    MASK_MIIR_MII_MDI   = 0x00000002
177
    MASK_MIIR_MII_MDC   = 0x00000001
176
    MASK_MIIR_MII_MDC   = 0x00000001
178
 
177
 
179
; ST+OP+PHYAD+REGAD+TA
178
; ST+OP+PHYAD+REGAD+TA
180
 
179
 
181
    OP_READ             = 0x6000        ; ST:01+OP:10+PHYAD+REGAD+TA:Z0
180
    OP_READ             = 0x6000        ; ST:01+OP:10+PHYAD+REGAD+TA:Z0
182
    OP_WRITE            = 0x5002        ; ST:01+OP:01+PHYAD+REGAD+TA:10
181
    OP_WRITE            = 0x5002        ; ST:01+OP:01+PHYAD+REGAD+TA:10
183
 
182
 
184
; -------------------------------------------------------------------------
183
; -------------------------------------------------------------------------
185
;      Constants for Myson PHY
184
;      Constants for Myson PHY
186
; -------------------------------------------------------------------------
185
; -------------------------------------------------------------------------
187
 
186
 
188
    MysonPHYID          = 0xd0000302
187
    MysonPHYID          = 0xd0000302
189
    MysonPHYID0         = 0x0302
188
    MysonPHYID0         = 0x0302
190
    StatusRegister      = 18
189
    StatusRegister      = 18
191
    SPEED100            = 0x0400        ; bit10
190
    SPEED100            = 0x0400        ; bit10
192
    FULLMODE            = 0x0800        ; bit11
191
    FULLMODE            = 0x0800        ; bit11
193
 
192
 
194
; -------------------------------------------------------------------------
193
; -------------------------------------------------------------------------
195
;      Constants for Seeq 80225 PHY
194
;      Constants for Seeq 80225 PHY
196
; -------------------------------------------------------------------------
195
; -------------------------------------------------------------------------
197
 
196
 
198
    SeeqPHYID0          = 0x0016
197
    SeeqPHYID0          = 0x0016
199
    MIIRegister18       = 18
198
    MIIRegister18       = 18
200
    SPD_DET_100         = 0x80
199
    SPD_DET_100         = 0x80
201
    DPLX_DET_FULL       = 0x40
200
    DPLX_DET_FULL       = 0x40
202
 
201
 
203
; -------------------------------------------------------------------------
202
; -------------------------------------------------------------------------
204
;      Constants for Ahdoc 101 PHY
203
;      Constants for Ahdoc 101 PHY
205
; -------------------------------------------------------------------------
204
; -------------------------------------------------------------------------
206
 
205
 
207
    AhdocPHYID0         = 0x0022
206
    AhdocPHYID0         = 0x0022
208
    DiagnosticReg       = 18
207
    DiagnosticReg       = 18
209
    DPLX_FULL           = 0x0800
208
    DPLX_FULL           = 0x0800
210
    Speed_100           = 0x0400
209
    Speed_100           = 0x0400
211
 
210
 
212
; --------------------------------------------------------------------------
211
; --------------------------------------------------------------------------
213
;      Constants
212
;      Constants
214
; --------------------------------------------------------------------------
213
; --------------------------------------------------------------------------
215
 
214
 
216
    MarvellPHYID0               = 0x0141
215
    MarvellPHYID0               = 0x0141
217
    LevelOnePHYID0              = 0x0013
216
    LevelOnePHYID0              = 0x0013
218
 
217
 
219
    MII1000BaseTControlReg      = 9
218
    MII1000BaseTControlReg      = 9
220
    MII1000BaseTStatusReg       = 10
219
    MII1000BaseTStatusReg       = 10
221
    SpecificReg                 = 17
220
    SpecificReg                 = 17
222
 
221
 
223
; for 1000BaseT Control Register
222
; for 1000BaseT Control Register
224
 
223
 
225
    PHYAbletoPerform1000FullDuplex = 0x0200
224
    PHYAbletoPerform1000FullDuplex = 0x0200
226
    PHYAbletoPerform1000HalfDuplex = 0x0100
225
    PHYAbletoPerform1000HalfDuplex = 0x0100
227
    PHY1000AbilityMask             = 0x300
226
    PHY1000AbilityMask             = 0x300
228
 
227
 
229
; for phy specific status register, marvell phy.
228
; for phy specific status register, marvell phy.
230
 
229
 
231
    SpeedMask      = 0x0c000
230
    SpeedMask      = 0x0c000
232
    Speed_1000M    = 0x08000
231
    Speed_1000M    = 0x08000
233
    Speed_100M     = 0x4000
232
    Speed_100M     = 0x4000
234
    Speed_10M      = 0
233
    Speed_10M      = 0
235
    Full_Duplex    = 0x2000
234
    Full_Duplex    = 0x2000
236
 
235
 
237
; for phy specific status register, levelone phy
236
; for phy specific status register, levelone phy
238
 
237
 
239
    LXT1000_100M   = 0x08000
238
    LXT1000_100M   = 0x08000
240
    LXT1000_1000M  = 0x0c000
239
    LXT1000_1000M  = 0x0c000
241
    LXT1000_Full   = 0x200
240
    LXT1000_Full   = 0x200
242
 
241
 
243
; for PHY
242
; for PHY
244
 
243
 
245
    LinkIsUp       = 0x0004
244
    LinkIsUp       = 0x0004
246
    LinkIsUp2      = 0x00040000
245
    LinkIsUp2      = 0x00040000
247
 
246
 
248
 
247
 
249
 
248
 
250
struct  descriptor
249
struct  descriptor
251
        status                  dd ?
250
        status                  dd ?
252
        control                 dd ?
251
        control                 dd ?
253
        buffer                  dd ?
252
        buffer                  dd ?
254
        next_desc               dd ?
253
        next_desc               dd ?
255
 
254
 
256
        next_desc_logical       dd ?
255
        next_desc_logical       dd ?
257
        skbuff                  dd ?
256
        skbuff                  dd ?
258
        reserved1               dd ?
257
        reserved1               dd ?
259
        reserved2               dd ?
258
        reserved2               dd ?
260
ends
259
ends
261
 
260
 
262
 
261
 
263
struct  device          ETH_DEVICE
262
struct  device          ETH_DEVICE
264
 
263
 
265
        io_addr         dd ?
264
        io_addr         dd ?
266
        pci_bus         dd ?
265
        pci_bus         dd ?
267
        pci_dev         dd ?
266
        pci_dev         dd ?
268
        irq_line        db ?
267
        irq_line        db ?
269
        dev_id          dw ?
268
        dev_id          dw ?
270
        flags           dd ?
269
        flags           dd ?
271
        crvalue         dd ?
270
        crvalue         dd ?
272
        bcrvalue        dd ?
271
        bcrvalue        dd ?
273
        cur_rx          dd ?
272
        cur_rx          dd ?
274
        cur_tx          dd ?
273
        cur_tx          dd ?
275
        default_port    dd ?
274
        default_port    dd ?
276
        PHYType         dd ?
275
        PHYType         dd ?
277
 
276
 
278
; MII transceiver section.
277
; MII transceiver section.
279
        mii_cnt         dd ?    ; MII device addresses.
278
        mii_cnt         dd ?    ; MII device addresses.
280
        phys            db ?    ; MII device addresses.
279
        phys            db ?    ; MII device addresses.
281
 
280
 
282
; descriptors
281
; descriptors
283
        rb 0x100 - ($ and 0xff) ; align 256
282
        rb 0x100 - ($ and 0xff) ; align 256
284
        tx_desc         rb NUM_TX_DESC*sizeof.descriptor
283
        tx_desc         rb NUM_TX_DESC*sizeof.descriptor
285
        rx_desc         rb NUM_RX_DESC*sizeof.descriptor
284
        rx_desc         rb NUM_RX_DESC*sizeof.descriptor
286
 
285
 
287
ends
286
ends
288
 
287
 
289
 
288
 
290
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
289
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
291
;;                        ;;
290
;;                        ;;
292
;; proc START             ;;
291
;; proc START             ;;
293
;;                        ;;
292
;;                        ;;
294
;; (standard driver proc) ;;
293
;; (standard driver proc) ;;
295
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
294
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
296
 
295
 
297
proc START c, reason:dword, cmdline:dword
296
proc START c, reason:dword, cmdline:dword
298
 
297
 
299
        cmp     [reason], DRV_ENTRY
298
        cmp     [reason], DRV_ENTRY
300
        jne     .fail
299
        jne     .fail
301
 
300
 
302
        DEBUGF  1,"Loading driver\n"
301
        DEBUGF  1,"Loading driver\n"
303
        invoke  RegService, my_service, service_proc
302
        invoke  RegService, my_service, service_proc
304
        ret
303
        ret
305
 
304
 
306
  .fail:
305
  .fail:
307
        xor     eax, eax
306
        xor     eax, eax
308
        ret
307
        ret
309
 
308
 
310
endp
309
endp
311
 
310
 
312
 
311
 
313
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
312
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
314
;;                        ;;
313
;;                        ;;
315
;; proc SERVICE_PROC      ;;
314
;; proc SERVICE_PROC      ;;
316
;;                        ;;
315
;;                        ;;
317
;; (standard driver proc) ;;
316
;; (standard driver proc) ;;
318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
317
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
319
 
318
 
320
proc service_proc stdcall, ioctl:dword
319
proc service_proc stdcall, ioctl:dword
321
 
320
 
322
        mov     edx, [ioctl]
321
        mov     edx, [ioctl]
323
        mov     eax, [edx + IOCTL.io_code]
322
        mov     eax, [edx + IOCTL.io_code]
324
 
323
 
325
;------------------------------------------------------
324
;------------------------------------------------------
326
 
325
 
327
        cmp     eax, 0 ;SRV_GETVERSION
326
        cmp     eax, 0 ;SRV_GETVERSION
328
        jne     @F
327
        jne     @F
329
 
328
 
330
        cmp     [edx + IOCTL.out_size], 4
329
        cmp     [edx + IOCTL.out_size], 4
331
        jb      .fail
330
        jb      .fail
332
        mov     eax, [edx + IOCTL.output]
331
        mov     eax, [edx + IOCTL.output]
333
        mov     [eax], dword API_VERSION
332
        mov     [eax], dword API_VERSION
334
 
333
 
335
        xor     eax, eax
334
        xor     eax, eax
336
        ret
335
        ret
337
 
336
 
338
;------------------------------------------------------
337
;------------------------------------------------------
339
  @@:
338
  @@:
340
        cmp     eax, 1 ;SRV_HOOK
339
        cmp     eax, 1 ;SRV_HOOK
341
        jne     .fail
340
        jne     .fail
342
 
341
 
343
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
342
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
344
        jb      .fail
343
        jb      .fail
345
 
344
 
346
        mov     eax, [edx + IOCTL.input]
345
        mov     eax, [edx + IOCTL.input]
347
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
346
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
348
        jne     .fail                                   ; other types arent supported for this card yet
347
        jne     .fail                                   ; other types arent supported for this card yet
349
 
348
 
350
; check if the device is already listed
349
; check if the device is already listed
351
 
350
 
352
        mov     esi, device_list
351
        mov     esi, device_list
353
        mov     ecx, [devices]
352
        mov     ecx, [devices]
354
        test    ecx, ecx
353
        test    ecx, ecx
355
        jz      .firstdevice
354
        jz      .firstdevice
356
 
355
 
357
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
356
;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
358
        mov     ax, [eax+1]                             ;
357
        mov     ax, [eax+1]                             ;
359
  .nextdevice:
358
  .nextdevice:
360
        mov     ebx, [esi]
359
        mov     ebx, [esi]
361
        cmp     al, byte[ebx + device.pci_bus]
360
        cmp     al, byte[ebx + device.pci_bus]
362
        jne     @f
361
        jne     @f
363
        cmp     ah, byte[ebx + device.pci_dev]
362
        cmp     ah, byte[ebx + device.pci_dev]
364
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
363
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
365
       @@:
364
       @@:
366
        add     esi, 4
365
        add     esi, 4
367
        loop    .nextdevice
366
        loop    .nextdevice
368
 
367
 
369
 
368
 
370
; This device doesnt have its own eth_device structure yet, lets create one
369
; This device doesnt have its own eth_device structure yet, lets create one
371
  .firstdevice:
370
  .firstdevice:
372
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
371
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
373
        jae     .fail
372
        jae     .fail
374
 
373
 
375
        allocate_and_clear ebx, sizeof.device, .fail
374
        allocate_and_clear ebx, sizeof.device, .fail
376
 
375
 
377
; Fill in the direct call addresses into the struct
376
; Fill in the direct call addresses into the struct
378
 
377
 
379
        mov     [ebx + device.reset], reset
378
        mov     [ebx + device.reset], reset
380
        mov     [ebx + device.transmit], transmit
379
        mov     [ebx + device.transmit], transmit
381
        mov     [ebx + device.unload], unload
380
        mov     [ebx + device.unload], unload
382
        mov     [ebx + device.name], my_service
381
        mov     [ebx + device.name], my_service
383
 
382
 
384
; save the pci bus and device numbers
383
; save the pci bus and device numbers
385
 
384
 
386
        mov     eax, [edx + IOCTL.input]
385
        mov     eax, [edx + IOCTL.input]
387
        movzx   ecx, byte[eax+1]
386
        movzx   ecx, byte[eax+1]
388
        mov     [ebx + device.pci_bus], ecx
387
        mov     [ebx + device.pci_bus], ecx
389
        movzx   ecx, byte[eax+2]
388
        movzx   ecx, byte[eax+2]
390
        mov     [ebx + device.pci_dev], ecx
389
        mov     [ebx + device.pci_dev], ecx
391
 
390
 
392
; Now, it's time to find the base io addres of the PCI device
391
; Now, it's time to find the base io addres of the PCI device
393
 
392
 
394
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
393
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
395
        mov     [ebx + device.io_addr], eax
394
        mov     [ebx + device.io_addr], eax
396
 
395
 
397
; We've found the io address, find IRQ now
396
; We've found the io address, find IRQ now
398
 
397
 
399
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
398
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
400
        mov     [ebx + device.irq_line], al
399
        mov     [ebx + device.irq_line], al
401
 
400
 
402
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
401
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
403
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
402
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
404
 
403
 
405
; Ok, the eth_device structure is ready, let's probe the device
404
; Ok, the eth_device structure is ready, let's probe the device
406
; Because initialization fires IRQ, IRQ handler must be aware of this device
405
; Because initialization fires IRQ, IRQ handler must be aware of this device
407
        mov     eax, [devices]                                          ; Add the device structure to our device list
406
        mov     eax, [devices]                                          ; Add the device structure to our device list
408
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
407
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
409
        inc     [devices]                                               ;
408
        inc     [devices]                                               ;
410
 
409
 
411
        call    probe                                                   ; this function will output in eax
410
        call    probe                                                   ; this function will output in eax
412
        test    eax, eax
411
        test    eax, eax
413
        jnz     .err2                                                   ; If an error occured, exit
412
        jnz     .err2                                                   ; If an error occured, exit
414
 
413
 
415
        mov     [ebx + device.type], NET_TYPE_ETH
414
        mov     [ebx + device.type], NET_TYPE_ETH
416
        invoke  NetRegDev
415
        invoke  NetRegDev
417
 
416
 
418
        cmp     eax, -1
417
        cmp     eax, -1
419
        je      .destroy
418
        je      .destroy
420
 
419
 
421
        ret
420
        ret
422
 
421
 
423
; If the device was already loaded, find the device number and return it in eax
422
; If the device was already loaded, find the device number and return it in eax
424
 
423
 
425
  .find_devicenum:
424
  .find_devicenum:
426
        DEBUGF  2,"Trying to find device number of already registered device\n"
425
        DEBUGF  2,"Trying to find device number of already registered device\n"
427
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
426
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
428
                                                                        ; into a device number in edi
427
                                                                        ; into a device number in edi
429
        mov     eax, edi                                                ; Application wants it in eax instead
428
        mov     eax, edi                                                ; Application wants it in eax instead
430
        DEBUGF  2,"Kernel says: %u\n", eax
429
        DEBUGF  2,"Kernel says: %u\n", eax
431
        ret
430
        ret
432
 
431
 
433
; If an error occured, remove all allocated data and exit (returning -1 in eax)
432
; If an error occured, remove all allocated data and exit (returning -1 in eax)
434
 
433
 
435
  .destroy:
434
  .destroy:
436
        ; todo: reset device into virgin state
435
        ; todo: reset device into virgin state
437
 
436
 
438
  .err2:
437
  .err2:
439
        dec     [devices]
438
        dec     [devices]
440
  .err:
439
  .err:
441
        DEBUGF  2,"removing device structure\n"
440
        DEBUGF  2,"removing device structure\n"
442
        invoke  KernelFree, ebx
441
        invoke  KernelFree, ebx
443
  .fail:
442
  .fail:
444
        or      eax, -1
443
        or      eax, -1
445
        ret
444
        ret
446
 
445
 
447
;------------------------------------------------------
446
;------------------------------------------------------
448
endp
447
endp
449
 
448
 
450
 
449
 
451
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
450
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
452
;;                                                                        ;;
451
;;                                                                        ;;
453
;;        Actual Hardware dependent code starts here                      ;;
452
;;        Actual Hardware dependent code starts here                      ;;
454
;;                                                                        ;;
453
;;                                                                        ;;
455
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
454
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
456
 
455
 
457
 
456
 
458
 
457
 
459
align 4
458
align 4
460
unload:
459
unload:
461
        ; TODO: (in this particular order)
460
        ; TODO: (in this particular order)
462
        ;
461
        ;
463
        ; - Stop the device
462
        ; - Stop the device
464
 
463
 
465
;    /* Disable Tx Rx*/
464
;    /* Disable Tx Rx*/
466
;    outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR );
465
;    outl( mtdx.crvalue & (~TxEnable) & (~RxEnable), mtdx.ioaddr + TCRRCR );
467
;
466
;
468
;    /* Reset the chip to erase previous misconfiguration. */
467
;    /* Reset the chip to erase previous misconfiguration. */
469
;    mtd_reset(nic);
468
;    mtd_reset(nic);
470
 
469
 
471
        ; - Detach int handler
470
        ; - Detach int handler
472
        ; - Remove device from local list (device_list)
471
        ; - Remove device from local list (device_list)
473
        ; - call unregister function in kernel
472
        ; - call unregister function in kernel
474
        ; - Remove all allocated structures and buffers the card used
473
        ; - Remove all allocated structures and buffers the card used
475
 
474
 
476
        or      eax, -1
475
        or      eax, -1
477
 
476
 
478
ret
477
ret
479
 
478
 
480
 
479
 
481
;-------
480
;-------
482
;
481
;
483
; PROBE
482
; PROBE
484
;
483
;
485
;-------
484
;-------
486
align 4
485
align 4
487
probe:
486
probe:
488
 
487
 
489
        DEBUGF  1,"Probing\n"
488
        DEBUGF  1,"Probing\n"
490
 
489
 
491
; Make the device a bus master
490
; Make the device a bus master
492
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
491
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
493
        or      al, PCI_CMD_MASTER
492
        or      al, PCI_CMD_MASTER
494
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
493
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
495
 
494
 
496
; Check vendor/device id's
495
; Check vendor/device id's
497
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
496
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], 0
498
        cmp     ax, 0x1516
497
        cmp     ax, 0x1516
499
        jne     .notfound
498
        jne     .notfound
500
        shr     eax, 16
499
        shr     eax, 16
501
        mov     [ebx + device.dev_id], ax
500
        mov     [ebx + device.dev_id], ax
502
        cmp     ax, 0x0800
501
        cmp     ax, 0x0800
503
        je      .mtd800
502
        je      .mtd800
504
        cmp     ax, 0x0803
503
        cmp     ax, 0x0803
505
        je      .mtd803
504
        je      .mtd803
506
        cmp     ax, 0x0891
505
        cmp     ax, 0x0891
507
        je      .mtd891
506
        je      .mtd891
508
 
507
 
509
  .notfound:
508
  .notfound:
510
        DEBUGF  2,"Device not supported!\n"
509
        DEBUGF  2,"Device not supported!\n"
511
        xor     eax, eax
510
        xor     eax, eax
512
        dec     eax
511
        dec     eax
513
        ret
512
        ret
514
 
513
 
515
  .mtd803:
514
  .mtd803:
516
        mov     [ebx + device.name], sz_mtd803
515
        mov     [ebx + device.name], sz_mtd803
517
        DEBUGF  1,"Device has chip xcvr\n"
516
        DEBUGF  1,"Device has chip xcvr\n"
518
        jmp     .xcvr_set
517
        jmp     .xcvr_set
519
 
518
 
520
  .mtd800:
519
  .mtd800:
521
        DEBUGF  1,"Device has mii xcvr\n"
520
        DEBUGF  1,"Device has mii xcvr\n"
522
        mov     [ebx + device.name], sz_mtd800
521
        mov     [ebx + device.name], sz_mtd800
523
        jmp     .xcvr_set
522
        jmp     .xcvr_set
524
 
523
 
525
  .mtd891:
524
  .mtd891:
526
        DEBUGF  1,"Device has mii xcvr\n"
525
        DEBUGF  1,"Device has mii xcvr\n"
527
        mov     [ebx + device.name], sz_mtd800
526
        mov     [ebx + device.name], sz_mtd800
528
 
527
 
529
  .xcvr_set:
528
  .xcvr_set:
530
        call    read_mac
529
        call    read_mac
531
 
530
 
532
; Reset the chip to erase previous misconfiguration.
531
; Reset the chip to erase previous misconfiguration.
533
        set_io  [ebx + device.io_addr], 0
532
        set_io  [ebx + device.io_addr], 0
534
        set_io  [ebx + device.io_addr], BCR
533
        set_io  [ebx + device.io_addr], BCR
535
        xor     eax, eax
534
        xor     eax, eax
536
        inc     eax
535
        inc     eax
537
        out     dx, eax
536
        out     dx, eax
538
 
537
 
539
; find the connected MII xcvrs
538
; find the connected MII xcvrs
540
        cmp     [ebx + device.dev_id], 0x0803
539
        cmp     [ebx + device.dev_id], 0x0803
541
        je      .is_803
540
        je      .is_803
542
 
541
 
543
;        int     phy, phy_idx =   0;
542
;        int     phy, phy_idx =   0;
544
;
543
;
545
;        for (phy =   1; phy < 32 && phy_idx < 1; phy++) {
544
;        for (phy =   1; phy < 32 && phy_idx < 1; phy++) {
546
;            int mii_status =   mdio_read(nic, phy, 1);
545
;            int mii_status =   mdio_read(nic, phy, 1);
547
;
546
;
548
;            if (mii_status !=   0xffff && mii_status !=   0x0000) {
547
;            if (mii_status !=   0xffff && mii_status !=   0x0000) {
549
;                mtdx.phys[phy_idx] =   phy;
548
;                mtdx.phys[phy_idx] =   phy;
550
;
549
;
551
;                DBG ( "%s: MII PHY found at address %d, status "
550
;                DBG ( "%s: MII PHY found at address %d, status "
552
;                      "0x%4.4x.\n", mtdx.nic_name, phy, mii_status );
551
;                      "0x%4.4x.\n", mtdx.nic_name, phy, mii_status );
553
;                /* get phy type */
552
;                /* get phy type */
554
;                {
553
;                {
555
;                    unsigned int data;
554
;                    unsigned int data;
556
;
555
;
557
;                    data =   mdio_read(nic, mtdx.phys[phy_idx], 2);
556
;                    data =   mdio_read(nic, mtdx.phys[phy_idx], 2);
558
;                    if (data equ=   SeeqPHYID0)
557
;                    if (data equ=   SeeqPHYID0)
559
;                        mtdx.PHYType =   SeeqPHY;
558
;                        mtdx.PHYType =   SeeqPHY;
560
;                    else if (data equ=   AhdocPHYID0)
559
;                    else if (data equ=   AhdocPHYID0)
561
;                        mtdx.PHYType =   AhdocPHY;
560
;                        mtdx.PHYType =   AhdocPHY;
562
;                    else if (data equ=   MarvellPHYID0)
561
;                    else if (data equ=   MarvellPHYID0)
563
;                        mtdx.PHYType =   MarvellPHY;
562
;                        mtdx.PHYType =   MarvellPHY;
564
;                    else if (data equ=   MysonPHYID0)
563
;                    else if (data equ=   MysonPHYID0)
565
;                        mtdx.PHYType =   Myson981;
564
;                        mtdx.PHYType =   Myson981;
566
;                    else if (data equ=   LevelOnePHYID0)
565
;                    else if (data equ=   LevelOnePHYID0)
567
;                        mtdx.PHYType =   LevelOnePHY;
566
;                        mtdx.PHYType =   LevelOnePHY;
568
;                    else
567
;                    else
569
;                        mtdx.PHYType =   OtherPHY;
568
;                        mtdx.PHYType =   OtherPHY;
570
;                }
569
;                }
571
;                phy_idx++;
570
;                phy_idx++;
572
;            }
571
;            }
573
;        }
572
;        }
574
;
573
;
575
;        mtdx.mii_cnt =   phy_idx;
574
;        mtdx.mii_cnt =   phy_idx;
576
;        if (phy_idx equ=   0) {
575
;        if (phy_idx equ=   0) {
577
;            printf("%s: MII PHY not found -- this device may "
576
;            printf("%s: MII PHY not found -- this device may "
578
;                   "not operate correctly.\n", mtdx.nic_name);
577
;                   "not operate correctly.\n", mtdx.nic_name);
579
;        }
578
;        }
580
 
579
 
581
        jmp     .no_803
580
        jmp     .no_803
582
 
581
 
583
  .is_803:
582
  .is_803:
584
        mov     [ebx + device.phys], 32
583
        mov     [ebx + device.phys], 32
585
 
584
 
586
; get phy type
585
; get phy type
587
        set_io  [ebx + device.io_addr], 0
586
        set_io  [ebx + device.io_addr], 0
588
        set_io  [ebx + device.io_addr], PHYIDENTIFIER
587
        set_io  [ebx + device.io_addr], PHYIDENTIFIER
589
        in      eax, dx
588
        in      eax, dx
590
 
589
 
591
        cmp     eax, MysonPHYID
590
        cmp     eax, MysonPHYID
592
        jne     @f
591
        jne     @f
593
        mov     [ebx + device.PHYType], MysonPHY
592
        mov     [ebx + device.PHYType], MysonPHY
594
        DEBUGF  1,"Myson PHY\n"
593
        DEBUGF  1,"Myson PHY\n"
595
        jmp     .no_803
594
        jmp     .no_803
596
       @@:
595
       @@:
597
 
596
 
598
        mov     [ebx + device.PHYType], OtherPHY
597
        mov     [ebx + device.PHYType], OtherPHY
599
        DEBUGF  1,"Other PHY\n"
598
        DEBUGF  1,"Other PHY\n"
600
  .no_803:
599
  .no_803:
601
 
600
 
602
;-------
601
;-------
603
;
602
;
604
; RESET
603
; RESET
605
;
604
;
606
;-------
605
;-------
607
align 4
606
align 4
608
reset:
607
reset:
609
 
608
 
610
        DEBUGF  1,"Resetting\n"
609
        DEBUGF  1,"Resetting\n"
611
 
610
 
612
; attach irq handler
611
; attach irq handler
613
        movzx   eax, [ebx + device.irq_line]
612
        movzx   eax, [ebx + device.irq_line]
614
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
613
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
615
        invoke  AttachIntHandler, eax, int_handler, ebx
614
        invoke  AttachIntHandler, eax, int_handler, ebx
616
        test    eax, eax
615
        test    eax, eax
617
        jnz     @f
616
        jnz     @f
618
        DEBUGF  2,"Could not attach int handler!\n"
617
        DEBUGF  2,"Could not attach int handler!\n"
619
        or      eax, -1
618
        or      eax, -1
620
        ret
619
        ret
621
  @@:
620
  @@:
622
 
621
 
623
; Reset the chip to erase previous misconfiguration.
622
; Reset the chip to erase previous misconfiguration.
624
        set_io  [ebx + device.io_addr], 0
623
        set_io  [ebx + device.io_addr], 0
625
        set_io  [ebx + device.io_addr], BCR
624
        set_io  [ebx + device.io_addr], BCR
626
        xor     eax, eax
625
        xor     eax, eax
627
        inc     eax
626
        inc     eax
628
        out     dx, eax
627
        out     dx, eax
629
 
628
 
630
        call    init_ring
629
        call    init_ring
631
 
630
 
632
; Initialize other registers.
631
; Initialize other registers.
633
; Configure the PCI bus bursts and FIFO thresholds.
632
; Configure the PCI bus bursts and FIFO thresholds.
634
        mov     [ebx + device.bcrvalue], 0x10         ; little-endian, 8 burst length
633
        mov     [ebx + device.bcrvalue], 0x10         ; little-endian, 8 burst length
635
        mov     [ebx + device.crvalue], 0xa00         ; 128 burst length
634
        mov     [ebx + device.crvalue], 0xa00         ; 128 burst length
636
 
635
 
637
        cmp     [ebx + device.dev_id], 0x891
636
        cmp     [ebx + device.dev_id], 0x891
638
        jne     @f
637
        jne     @f
639
        or      [ebx + device.bcrvalue], 0x200       ; set PROG bit
638
        or      [ebx + device.bcrvalue], 0x200       ; set PROG bit
640
        or      [ebx + device.crvalue], 0x02000000   ; set enhanced bit
639
        or      [ebx + device.crvalue], 0x02000000   ; set enhanced bit
641
       @@:
640
       @@:
642
        or      [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable
641
        or      [ebx + device.crvalue], RxEnable + TxThreshold + TxEnable
643
 
642
 
644
        call    set_rx_mode
643
        call    set_rx_mode
645
 
644
 
646
        set_io  [ebx + device.io_addr], 0
645
        set_io  [ebx + device.io_addr], 0
647
        set_io  [ebx + device.io_addr], BCR
646
        set_io  [ebx + device.io_addr], BCR
648
        mov     eax, [ebx + device.bcrvalue]
647
        mov     eax, [ebx + device.bcrvalue]
649
        out     dx, eax
648
        out     dx, eax
650
 
649
 
651
        set_io  [ebx + device.io_addr], TCRRCR
650
        set_io  [ebx + device.io_addr], TCRRCR
652
        mov     eax, [ebx + device.crvalue]
651
        mov     eax, [ebx + device.crvalue]
653
        out     dx, eax
652
        out     dx, eax
654
 
653
 
655
        call    getlinkstatus
654
        call    getlinkstatus
656
 
655
 
657
; Restart Rx engine if stopped.
656
; Restart Rx engine if stopped.
658
        set_io  [ebx + device.io_addr], 0
657
        set_io  [ebx + device.io_addr], 0
659
        set_io  [ebx + device.io_addr], RXPDR
658
        set_io  [ebx + device.io_addr], RXPDR
660
        xor     eax, eax
659
        xor     eax, eax
661
        out     dx, eax
660
        out     dx, eax
662
 
661
 
663
; Enable interrupts
662
; Enable interrupts
664
        set_io  [ebx + device.io_addr], ISR
663
        set_io  [ebx + device.io_addr], ISR
665
        mov     eax, FBE or TUNF or CNTOVF or RBU or TI or RI
664
        mov     eax, FBE or TUNF or CNTOVF or RBU or TI or RI
666
        out     dx, eax
665
        out     dx, eax
667
        set_io  [ebx + device.io_addr], IMR
666
        set_io  [ebx + device.io_addr], IMR
668
        out     dx, eax
667
        out     dx, eax
669
 
668
 
670
; clear packet/byte counters
669
; clear packet/byte counters
671
        xor     eax, eax
670
        xor     eax, eax
672
        lea     edi, [ebx + device.bytes_tx]
671
        lea     edi, [ebx + device.bytes_tx]
673
        mov     ecx, 6
672
        mov     ecx, 6
674
        rep     stosd
673
        rep     stosd
675
 
674
 
676
        mov     [ebx + device.mtu], 1514
675
        mov     [ebx + device.mtu], 1514
677
        xor     eax, eax
676
        xor     eax, eax
678
        ret
677
        ret
679
 
678
 
680
 
679
 
681
 
680
 
682
 
681
 
683
align 4
682
align 4
684
init_ring:
683
init_ring:
685
 
684
 
686
        DEBUGF  1,"initializing rx and tx ring\n"
685
        DEBUGF  1,"initializing rx and tx ring\n"
687
 
686
 
688
; Initialize all Rx descriptors
687
; Initialize all Rx descriptors
689
        lea     esi, [ebx + device.rx_desc]
688
        lea     esi, [ebx + device.rx_desc]
690
        mov     [ebx + device.cur_rx], esi
689
        mov     [ebx + device.cur_rx], esi
691
        mov     ecx, NUM_RX_DESC
690
        mov     ecx, NUM_RX_DESC
692
  .rx_desc_loop:
691
  .rx_desc_loop:
693
        mov     [esi + descriptor.status], RXOWN
692
        mov     [esi + descriptor.status], RXOWN
694
        mov     [esi + descriptor.control], 1536 shl RBSShift
693
        mov     [esi + descriptor.control], 1536 shl RBSShift
695
 
694
 
696
        lea     eax, [esi + sizeof.descriptor]
695
        lea     eax, [esi + sizeof.descriptor]
697
        mov     [esi + descriptor.next_desc_logical], eax
696
        mov     [esi + descriptor.next_desc_logical], eax
698
        push    ecx esi
697
        push    ecx esi
699
        invoke  GetPhysAddr
698
        invoke  GetPhysAddr
700
        mov     [esi + descriptor.next_desc], eax
699
        mov     [esi + descriptor.next_desc], eax
701
 
700
 
702
        invoke  KernelAlloc, 1536
701
        invoke  KernelAlloc, 1536
703
        pop     esi
702
        pop     esi
704
        push    esi
703
        push    esi
705
        mov     [esi + descriptor.skbuff], eax
704
        mov     [esi + descriptor.skbuff], eax
706
        invoke  GetPgAddr
705
        invoke  GetPgAddr
707
        pop     esi ecx
706
        pop     esi ecx
708
        mov     [esi + descriptor.buffer], eax
707
        mov     [esi + descriptor.buffer], eax
709
 
708
 
710
        add     esi, sizeof.descriptor
709
        add     esi, sizeof.descriptor
711
        loop    .rx_desc_loop
710
        loop    .rx_desc_loop
712
 
711
 
713
; Mark the last entry as wrapping the ring.
712
; Mark the last entry as wrapping the ring.
714
        lea     eax, [ebx + device.rx_desc]
713
        lea     eax, [ebx + device.rx_desc]
715
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
714
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
716
        push    esi
715
        push    esi
717
        invoke  GetPhysAddr
716
        invoke  GetPhysAddr
718
        pop     esi
717
        pop     esi
719
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
718
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
720
 
719
 
721
        set_io  [ebx + device.io_addr],   0
720
        set_io  [ebx + device.io_addr],   0
722
        set_io  [ebx + device.io_addr],   RXLBA
721
        set_io  [ebx + device.io_addr],   RXLBA
723
        out     dx, eax
722
        out     dx, eax
724
 
723
 
725
; Initialize all Tx descriptors
724
; Initialize all Tx descriptors
726
        lea     esi, [ebx + device.tx_desc]
725
        lea     esi, [ebx + device.tx_desc]
727
        mov     [ebx + device.cur_tx], esi
726
        mov     [ebx + device.cur_tx], esi
728
        mov     ecx, NUM_TX_DESC
727
        mov     ecx, NUM_TX_DESC
729
  .tx_desc_loop:
728
  .tx_desc_loop:
730
        mov     [esi + descriptor.status], 0
729
        mov     [esi + descriptor.status], 0
731
 
730
 
732
        lea     eax, [esi + sizeof.descriptor]
731
        lea     eax, [esi + sizeof.descriptor]
733
        mov     [esi + descriptor.next_desc_logical], eax
732
        mov     [esi + descriptor.next_desc_logical], eax
734
        push    ecx esi
733
        push    ecx esi
735
        invoke  GetPhysAddr
734
        invoke  GetPhysAddr
736
        pop     esi ecx
735
        pop     esi ecx
737
        mov     [esi + descriptor.next_desc], eax
736
        mov     [esi + descriptor.next_desc], eax
738
        mov     [esi + descriptor.skbuff], 0
737
        mov     [esi + descriptor.skbuff], 0
739
        add     esi, sizeof.descriptor
738
        add     esi, sizeof.descriptor
740
        loop    .tx_desc_loop
739
        loop    .tx_desc_loop
741
 
740
 
742
; Mark the last entry as wrapping the ring.
741
; Mark the last entry as wrapping the ring.
743
        lea     eax, [ebx + device.tx_desc]
742
        lea     eax, [ebx + device.tx_desc]
744
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
743
        mov     [esi - sizeof.descriptor + descriptor.next_desc_logical], eax
745
        push    esi
744
        push    esi
746
        invoke  GetPhysAddr
745
        invoke  GetPhysAddr
747
        pop     esi
746
        pop     esi
748
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
747
        mov     [esi - sizeof.descriptor + descriptor.next_desc], eax
749
 
748
 
750
        set_io  [ebx + device.io_addr],   0
749
        set_io  [ebx + device.io_addr],   0
751
        set_io  [ebx + device.io_addr],   TXLBA
750
        set_io  [ebx + device.io_addr],   TXLBA
752
        out     dx, eax
751
        out     dx, eax
753
 
752
 
754
        ret
753
        ret
755
 
754
 
756
 
755
 
757
align 4
756
align 4
758
set_rx_mode:
757
set_rx_mode:
759
 
758
 
760
        DEBUGF  1,"Setting RX mode\n"
759
        DEBUGF  1,"Setting RX mode\n"
761
 
760
 
762
; Too many to match, or accept all multicasts.
761
; Too many to match, or accept all multicasts.
763
        set_io  [ebx + device.io_addr], 0
762
        set_io  [ebx + device.io_addr], 0
764
        set_io  [ebx + device.io_addr], MAR0
763
        set_io  [ebx + device.io_addr], MAR0
765
        xor     eax, eax
764
        xor     eax, eax
766
        not     eax
765
        not     eax
767
        out     dx, eax
766
        out     dx, eax
768
        set_io  [ebx + device.io_addr], MAR1
767
        set_io  [ebx + device.io_addr], MAR1
769
        out     dx, eax
768
        out     dx, eax
770
 
769
 
771
        and     [ebx + device.crvalue], not (RxModeMask)
770
        and     [ebx + device.crvalue], not (RxModeMask)
772
        or      [ebx + device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys
771
        or      [ebx + device.crvalue], AcceptBroadcast + AcceptMulticast + AcceptMyPhys
773
 
772
 
774
        ret
773
        ret
775
 
774
 
776
 
775
 
777
align 4
776
align 4
778
getlinkstatus:
777
getlinkstatus:
779
 
778
 
780
        DEBUGF  1,"Getting link status\n"
779
        DEBUGF  1,"Getting link status\n"
781
 
780
 
782
        mov     [ebx + device.state], ETH_LINK_DOWN     ; assume link is dead
781
        mov     [ebx + device.state], ETH_LINK_DOWN     ; assume link is dead
783
 
782
 
784
        cmp     [ebx + device.PHYType], MysonPHY
783
        cmp     [ebx + device.PHYType], MysonPHY
785
        jne     .no_myson_phy
784
        jne     .no_myson_phy
786
        set_io  [ebx + device.io_addr], 0
785
        set_io  [ebx + device.io_addr], 0
787
        set_io  [ebx + device.io_addr], BMCRSR
786
        set_io  [ebx + device.io_addr], BMCRSR
788
        in      eax, dx
787
        in      eax, dx
789
        test    eax, LinkIsUp2
788
        test    eax, LinkIsUp2
790
        jnz     getlinktype
789
        jnz     getlinktype
791
        ret
790
        ret
792
 
791
 
793
  .no_myson_phy:
792
  .no_myson_phy:
794
        set_io  [ebx + device.io_addr], 0
793
        set_io  [ebx + device.io_addr], 0
795
        set_io  [ebx + device.io_addr], BMCRSR
794
        set_io  [ebx + device.io_addr], BMCRSR
796
        in      eax, dx
795
        in      eax, dx
797
        test    eax, LinkIsUp
796
        test    eax, LinkIsUp
798
        jnz     getlinktype
797
        jnz     getlinktype
799
        ret
798
        ret
800
 
799
 
801
getlinktype:
800
getlinktype:
802
 
801
 
803
        DEBUGF  1,"Getting link type\n"
802
        DEBUGF  1,"Getting link type\n"
804
        cmp     [ebx + device.PHYType], MysonPHY
803
        cmp     [ebx + device.PHYType], MysonPHY
805
        jne     .no_myson_phy
804
        jne     .no_myson_phy
806
 
805
 
807
        DEBUGF  1,"myson PHY\n"
806
        DEBUGF  1,"myson PHY\n"
808
        set_io  [ebx + device.io_addr], 0
807
        set_io  [ebx + device.io_addr], 0
809
        set_io  [ebx + device.io_addr], TCRRCR
808
        set_io  [ebx + device.io_addr], TCRRCR
810
        in      eax, dx
809
        in      eax, dx
811
        test    eax, FD
810
        test    eax, FD
812
        jz      @f
811
        jz      @f
813
        DEBUGF  1,"full duplex\n"
812
        DEBUGF  1,"full duplex\n"
814
        or      [ebx + device.state], ETH_LINK_FD
813
        or      [ebx + device.state], ETH_LINK_FD
815
       @@:
814
       @@:
816
        test    eax, PS10
815
        test    eax, PS10
817
        jnz     @f
816
        jnz     @f
818
        DEBUGF  1,"100mbit\n"
817
        DEBUGF  1,"100mbit\n"
819
        or      [ebx + device.state], ETH_LINK_100M
818
        or      [ebx + device.state], ETH_LINK_100M
820
        ret
819
        ret
821
       @@:
820
       @@:
822
        DEBUGF  1,"10mbit\n"
821
        DEBUGF  1,"10mbit\n"
823
        or      [ebx + device.state], ETH_LINK_10M
822
        or      [ebx + device.state], ETH_LINK_10M
824
        ret
823
        ret
825
 
824
 
826
  .no_myson_phy:
825
  .no_myson_phy:
827
        DEBUGF  1,"not a myson PHY\n"
826
        DEBUGF  1,"not a myson PHY\n"
828
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
827
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
829
 
828
 
830
;        if (mtdx.PHYType equ=   SeeqPHY) { /* this PHY is SEEQ 80225 */
829
;        if (mtdx.PHYType equ=   SeeqPHY) { /* this PHY is SEEQ 80225 */
831
;            unsigned int data;
830
;            unsigned int data;
832
;
831
;
833
;            data =   mdio_read(dev, mtdx.phys[0], MIIRegister18);
832
;            data =   mdio_read(dev, mtdx.phys[0], MIIRegister18);
834
;            if (data & SPD_DET_100)
833
;            if (data & SPD_DET_100)
835
;                mtdx.line_speed =   2; /* 100M */
834
;                mtdx.line_speed =   2; /* 100M */
836
;            else
835
;            else
837
;                mtdx.line_speed =   1; /* 10M */
836
;                mtdx.line_speed =   1; /* 10M */
838
;            if (data & DPLX_DET_FULL)
837
;            if (data & DPLX_DET_FULL)
839
;                mtdx.duplexmode =   2; /* full duplex mode */
838
;                mtdx.duplexmode =   2; /* full duplex mode */
840
;            else
839
;            else
841
;                mtdx.duplexmode =   1; /* half duplex mode */
840
;                mtdx.duplexmode =   1; /* half duplex mode */
842
;        } else if (mtdx.PHYType equ=   AhdocPHY) {
841
;        } else if (mtdx.PHYType equ=   AhdocPHY) {
843
;            unsigned int data;
842
;            unsigned int data;
844
;
843
;
845
;            data =   mdio_read(dev, mtdx.phys[0], DiagnosticReg);
844
;            data =   mdio_read(dev, mtdx.phys[0], DiagnosticReg);
846
;            if (data & Speed_100)
845
;            if (data & Speed_100)
847
;                mtdx.line_speed =   2; /* 100M */
846
;                mtdx.line_speed =   2; /* 100M */
848
;            else
847
;            else
849
;                mtdx.line_speed =   1; /* 10M */
848
;                mtdx.line_speed =   1; /* 10M */
850
;            if (data & DPLX_FULL)
849
;            if (data & DPLX_FULL)
851
;                mtdx.duplexmode =   2; /* full duplex mode */
850
;                mtdx.duplexmode =   2; /* full duplex mode */
852
;            else
851
;            else
853
;                mtdx.duplexmode =   1; /* half duplex mode */
852
;                mtdx.duplexmode =   1; /* half duplex mode */
854
;        }
853
;        }
855
;        else if (mtdx.PHYType equ=   MarvellPHY) {
854
;        else if (mtdx.PHYType equ=   MarvellPHY) {
856
;            unsigned int data;
855
;            unsigned int data;
857
;
856
;
858
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
857
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
859
;            if (data & Full_Duplex)
858
;            if (data & Full_Duplex)
860
;                mtdx.duplexmode =   2; /* full duplex mode */
859
;                mtdx.duplexmode =   2; /* full duplex mode */
861
;            else
860
;            else
862
;                mtdx.duplexmode =   1; /* half duplex mode */
861
;                mtdx.duplexmode =   1; /* half duplex mode */
863
;            data &=   SpeedMask;
862
;            data &=   SpeedMask;
864
;            if (data equ=   Speed_1000M)
863
;            if (data equ=   Speed_1000M)
865
;                mtdx.line_speed =   3; /* 1000M */
864
;                mtdx.line_speed =   3; /* 1000M */
866
;            else if (data equ=   Speed_100M)
865
;            else if (data equ=   Speed_100M)
867
;                mtdx.line_speed =   2; /* 100M */
866
;                mtdx.line_speed =   2; /* 100M */
868
;            else
867
;            else
869
;                mtdx.line_speed =   1; /* 10M */
868
;                mtdx.line_speed =   1; /* 10M */
870
;        }
869
;        }
871
;        else if (mtdx.PHYType equ=   Myson981) {
870
;        else if (mtdx.PHYType equ=   Myson981) {
872
;            unsigned int data;
871
;            unsigned int data;
873
;
872
;
874
;            data =   mdio_read(dev, mtdx.phys[0], StatusRegister);
873
;            data =   mdio_read(dev, mtdx.phys[0], StatusRegister);
875
;
874
;
876
;            if (data & SPEED100)
875
;            if (data & SPEED100)
877
;                mtdx.line_speed =   2;
876
;                mtdx.line_speed =   2;
878
;            else
877
;            else
879
;                mtdx.line_speed =   1;
878
;                mtdx.line_speed =   1;
880
;
879
;
881
;            if (data & FULLMODE)
880
;            if (data & FULLMODE)
882
;                mtdx.duplexmode =   2;
881
;                mtdx.duplexmode =   2;
883
;            else
882
;            else
884
;                mtdx.duplexmode =   1;
883
;                mtdx.duplexmode =   1;
885
;        }
884
;        }
886
;        else if (mtdx.PHYType equ=   LevelOnePHY) {
885
;        else if (mtdx.PHYType equ=   LevelOnePHY) {
887
;            unsigned int data;
886
;            unsigned int data;
888
;
887
;
889
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
888
;            data =   mdio_read(dev, mtdx.phys[0], SpecificReg);
890
;            if (data & LXT1000_Full)
889
;            if (data & LXT1000_Full)
891
;                mtdx.duplexmode =   2; /* full duplex mode */
890
;                mtdx.duplexmode =   2; /* full duplex mode */
892
;            else
891
;            else
893
;                mtdx.duplexmode =   1; /* half duplex mode */
892
;                mtdx.duplexmode =   1; /* half duplex mode */
894
;            data &=   SpeedMask;
893
;            data &=   SpeedMask;
895
;            if (data equ=   LXT1000_1000M)
894
;            if (data equ=   LXT1000_1000M)
896
;                mtdx.line_speed =   3; /* 1000M */
895
;                mtdx.line_speed =   3; /* 1000M */
897
;            else if (data equ=   LXT1000_100M)
896
;            else if (data equ=   LXT1000_100M)
898
;                mtdx.line_speed =   2; /* 100M */
897
;                mtdx.line_speed =   2; /* 100M */
899
;            else
898
;            else
900
 ;               mtdx.line_speed =   1; /* 10M */
899
 ;               mtdx.line_speed =   1; /* 10M */
901
  ;      }
900
  ;      }
902
 
901
 
903
;        // chage crvalue
902
;        // chage crvalue
904
;        // mtdx.crvalue&equ(~PS10)&(~FD);
903
;        // mtdx.crvalue&equ(~PS10)&(~FD);
905
;        mtdx.crvalue &=   (~PS10) & (~FD) & (~PS1000);
904
;        mtdx.crvalue &=   (~PS10) & (~FD) & (~PS1000);
906
;        if (mtdx.line_speed equ=   1)
905
;        if (mtdx.line_speed equ=   1)
907
;            mtdx.crvalue |=   PS10;
906
;            mtdx.crvalue |=   PS10;
908
;        else if (mtdx.line_speed equ=   3)
907
;        else if (mtdx.line_speed equ=   3)
909
;            mtdx.crvalue |=   PS1000;
908
;            mtdx.crvalue |=   PS1000;
910
;        if (mtdx.duplexmode equ=   2)
909
;        if (mtdx.duplexmode equ=   2)
911
;            mtdx.crvalue |=   FD;
910
;            mtdx.crvalue |=   FD;
912
 
911
 
913
        ret
912
        ret
914
 
913
 
915
 
914
 
916
 
915
 
917
 
916
 
918
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
917
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
919
;;                                         ;;
918
;;                                         ;;
920
;; Transmit                                ;;
919
;; Transmit                                ;;
921
;;                                         ;;
920
;;                                         ;;
922
;; In: buffer pointer in [esp+4]           ;;
921
;; In: buffer pointer in [esp+4]           ;;
923
;;     size of buffer in [esp+8]           ;;
922
;;     size of buffer in [esp+8]           ;;
924
;;     pointer to device structure in ebx  ;;
923
;;     pointer to device structure in ebx  ;;
925
;;                                         ;;
924
;;                                         ;;
926
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
925
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
927
 
926
 
928
proc transmit stdcall bufferptr, buffersize
927
proc transmit stdcall bufferptr, buffersize
929
 
928
 
930
        pushf
929
        pushf
931
        cli
930
        cli
932
 
931
 
933
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
932
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
934
        mov     eax, [bufferptr]
933
        mov     eax, [bufferptr]
935
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
934
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
936
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
935
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
937
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
936
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
938
        [eax+13]:2,[eax+12]:2
937
        [eax+13]:2,[eax+12]:2
939
 
938
 
940
        cmp     [buffersize], 1514
939
        cmp     [buffersize], 1514
941
        ja      .fail
940
        ja      .fail
942
        cmp     [buffersize], 60
941
        cmp     [buffersize], 60
943
        jb      .fail
942
        jb      .fail
944
 
943
 
945
        mov     esi, [ebx + device.cur_tx]
944
        mov     esi, [ebx + device.cur_tx]
946
 
945
 
947
        test    [esi + descriptor.status], TXOWN
946
        test    [esi + descriptor.status], TXOWN
948
        jnz     .fail
947
        jnz     .fail
949
 
948
 
950
        push    [esi + descriptor.next_desc_logical]
949
        push    [esi + descriptor.next_desc_logical]
951
        pop     [ebx + device.cur_tx]
950
        pop     [ebx + device.cur_tx]
952
 
951
 
953
        mov     eax, [bufferptr]
952
        mov     eax, [bufferptr]
954
        mov     [esi + descriptor.skbuff], eax
953
        mov     [esi + descriptor.skbuff], eax
955
        invoke  GetPhysAddr
954
        invoke  GetPhysAddr
956
        mov     [esi + descriptor.buffer], eax
955
        mov     [esi + descriptor.buffer], eax
957
 
956
 
958
        mov     eax, [buffersize]
957
        mov     eax, [buffersize]
959
        mov     ecx, eax
958
        mov     ecx, eax
960
        shl     eax, PKTSShift               ; packet size
959
        shl     eax, PKTSShift               ; packet size
961
        shl     ecx, TBSShift
960
        shl     ecx, TBSShift
962
        or      eax, ecx
961
        or      eax, ecx
963
        or      eax, TXIC + TXLD + TXFD + CRCEnable + PADEnable
962
        or      eax, TXIC + TXLD + TXFD + CRCEnable + PADEnable
964
        mov     [esi + descriptor.control], eax
963
        mov     [esi + descriptor.control], eax
965
        mov     [esi + descriptor.status], TXOWN
964
        mov     [esi + descriptor.status], TXOWN
966
 
965
 
967
; Update stats
966
; Update stats
968
        inc     [ebx + device.packets_tx]
967
        inc     [ebx + device.packets_tx]
969
        mov     eax, [buffersize]
968
        mov     eax, [buffersize]
970
        add     dword[ebx + device.bytes_tx], eax
969
        add     dword[ebx + device.bytes_tx], eax
971
        adc     dword[ebx + device.bytes_tx + 4], 0
970
        adc     dword[ebx + device.bytes_tx + 4], 0
972
 
971
 
973
; TX Poll
972
; TX Poll
974
        set_io  [ebx + device.io_addr], 0
973
        set_io  [ebx + device.io_addr], 0
975
        set_io  [ebx + device.io_addr], TXPDR
974
        set_io  [ebx + device.io_addr], TXPDR
976
        xor     eax, eax
975
        xor     eax, eax
977
        out     dx, eax
976
        out     dx, eax
978
 
977
 
979
        DEBUGF  1,"Transmit OK\n"
978
        DEBUGF  1,"Transmit OK\n"
980
        popf
979
        popf
981
        xor     eax, eax
980
        xor     eax, eax
982
        ret
981
        ret
983
 
982
 
984
  .fail:
983
  .fail:
985
        DEBUGF  2,"Transmit failed\n"
984
        DEBUGF  2,"Transmit failed\n"
986
        invoke  KernelFree, [bufferptr]
985
        invoke  KernelFree, [bufferptr]
987
        popf
986
        popf
988
        or      eax, -1
987
        or      eax, -1
989
        ret
988
        ret
990
 
989
 
991
endp
990
endp
992
 
991
 
993
 
992
 
994
 
993
 
995
align 4
994
align 4
996
read_mac:
995
read_mac:
997
 
996
 
998
        set_io  [ebx + device.io_addr], 0
997
        set_io  [ebx + device.io_addr], 0
999
        set_io  [ebx + device.io_addr], PAR0
998
        set_io  [ebx + device.io_addr], PAR0
1000
        lea     edi, [ebx + device.mac]
999
        lea     edi, [ebx + device.mac]
1001
        insd
1000
        insd
1002
        set_io  [ebx + device.io_addr], PAR1
1001
        set_io  [ebx + device.io_addr], PAR1
1003
        insw
1002
        insw
1004
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1003
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
1005
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1004
        [ebx + device.mac+0]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
1006
 
1005
 
1007
        ret
1006
        ret
1008
 
1007
 
1009
align 4
1008
align 4
1010
write_mac:
1009
write_mac:
1011
 
1010
 
1012
        ret
1011
        ret
1013
 
1012
 
1014
 
1013
 
1015
 
1014
 
1016
;;;;;;;;;;;;;;;;;;;;;;;
1015
;;;;;;;;;;;;;;;;;;;;;;;
1017
;;                   ;;
1016
;;                   ;;
1018
;; Interrupt handler ;;
1017
;; Interrupt handler ;;
1019
;;                   ;;
1018
;;                   ;;
1020
;;;;;;;;;;;;;;;;;;;;;;;
1019
;;;;;;;;;;;;;;;;;;;;;;;
1021
 
1020
 
1022
align 4
1021
align 4
1023
int_handler:
1022
int_handler:
1024
 
1023
 
1025
        push    ebx esi edi
1024
        push    ebx esi edi
1026
 
1025
 
1027
        DEBUGF  1,"INT\n"
1026
        DEBUGF  1,"INT\n"
1028
 
1027
 
1029
; find pointer of device wich made IRQ occur
1028
; find pointer of device wich made IRQ occur
1030
 
1029
 
1031
        mov     ecx, [devices]
1030
        mov     ecx, [devices]
1032
        test    ecx, ecx
1031
        test    ecx, ecx
1033
        jz      .nothing
1032
        jz      .nothing
1034
        mov     esi, device_list
1033
        mov     esi, device_list
1035
  .nextdevice:
1034
  .nextdevice:
1036
        mov     ebx, [esi]
1035
        mov     ebx, [esi]
1037
 
1036
 
1038
        set_io  [ebx + device.io_addr], 0
1037
        set_io  [ebx + device.io_addr], 0
1039
        set_io  [ebx + device.io_addr], ISR
1038
        set_io  [ebx + device.io_addr], ISR
1040
        in      eax, dx
1039
        in      eax, dx
1041
        out     dx, eax                                 ; send it back to ACK
1040
        out     dx, eax                                 ; send it back to ACK
1042
        test    eax, eax
1041
        test    eax, eax
1043
        jnz     .got_it
1042
        jnz     .got_it
1044
  .continue:
1043
  .continue:
1045
        add     esi, 4
1044
        add     esi, 4
1046
        dec     ecx
1045
        dec     ecx
1047
        jnz     .nextdevice
1046
        jnz     .nextdevice
1048
  .nothing:
1047
  .nothing:
1049
        pop     edi esi ebx
1048
        pop     edi esi ebx
1050
        xor     eax, eax
1049
        xor     eax, eax
1051
 
1050
 
1052
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1051
        ret                                             ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
1053
 
1052
 
1054
  .got_it:
1053
  .got_it:
1055
 
1054
 
1056
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
1055
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
1057
 
1056
 
1058
        test    ax, RI  ; receive interrupt
1057
        test    ax, RI  ; receive interrupt
1059
        jz      .no_rx
1058
        jz      .no_rx
1060
        push    ax
1059
        push    ax
1061
  .rx_loop:
1060
  .rx_loop:
1062
        mov     esi, [ebx + device.cur_rx]
1061
        mov     esi, [ebx + device.cur_rx]
1063
        test    [esi + descriptor.status], RXOWN
1062
        test    [esi + descriptor.status], RXOWN
1064
        jnz     .rx_done
1063
        jnz     .rx_done
1065
 
1064
 
1066
        push    ebx
1065
        push    ebx
1067
        push    .rx_complete
1066
        push    .rx_complete
1068
 
1067
 
1069
        mov     ecx, [esi + descriptor.status]
1068
        mov     ecx, [esi + descriptor.status]
1070
        shr     ecx, FLNGShift
1069
        shr     ecx, FLNGShift
1071
        sub     ecx, 4                  ; we dont need CRC
1070
        sub     ecx, 4                  ; we dont need CRC
1072
        push    ecx
1071
        push    ecx
1073
        DEBUGF  1,"Received %u bytes\n", ecx
1072
        DEBUGF  1,"Received %u bytes\n", ecx
1074
 
1073
 
1075
; Update stats
1074
; Update stats
1076
        add     dword[ebx + device.bytes_rx], ecx
1075
        add     dword[ebx + device.bytes_rx], ecx
1077
        adc     dword[ebx + device.bytes_rx + 4], 0
1076
        adc     dword[ebx + device.bytes_rx + 4], 0
1078
        inc     [ebx + device.packets_rx]
1077
        inc     [ebx + device.packets_rx]
1079
 
1078
 
1080
        push    [esi + descriptor.skbuff]
1079
        push    [esi + descriptor.skbuff]
1081
        jmp     [Eth_input]
1080
        jmp     [Eth_input]
1082
 
1081
 
1083
  .rx_complete:
1082
  .rx_complete:
1084
        pop     ebx
1083
        pop     ebx
1085
        mov     esi, [ebx + device.cur_rx]
1084
        mov     esi, [ebx + device.cur_rx]
1086
        mov     [esi + descriptor.control], 1536 shl RBSShift
1085
        mov     [esi + descriptor.control], 1536 shl RBSShift
1087
        push    esi
1086
        push    esi
1088
        invoke  KernelAlloc, 1536
1087
        invoke  KernelAlloc, 1536
1089
        pop     esi
1088
        pop     esi
1090
        mov     [esi + descriptor.skbuff], eax
1089
        mov     [esi + descriptor.skbuff], eax
1091
        invoke  GetPgAddr
1090
        invoke  GetPgAddr
1092
        mov     [esi + descriptor.buffer], eax
1091
        mov     [esi + descriptor.buffer], eax
1093
        mov     [esi + descriptor.status], RXOWN
1092
        mov     [esi + descriptor.status], RXOWN
1094
 
1093
 
1095
        push    [esi + descriptor.next_desc_logical]
1094
        push    [esi + descriptor.next_desc_logical]
1096
        pop     [ebx + device.cur_rx]
1095
        pop     [ebx + device.cur_rx]
1097
 
1096
 
1098
        jmp     .rx_loop
1097
        jmp     .rx_loop
1099
 
1098
 
1100
  .rx_done:
1099
  .rx_done:
1101
        DEBUGF  1,"RX done\n"
1100
        DEBUGF  1,"RX done\n"
1102
 
1101
 
1103
; Restart Rx engine if stopped.
1102
; Restart Rx engine if stopped.
1104
        set_io  [ebx + device.io_addr], 0
1103
        set_io  [ebx + device.io_addr], 0
1105
        set_io  [ebx + device.io_addr], RXPDR
1104
        set_io  [ebx + device.io_addr], RXPDR
1106
        xor     eax, eax
1105
        xor     eax, eax
1107
        out     dx, eax
1106
        out     dx, eax
1108
 
1107
 
1109
        pop     ax
1108
        pop     ax
1110
  .no_rx:
1109
  .no_rx:
1111
 
1110
 
1112
        test    ax, TI ; transmit interrupt
1111
        test    ax, TI ; transmit interrupt
1113
        jz      .no_tx
1112
        jz      .no_tx
1114
        DEBUGF  1,"TX\n"
1113
        DEBUGF  1,"TX\n"
1115
        push    ax
1114
        push    ax
1116
        lea     esi, [ebx + device.tx_desc]
1115
        lea     esi, [ebx + device.tx_desc]
1117
        mov     ecx, NUM_TX_DESC
1116
        mov     ecx, NUM_TX_DESC
1118
  .tx_loop:
1117
  .tx_loop:
1119
        test    [esi + descriptor.status], TXOWN
1118
        test    [esi + descriptor.status], TXOWN
1120
        jnz     .skip_this_one
1119
        jnz     .skip_this_one
1121
        mov     eax, [esi + descriptor.skbuff]
1120
        mov     eax, [esi + descriptor.skbuff]
1122
        test    eax, eax
1121
        test    eax, eax
1123
        je      .skip_this_one
1122
        je      .skip_this_one
1124
        mov     [esi + descriptor.skbuff], 0
1123
        mov     [esi + descriptor.skbuff], 0
1125
        DEBUGF  1,"freeing buffer: 0x%x\n", eax
1124
        DEBUGF  1,"freeing buffer: 0x%x\n", eax
1126
        invoke  KernelFree, eax
1125
        invoke  KernelFree, eax
1127
  .skip_this_one:
1126
  .skip_this_one:
1128
        mov     esi, [esi + descriptor.next_desc_logical]
1127
        mov     esi, [esi + descriptor.next_desc_logical]
1129
        loop    .tx_loop
1128
        loop    .tx_loop
1130
        pop     ax
1129
        pop     ax
1131
  .no_tx:
1130
  .no_tx:
1132
 
1131
 
1133
        test    ax, LSCStatus
1132
        test    ax, LSCStatus
1134
        jz      .no_link_change
1133
        jz      .no_link_change
1135
        push    ax
1134
        push    ax
1136
        call    getlinkstatus
1135
        call    getlinkstatus
1137
        pop     ax
1136
        pop     ax
1138
  .no_link_change:
1137
  .no_link_change:
1139
 
1138
 
1140
;        test    ax, TBU
1139
;        test    ax, TBU
1141
;        jz      .no_tbu
1140
;        jz      .no_tbu
1142
;        DEBUGF  2,"Transmit buffer unavailable!\n"
1141
;        DEBUGF  2,"Transmit buffer unavailable!\n"
1143
;  .no_tbu:
1142
;  .no_tbu:
1144
 
1143
 
1145
  .fail:
1144
  .fail:
1146
        pop     edi esi ebx
1145
        pop     edi esi ebx
1147
        xor     eax, eax
1146
        xor     eax, eax
1148
        inc     eax
1147
        inc     eax
1149
 
1148
 
1150
        ret
1149
        ret
1151
 
1150
 
1152
 
1151
 
1153
; End of code
1152
; End of code
1154
 
1153
 
1155
 
1154
 
1156
data fixups
1155
data fixups
1157
end data
1156
end data
1158
 
1157
 
1159
include '../peimport.inc'
1158
include '../peimport.inc'
1160
 
1159
 
1161
my_service      db 'mtd80x',0                   ; max 16 chars include zero
1160
my_service      db 'mtd80x',0                   ; max 16 chars include zero
1162
 
1161
 
1163
sz_mtd800       db "Myson MTD800", 0
1162
sz_mtd800       db "Myson MTD800", 0
1164
sz_mtd803       db "Surecom EP-320X", 0
1163
sz_mtd803       db "Surecom EP-320X", 0
1165
sz_mtd891       db "Myson MTD891", 0
1164
sz_mtd891       db "Myson MTD891", 0
1166
 
1165
 
1167
 
1166
 
1168
include_debug_strings                           ; All data wich FDO uses will be included here
1167
include_debug_strings                           ; All data wich FDO uses will be included here
1169
 
1168
 
1170
align 4
1169
align 4
1171
devices       dd 0
1170
devices       dd 0
1172
device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling
1171
device_list   rd MAX_DEVICES                    ; This list contains all pointers to device structures the driver is handling