Subversion Repositories Kolibri OS

Rev

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

Rev 5363 Rev 5522
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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
;;  R6040 driver for KolibriOS                                     ;;
6
;;  R6040 driver for KolibriOS                                     ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  based on R6040.c from linux                                    ;;
8
;;  based on R6040.c from linux                                    ;;
9
;;                                                                 ;;
9
;;                                                                 ;;
10
;;    Written by Asper (asper.85@mail.ru)                          ;;
10
;;    Written by Asper (asper.85@mail.ru)                          ;;
11
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
11
;;            and hidnplayr (hidnplayr@gmail.com)                  ;;
12
;;                                                                 ;;
12
;;                                                                 ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
13
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;             Version 2, June 1991                                ;;
14
;;             Version 2, June 1991                                ;;
15
;;                                                                 ;;
15
;;                                                                 ;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
 
17
 
18
format PE DLL native
18
format PE DLL native
19
entry START
19
entry START
20
 
20
 
21
        CURRENT_API             = 0x0200
21
        CURRENT_API             = 0x0200
22
        COMPATIBLE_API          = 0x0100
22
        COMPATIBLE_API          = 0x0100
23
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
23
        API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
24
 
24
 
25
        MAX_DEVICES             = 16
25
        MAX_DEVICES             = 16
26
 
26
 
27
        __DEBUG__               = 1
27
        __DEBUG__               = 1
28
        __DEBUG_LEVEL__         = 2
28
        __DEBUG_LEVEL__         = 2
29
 
29
 
30
        W_MAX_TIMEOUT           = 0x0FFF        ; max time out delay time
30
        W_MAX_TIMEOUT           = 0x0FFF        ; max time out delay time
31
 
31
 
32
        TX_TIMEOUT              = 6000          ; Time before concluding the transmitter is hung, in ms
32
        TX_TIMEOUT              = 6000          ; Time before concluding the transmitter is hung, in ms
33
 
33
 
34
        TX_RING_SIZE            = 4             ; RING sizes must be a power of 2
34
        TX_RING_SIZE            = 4             ; RING sizes must be a power of 2
35
        RX_RING_SIZE            = 4
35
        RX_RING_SIZE            = 4
36
 
36
 
37
        RX_BUF_LEN_IDX          = 3             ; 0==8K, 1==16K, 2==32K, 3==64K
37
        RX_BUF_LEN_IDX          = 3             ; 0==8K, 1==16K, 2==32K, 3==64K
38
 
38
 
39
; Threshold is bytes transferred to chip before transmission starts.
39
; Threshold is bytes transferred to chip before transmission starts.
40
 
40
 
41
        TX_FIFO_THRESH          = 256           ; In bytes, rounded down to 32 byte units.
41
        TX_FIFO_THRESH          = 256           ; In bytes, rounded down to 32 byte units.
42
 
42
 
43
; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
43
; The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024.
44
 
44
 
45
        RX_FIFO_THRESH          = 4             ; Rx buffer level before first PCI xfer.
45
        RX_FIFO_THRESH          = 4             ; Rx buffer level before first PCI xfer.
46
        RX_DMA_BURST            = 4             ; Maximum PCI burst, '4' is 256 bytes
46
        RX_DMA_BURST            = 4             ; Maximum PCI burst, '4' is 256 bytes
47
        TX_DMA_BURST            = 4
47
        TX_DMA_BURST            = 4
48
 
48
 
49
section '.flat' readable writable executable
49
section '.flat' readable writable executable
50
 
50
 
51
include '../proc32.inc'
51
include '../proc32.inc'
52
include '../struct.inc'
52
include '../struct.inc'
53
include '../macros.inc'
53
include '../macros.inc'
54
include '../fdo.inc'
54
include '../fdo.inc'
55
include '../netdrv.inc'
55
include '../netdrv.inc'
56
 
56
 
57
; Operational parameters that usually are not changed.
57
; Operational parameters that usually are not changed.
58
 
58
 
59
PHY1_ADDR       = 1                     ; For MAC1
59
PHY1_ADDR       = 1                     ; For MAC1
60
PHY2_ADDR       = 3                     ; For MAC2
60
PHY2_ADDR       = 3                     ; For MAC2
61
PHY_MODE        = 0x3100                ; PHY CHIP Register 0
61
PHY_MODE        = 0x3100                ; PHY CHIP Register 0
62
PHY_CAP         = 0x01E1                ; PHY CHIP Register 4
62
PHY_CAP         = 0x01E1                ; PHY CHIP Register 4
63
 
63
 
64
;**************************************************************************
64
;**************************************************************************
65
; RDC R6040 Register Definitions
65
; RDC R6040 Register Definitions
66
;**************************************************************************
66
;**************************************************************************
67
 
67
 
68
MCR0            = 0x00                  ; Control register 0
68
MCR0            = 0x00                  ; Control register 0
69
MCR0_RCVEN      = 0x0002                ; Receive enable
69
MCR0_RCVEN      = 0x0002                ; Receive enable
70
MCR0_PROMISC    = 0x0020                ; Promiscuous mode
70
MCR0_PROMISC    = 0x0020                ; Promiscuous mode
71
MCR0_HASH_EN    = 0x0100                ; Enable multicast hash table function
71
MCR0_HASH_EN    = 0x0100                ; Enable multicast hash table function
72
MCR0_XMTEN      = 0x1000                ; Transmission enable
72
MCR0_XMTEN      = 0x1000                ; Transmission enable
73
MCR0_FD         = 0x8000                ; Full/Half Duplex mode
73
MCR0_FD         = 0x8000                ; Full/Half Duplex mode
74
 
74
 
75
MCR1            = 0x01                  ; Control register 1
75
MCR1            = 0x01                  ; Control register 1
76
MAC_RST         = 0x0001                ; Reset the MAC
76
MAC_RST         = 0x0001                ; Reset the MAC
77
 
77
 
78
MBCR            = 0x08                  ; Bus control
78
MBCR            = 0x08                  ; Bus control
79
MT_ICR          = 0x0C                  ; TX interrupt control
79
MT_ICR          = 0x0C                  ; TX interrupt control
80
MR_ICR          = 0x10                  ; RX interrupt control
80
MR_ICR          = 0x10                  ; RX interrupt control
81
MTPR            = 0x14                  ; TX poll command register
81
MTPR            = 0x14                  ; TX poll command register
82
MR_BSR          = 0x18                  ; RX buffer size
82
MR_BSR          = 0x18                  ; RX buffer size
83
MR_DCR          = 0x1A                  ; RX descriptor control
83
MR_DCR          = 0x1A                  ; RX descriptor control
84
MLSR            = 0x1C                  ; Last status
84
MLSR            = 0x1C                  ; Last status
85
 
85
 
86
MMDIO           = 0x20                  ; MDIO control register
86
MMDIO           = 0x20                  ; MDIO control register
87
MDIO_WRITE      = 0x4000                ; MDIO write
87
MDIO_WRITE      = 0x4000                ; MDIO write
88
MDIO_READ       = 0x2000                ; MDIO read
88
MDIO_READ       = 0x2000                ; MDIO read
89
MMRD            = 0x24                  ; MDIO read data register
89
MMRD            = 0x24                  ; MDIO read data register
90
MMWD            = 0x28                  ; MDIO write data register
90
MMWD            = 0x28                  ; MDIO write data register
91
 
91
 
92
MTD_SA0         = 0x2C                  ; TX descriptor start address 0
92
MTD_SA0         = 0x2C                  ; TX descriptor start address 0
93
MTD_SA1         = 0x30                  ; TX descriptor start address 1
93
MTD_SA1         = 0x30                  ; TX descriptor start address 1
94
MRD_SA0         = 0x34                  ; RX descriptor start address 0
94
MRD_SA0         = 0x34                  ; RX descriptor start address 0
95
MRD_SA1         = 0x38                  ; RX descriptor start address 1
95
MRD_SA1         = 0x38                  ; RX descriptor start address 1
96
 
96
 
97
MISR            = 0x3C                  ; Status register
97
MISR            = 0x3C                  ; Status register
98
MIER            = 0x40                  ; INT enable register
98
MIER            = 0x40                  ; INT enable register
99
MSK_INT         = 0x0000                ; Mask off interrupts
99
MSK_INT         = 0x0000                ; Mask off interrupts
100
RX_FINISH       = 0x0001                ; RX finished
100
RX_FINISH       = 0x0001                ; RX finished
101
RX_NO_DESC      = 0x0002                ; No RX descriptor available
101
RX_NO_DESC      = 0x0002                ; No RX descriptor available
102
RX_FIFO_FULL    = 0x0004                ; RX FIFO full
102
RX_FIFO_FULL    = 0x0004                ; RX FIFO full
103
RX_EARLY        = 0x0008                ; RX early
103
RX_EARLY        = 0x0008                ; RX early
104
TX_FINISH       = 0x0010                ; TX finished
104
TX_FINISH       = 0x0010                ; TX finished
105
TX_EARLY        = 0x0080                ; TX early
105
TX_EARLY        = 0x0080                ; TX early
106
EVENT_OVRFL     = 0x0100                ; Event counter overflow
106
EVENT_OVRFL     = 0x0100                ; Event counter overflow
107
LINK_CHANGED    = 0x0200                ; PHY link changed
107
LINK_CHANGED    = 0x0200                ; PHY link changed
108
 
108
 
109
ME_CISR         = 0x44                  ; Event counter INT status
109
ME_CISR         = 0x44                  ; Event counter INT status
110
ME_CIER         = 0x48                  ; Event counter INT enable
110
ME_CIER         = 0x48                  ; Event counter INT enable
111
MR_CNT          = 0x50                  ; Successfully received packet counter
111
MR_CNT          = 0x50                  ; Successfully received packet counter
112
ME_CNT0         = 0x52                  ; Event counter 0
112
ME_CNT0         = 0x52                  ; Event counter 0
113
ME_CNT1         = 0x54                  ; Event counter 1
113
ME_CNT1         = 0x54                  ; Event counter 1
114
ME_CNT2         = 0x56                  ; Event counter 2
114
ME_CNT2         = 0x56                  ; Event counter 2
115
ME_CNT3         = 0x58                  ; Event counter 3
115
ME_CNT3         = 0x58                  ; Event counter 3
116
MT_CNT          = 0x5A                  ; Successfully transmit packet counter
116
MT_CNT          = 0x5A                  ; Successfully transmit packet counter
117
ME_CNT4         = 0x5C                  ; Event counter 4
117
ME_CNT4         = 0x5C                  ; Event counter 4
118
MP_CNT          = 0x5E                  ; Pause frame counter register
118
MP_CNT          = 0x5E                  ; Pause frame counter register
119
MAR0            = 0x60                  ; Hash table 0
119
MAR0            = 0x60                  ; Hash table 0
120
MAR1            = 0x62                  ; Hash table 1
120
MAR1            = 0x62                  ; Hash table 1
121
MAR2            = 0x64                  ; Hash table 2
121
MAR2            = 0x64                  ; Hash table 2
122
MAR3            = 0x66                  ; Hash table 3
122
MAR3            = 0x66                  ; Hash table 3
123
MID_0L          = 0x68                  ; Multicast address MID0 Low
123
MID_0L          = 0x68                  ; Multicast address MID0 Low
124
MID_0M          = 0x6A                  ; Multicast address MID0 Medium
124
MID_0M          = 0x6A                  ; Multicast address MID0 Medium
125
MID_0H          = 0x6C                  ; Multicast address MID0 High
125
MID_0H          = 0x6C                  ; Multicast address MID0 High
126
MID_1L          = 0x70                  ; MID1 Low
126
MID_1L          = 0x70                  ; MID1 Low
127
MID_1M          = 0x72                  ; MID1 Medium
127
MID_1M          = 0x72                  ; MID1 Medium
128
MID_1H          = 0x74                  ; MID1 High
128
MID_1H          = 0x74                  ; MID1 High
129
MID_2L          = 0x78                  ; MID2 Low
129
MID_2L          = 0x78                  ; MID2 Low
130
MID_2M          = 0x7A                  ; MID2 Medium
130
MID_2M          = 0x7A                  ; MID2 Medium
131
MID_2H          = 0x7C                  ; MID2 High
131
MID_2H          = 0x7C                  ; MID2 High
132
MID_3L          = 0x80                  ; MID3 Low
132
MID_3L          = 0x80                  ; MID3 Low
133
MID_3M          = 0x82                  ; MID3 Medium
133
MID_3M          = 0x82                  ; MID3 Medium
134
MID_3H          = 0x84                  ; MID3 High
134
MID_3H          = 0x84                  ; MID3 High
135
PHY_CC          = 0x88                  ; PHY status change configuration register
135
PHY_CC          = 0x88                  ; PHY status change configuration register
136
PHY_ST          = 0x8A                  ; PHY status register
136
PHY_ST          = 0x8A                  ; PHY status register
137
MAC_SM          = 0xAC                  ; MAC status machine
137
MAC_SM          = 0xAC                  ; MAC status machine
138
MAC_ID          = 0xBE                  ; Identifier register
138
MAC_ID          = 0xBE                  ; Identifier register
139
 
139
 
140
MAX_BUF_SIZE    = 0x600                 ; 1536
140
MAX_BUF_SIZE    = 1514
141
 
141
 
142
MBCR_DEFAULT    = 0x012A                ; MAC Bus Control Register
142
MBCR_DEFAULT    = 0x012A                ; MAC Bus Control Register
143
MCAST_MAX       = 3                     ; Max number multicast addresses to filter
143
MCAST_MAX       = 3                     ; Max number multicast addresses to filter
144
 
144
 
145
;Descriptor status
145
;Descriptor status
146
DSC_OWNER_MAC   = 0x8000                ; MAC is the owner of this descriptor
146
DSC_OWNER_MAC   = 0x8000                ; MAC is the owner of this descriptor
147
DSC_RX_OK       = 0x4000                ; RX was successfull
147
DSC_RX_OK       = 0x4000                ; RX was successfull
148
DSC_RX_ERR      = 0x0800                ; RX PHY error
148
DSC_RX_ERR      = 0x0800                ; RX PHY error
149
DSC_RX_ERR_DRI  = 0x0400                ; RX dribble packet
149
DSC_RX_ERR_DRI  = 0x0400                ; RX dribble packet
150
DSC_RX_ERR_BUF  = 0x0200                ; RX length exceeds buffer size
150
DSC_RX_ERR_BUF  = 0x0200                ; RX length exceeds buffer size
151
DSC_RX_ERR_LONG = 0x0100                ; RX length > maximum packet length
151
DSC_RX_ERR_LONG = 0x0100                ; RX length > maximum packet length
152
DSC_RX_ERR_RUNT = 0x0080                ; RX packet length < 64 byte
152
DSC_RX_ERR_RUNT = 0x0080                ; RX packet length < 64 byte
153
DSC_RX_ERR_CRC  = 0x0040                ; RX CRC error
153
DSC_RX_ERR_CRC  = 0x0040                ; RX CRC error
154
DSC_RX_BCAST    = 0x0020                ; RX broadcast (no error)
154
DSC_RX_BCAST    = 0x0020                ; RX broadcast (no error)
155
DSC_RX_MCAST    = 0x0010                ; RX multicast (no error)
155
DSC_RX_MCAST    = 0x0010                ; RX multicast (no error)
156
DSC_RX_MCH_HIT  = 0x0008                ; RX multicast hit in hash table (no error)
156
DSC_RX_MCH_HIT  = 0x0008                ; RX multicast hit in hash table (no error)
157
DSC_RX_MIDH_HIT = 0x0004                ; RX MID table hit (no error)
157
DSC_RX_MIDH_HIT = 0x0004                ; RX MID table hit (no error)
158
DSC_RX_IDX_MID_MASK  = 3                ; RX mask for the index of matched MIDx
158
DSC_RX_IDX_MID_MASK  = 3                ; RX mask for the index of matched MIDx
159
 
159
 
160
;PHY settings
160
;PHY settings
161
ICPLUS_PHY_ID   = 0x0243
161
ICPLUS_PHY_ID   = 0x0243
162
 
162
 
163
RX_INTS         = RX_FIFO_FULL or RX_NO_DESC or RX_FINISH
163
RX_INTS         = RX_FIFO_FULL or RX_NO_DESC or RX_FINISH
164
TX_INTS         = TX_FINISH
164
TX_INTS         = TX_FINISH
165
INT_MASK        = RX_INTS or TX_INTS
165
INT_MASK        = RX_INTS or TX_INTS
166
 
166
 
167
RX_BUF_LEN      equ (8192 << RX_BUF_LEN_IDX)    ; Size of the in-memory receive ring.
167
RX_BUF_LEN      equ (8192 << RX_BUF_LEN_IDX)    ; Size of the in-memory receive ring.
168
 
168
 
169
IO_SIZE         = 256       ; RDC MAC I/O Size
169
IO_SIZE         = 256       ; RDC MAC I/O Size
170
MAX_MAC         = 2         ; MAX RDC MAC
170
MAX_MAC         = 2         ; MAX RDC MAC
171
 
171
 
172
struct  x_head
172
struct  x_head
173
 
173
 
174
        status          dw ?   ;0-1
174
        status          dw ?   ;0-1
175
        len             dw ?   ;2-3
175
        len             dw ?   ;2-3
176
        buf             dd ?   ;4-7
176
        buf             dd ?   ;4-7
177
        ndesc           dd ?   ;8-B
177
        ndesc           dd ?   ;8-B
178
        rev1            dd ?   ;C-F
178
        rev1            dd ?   ;C-F
179
        vbufp           dd ?   ;10-13
179
        vbufp           dd ?   ;10-13
180
        vndescp         dd ?   ;14-17
180
        vndescp         dd ?   ;14-17
181
        skb_ptr         dd ?   ;18-1B
181
        skb_ptr         dd ?   ;18-1B
182
        rev2            dd ?   ;1C-1F
182
        rev2            dd ?   ;1C-1F
183
 
183
 
184
ends
184
ends
185
 
185
 
186
 
186
 
187
struct  device          ETH_DEVICE
187
struct  device          ETH_DEVICE
188
 
188
 
189
        io_addr         dd ?
189
        io_addr         dd ?
190
        pci_bus         dd ?
190
        pci_bus         dd ?
191
        pci_dev         dd ?
191
        pci_dev         dd ?
192
        irq_line        db ?
192
        irq_line        db ?
193
                        rb 3    ; align 4
193
                        rb 3    ; align 4
194
 
194
 
195
        cur_rx          dw ?
195
        cur_rx          dw ?
196
        cur_tx          dw ?
196
        cur_tx          dw ?
197
        last_tx         dw ?
197
        last_tx         dw ?
198
        phy_addr        dd ?
198
        phy_addr        dd ?
199
        phy_mode        dw ?
199
        phy_mode        dw ?
200
        mcr0            dw ?
200
        mcr0            dw ?
201
        mcr1            dw ?
201
        mcr1            dw ?
202
        switch_sig      dw ?
202
        switch_sig      dw ?
203
 
203
 
204
        rb 0x100 - ($ and 0xff) ; align 256
204
        rb 0x100 - ($ and 0xff) ; align 256
205
        tx_ring         rb ((TX_RING_SIZE*sizeof.x_head+32) and 0xfffffff0)
205
        tx_ring         rb ((TX_RING_SIZE*sizeof.x_head+32) and 0xfffffff0)
206
        rx_ring         rb ((RX_RING_SIZE*sizeof.x_head+32) and 0xfffffff0)
206
        rx_ring         rb ((RX_RING_SIZE*sizeof.x_head+32) and 0xfffffff0)
207
 
207
 
208
ends
208
ends
209
 
209
 
210
 
210
 
211
 
211
 
212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213
;;                        ;;
213
;;                        ;;
214
;; proc START             ;;
214
;; proc START             ;;
215
;;                        ;;
215
;;                        ;;
216
;; (standard driver proc) ;;
216
;; (standard driver proc) ;;
217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
218
 
218
 
219
proc START c, reason:dword, cmdline:dword
219
proc START c, reason:dword, cmdline:dword
220
 
220
 
221
        cmp     [reason], DRV_ENTRY
221
        cmp     [reason], DRV_ENTRY
222
        jne     .fail
222
        jne     .fail
223
 
223
 
224
        DEBUGF  2,"Loading driver\n"
224
        DEBUGF  2,"Loading driver\n"
225
        invoke  RegService, my_service, service_proc
225
        invoke  RegService, my_service, service_proc
226
        ret
226
        ret
227
 
227
 
228
  .fail:
228
  .fail:
229
        xor     eax, eax
229
        xor     eax, eax
230
        ret
230
        ret
231
 
231
 
232
endp
232
endp
233
 
233
 
234
 
234
 
235
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
235
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
236
;;                        ;;
236
;;                        ;;
237
;; proc SERVICE_PROC      ;;
237
;; proc SERVICE_PROC      ;;
238
;;                        ;;
238
;;                        ;;
239
;; (standard driver proc) ;;
239
;; (standard driver proc) ;;
240
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
240
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
241
 
241
 
242
proc service_proc stdcall, ioctl:dword
242
proc service_proc stdcall, ioctl:dword
243
 
243
 
244
        mov     edx, [ioctl]
244
        mov     edx, [ioctl]
245
        mov     eax, [edx + IOCTL.io_code]
245
        mov     eax, [edx + IOCTL.io_code]
246
 
246
 
247
;------------------------------------------------------
247
;------------------------------------------------------
248
 
248
 
249
        cmp     eax, 0 ;SRV_GETVERSION
249
        cmp     eax, 0 ;SRV_GETVERSION
250
        jne     @F
250
        jne     @F
251
 
251
 
252
        cmp     [edx + IOCTL.out_size], 4
252
        cmp     [edx + IOCTL.out_size], 4
253
        jb      .fail
253
        jb      .fail
254
        mov     eax, [edx + IOCTL.output]
254
        mov     eax, [edx + IOCTL.output]
255
        mov     [eax], dword API_VERSION
255
        mov     [eax], dword API_VERSION
256
 
256
 
257
        xor     eax, eax
257
        xor     eax, eax
258
        ret
258
        ret
259
 
259
 
260
;------------------------------------------------------
260
;------------------------------------------------------
261
  @@:
261
  @@:
262
        cmp     eax, 1 ;SRV_HOOK
262
        cmp     eax, 1 ;SRV_HOOK
263
        jne     .fail
263
        jne     .fail
264
 
264
 
265
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
265
        cmp     [edx + IOCTL.inp_size], 3               ; Data input must be at least 3 bytes
266
        jb      .fail
266
        jb      .fail
267
 
267
 
268
        mov     eax, [edx + IOCTL.input]
268
        mov     eax, [edx + IOCTL.input]
269
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
269
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
270
        jne     .fail                                   ; other types arent supported for this card yet
270
        jne     .fail                                   ; other types arent supported for this card yet
271
 
271
 
272
; check if the device is already listed
272
; check if the device is already listed
273
 
273
 
274
        mov     esi, device_list
274
        mov     esi, device_list
275
        mov     ecx, [devices]
275
        mov     ecx, [devices]
276
        test    ecx, ecx
276
        test    ecx, ecx
277
        jz      .firstdevice
277
        jz      .firstdevice
278
 
278
 
279
;        mov     eax, [edx + IOCTL.input]               ; get the pci bus and device numbers
279
;        mov     eax, [edx + IOCTL.input]               ; get the pci bus and device numbers
280
        mov     ax , [eax+1]                            ;
280
        mov     ax , [eax+1]                            ;
281
  .nextdevice:
281
  .nextdevice:
282
        mov     ebx, [esi]
282
        mov     ebx, [esi]
283
        cmp     al, byte[ebx + device.pci_bus]
283
        cmp     al, byte[ebx + device.pci_bus]
284
        jne     @f
284
        jne     @f
285
        cmp     ah, byte[ebx + device.pci_dev]
285
        cmp     ah, byte[ebx + device.pci_dev]
286
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
286
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
287
       @@:
287
       @@:
288
        add     esi, 4
288
        add     esi, 4
289
        loop    .nextdevice
289
        loop    .nextdevice
290
 
290
 
291
 
291
 
292
; This device doesnt have its own eth_device structure yet, lets create one
292
; This device doesnt have its own eth_device structure yet, lets create one
293
  .firstdevice:
293
  .firstdevice:
294
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
294
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
295
        jae     .fail
295
        jae     .fail
296
 
296
 
297
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
297
        allocate_and_clear ebx, sizeof.device, .fail    ; Allocate the buffer for device structure
298
 
298
 
299
; Fill in the direct call addresses into the struct
299
; Fill in the direct call addresses into the struct
300
 
300
 
301
        mov     [ebx + device.reset], reset
301
        mov     [ebx + device.reset], reset
302
        mov     [ebx + device.transmit], transmit
302
        mov     [ebx + device.transmit], transmit
303
        mov     [ebx + device.unload], unload
303
        mov     [ebx + device.unload], unload
304
        mov     [ebx + device.name], my_service
304
        mov     [ebx + device.name], my_service
305
 
305
 
306
; save the pci bus and device numbers
306
; save the pci bus and device numbers
307
 
307
 
308
        mov     eax, [edx + IOCTL.input]
308
        mov     eax, [edx + IOCTL.input]
309
        movzx   ecx, byte[eax+1]
309
        movzx   ecx, byte[eax+1]
310
        mov     [ebx + device.pci_bus], ecx
310
        mov     [ebx + device.pci_bus], ecx
311
        movzx   ecx, byte[eax+2]
311
        movzx   ecx, byte[eax+2]
312
        mov     [ebx + device.pci_dev], ecx
312
        mov     [ebx + device.pci_dev], ecx
313
 
313
 
314
; Now, it's time to find the base io addres of the PCI device
314
; Now, it's time to find the base io addres of the PCI device
315
 
315
 
316
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
316
        stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
317
        mov     [ebx + device.io_addr], eax
317
        mov     [ebx + device.io_addr], eax
318
 
318
 
319
; We've found the io address, find IRQ now
319
; We've found the io address, find IRQ now
320
 
320
 
321
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
321
        invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
322
        mov     [ebx + device.irq_line], al
322
        mov     [ebx + device.irq_line], al
323
 
323
 
324
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
324
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
325
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
325
        [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:8
326
 
326
 
327
; Ok, the eth_device structure is ready, let's probe the device
327
; Ok, the eth_device structure is ready, let's probe the device
328
 
328
 
329
        mov     eax, [devices]                                          ; Add the device structure to our device list
329
        mov     eax, [devices]                                          ; Add the device structure to our device list
330
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
330
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
331
        inc     [devices]                                               ;
331
        inc     [devices]                                               ;
332
 
332
 
333
        call    probe                                                   ; this function will output in eax
333
        call    probe                                                   ; this function will output in eax
334
        test    eax, eax
334
        test    eax, eax
335
        jnz     .err2
335
        jnz     .err2
336
 
336
 
337
        DEBUGF  2,"Initialised OK\n"
337
        DEBUGF  2,"Initialised OK\n"
338
 
338
 
339
        mov     [ebx + device.type], NET_TYPE_ETH
339
        mov     [ebx + device.type], NET_TYPE_ETH
340
        invoke  NetRegDev
340
        invoke  NetRegDev
341
 
341
 
342
        cmp     eax, -1
342
        cmp     eax, -1
343
        je      .destroy
343
        je      .destroy
344
 
344
 
345
        ret
345
        ret
346
 
346
 
347
; If the device was already loaded, find the device number and return it in eax
347
; If the device was already loaded, find the device number and return it in eax
348
 
348
 
349
  .find_devicenum:
349
  .find_devicenum:
350
        DEBUGF  2,"Trying to find device number of already registered device\n"
350
        DEBUGF  2,"Trying to find device number of already registered device\n"
351
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
351
        invoke  NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
352
                                                                        ; into a device number in edi
352
                                                                        ; into a device number in edi
353
        mov     eax, edi                                                ; Application wants it in eax instead
353
        mov     eax, edi                                                ; Application wants it in eax instead
354
        DEBUGF  2,"Kernel says: %u\n", eax
354
        DEBUGF  2,"Kernel says: %u\n", eax
355
        ret
355
        ret
356
 
356
 
357
; If an error occured, remove all allocated data and exit (returning -1 in eax)
357
; If an error occured, remove all allocated data and exit (returning -1 in eax)
358
 
358
 
359
  .destroy:
359
  .destroy:
360
        ; todo: reset device into virgin state
360
        ; todo: reset device into virgin state
361
 
361
 
362
  .err2:
362
  .err2:
363
        dec     [devices]
363
        dec     [devices]
364
  .err:
364
  .err:
365
        invoke  KernelFree, ebx
365
        invoke  KernelFree, ebx
366
  .fail:
366
  .fail:
367
        DEBUGF  2, "Failed to load\n"
367
        DEBUGF  2, "Failed to load\n"
368
        or      eax, -1
368
        or      eax, -1
369
        ret
369
        ret
370
 
370
 
371
;------------------------------------------------------
371
;------------------------------------------------------
372
endp
372
endp
373
 
373
 
374
 
374
 
375
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
375
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
376
;;                                                                        ;;
376
;;                                                                        ;;
377
;;        Actual Hardware dependent code starts here                      ;;
377
;;        Actual Hardware dependent code starts here                      ;;
378
;;                                                                        ;;
378
;;                                                                        ;;
379
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
379
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
380
 
380
 
381
 
381
 
382
;mdio_read:
382
;mdio_read:
383
;        stdcall phy_read, [ebx + device.io_addr], [ebx + device.phy_addr], ecx
383
;        stdcall phy_read, [ebx + device.io_addr], [ebx + device.phy_addr], ecx
384
 
384
 
385
;        ret
385
;        ret
386
 
386
 
387
;mdio_write:
387
;mdio_write:
388
;        stdcall phy_write, [ebx + device.io_addr], [ebx + device.phy_addr], ecx, eax
388
;        stdcall phy_write, [ebx + device.io_addr], [ebx + device.phy_addr], ecx, eax
389
 
389
 
390
;        ret
390
;        ret
391
 
391
 
392
 
392
 
393
align 4
393
align 4
394
unload:
394
unload:
395
        ; TODO: (in this particular order)
395
        ; TODO: (in this particular order)
396
        ;
396
        ;
397
        ; - Stop the device
397
        ; - Stop the device
398
        ; - Detach int handler
398
        ; - Detach int handler
399
        ; - Remove device from local list (RTL8139_LIST)
399
        ; - Remove device from local list (device_list)
400
        ; - call unregister function in kernel
400
        ; - call unregister function in kernel
401
        ; - Remove all allocated structures and buffers the card used
401
        ; - Remove all allocated structures and buffers the card used
402
 
402
 
403
        or      eax,-1
403
        or      eax, -1
404
 
-
 
405
ret
404
        ret
406
 
405
 
407
 
406
 
408
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
407
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
409
;;
408
;;
410
;;  probe: enables the device (if it really is R6040)
409
;;  probe: enables the device (if it really is R6040)
411
;;
410
;;
412
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
411
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
413
 
412
 
414
align 4
413
align 4
415
probe:
414
probe:
416
        DEBUGF  1,"Probing\n"
415
        DEBUGF  1,"Probing\n"
417
 
416
 
418
; Make the device a bus master
417
; Make the device a bus master
419
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
418
        invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
420
        or      al, PCI_CMD_MASTER
419
        or      al, PCI_CMD_MASTER
421
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
420
        invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
422
 
421
 
423
        ; If PHY status change register is still set to zero
422
        ; If PHY status change register is still set to zero
424
        ; it means the bootloader didn't initialize it
423
        ; it means the bootloader didn't initialize it
425
 
424
 
426
        set_io  [ebx + device.io_addr], 0
425
        set_io  [ebx + device.io_addr], 0
427
        set_io  [ebx + device.io_addr], PHY_CC
426
        set_io  [ebx + device.io_addr], PHY_CC
428
        in      ax, dx
427
        in      ax, dx
429
        test    ax, ax
428
        test    ax, ax
430
        jnz     @f
429
        jnz     @f
431
        mov     ax, 0x9F07
430
        mov     ax, 0x9F07
432
        out     dx, ax
431
        out     dx, ax
433
     @@:
432
  @@:
434
 
433
 
435
        call    read_mac
434
        call    read_mac
436
 
435
 
437
        ; Some bootloaders/BIOSes do not initialize MAC address, warn about that
436
        ; Some bootloaders/BIOSes do not initialize MAC address, warn about that
438
        and     eax, 0xFF
437
        and     eax, 0xFF
439
        or      eax, dword [ebx + device.mac]
438
        or      eax, dword [ebx + device.mac]
440
        test    eax, eax
439
        test    eax, eax
441
        jnz     @f
440
        jnz     @f
442
        DEBUGF  2, "MAC address not initialized!\n"
441
        DEBUGF  2, "MAC address not initialized!\n"
443
 
442
 
444
     @@:
443
  @@:
445
        ; Init RDC private data
444
        ; Init RDC private data
446
        mov     [ebx + device.mcr0], MCR0_XMTEN or MCR0_RCVEN
445
        mov     [ebx + device.mcr0], MCR0_XMTEN or MCR0_RCVEN
447
        mov     [ebx + device.phy_addr], PHY1_ADDR
446
        mov     [ebx + device.phy_addr], PHY1_ADDR
448
        mov     [ebx + device.switch_sig], 0
447
        mov     [ebx + device.switch_sig], 0
449
 
448
 
450
        ; Check the vendor ID on the PHY, if 0xFFFF assume none attached
449
        ; Check the vendor ID on the PHY, if 0xFFFF assume none attached
451
        stdcall phy_read, [ebx + device.phy_addr], 2
450
        stdcall phy_read, [ebx + device.phy_addr], 2
452
        cmp     ax, 0xFFFF
451
        cmp     ax, 0xFFFF
453
        jne     @f
452
        jne     @f
454
        DEBUGF  2, "Failed to detect an attached PHY!\n"
453
        DEBUGF  2, "Failed to detect an attached PHY!\n"
-
 
454
  .err:
455
        mov     eax, -1
455
        mov     eax, -1
456
        ret
456
        ret
457
     @@:
457
  @@:
458
 
458
 
459
        ; Set MAC address
459
        ; Set MAC address
460
        call    init_mac_regs
460
        call    init_mac_regs
461
 
461
 
462
        ; Initialize and alloc RX/TX buffers
462
        ; Initialize and alloc RX/TX buffers
463
        call    init_txbufs
463
        call    init_txbufs
464
        call    init_rxbufs
464
        call    init_rxbufs
-
 
465
        test    eax, eax
-
 
466
        jnz     .err
465
 
467
 
466
        ; Read the PHY ID
468
        ; Read the PHY ID
467
        mov     [ebx + device.phy_mode], MCR0_FD
469
        mov     [ebx + device.phy_mode], MCR0_FD
468
        stdcall phy_read, 0, 2
470
        stdcall phy_read, 0, 2
469
        mov     [ebx + device.switch_sig], ax
471
        mov     [ebx + device.switch_sig], ax
470
        cmp     ax, ICPLUS_PHY_ID
472
        cmp     ax, ICPLUS_PHY_ID
471
        jne     @f
473
        jne     @f
472
        stdcall phy_write, 29, 31, 0x175C ; Enable registers
474
        stdcall phy_write, 29, 31, 0x175C ; Enable registers
473
        jmp     .phy_readen
475
        jmp     .phy_readen
474
      @@:
476
  @@:
475
 
477
 
476
        ; PHY Mode Check
478
        ; PHY Mode Check
477
        stdcall phy_write, [ebx + device.phy_addr], 4, PHY_CAP
479
        stdcall phy_write, [ebx + device.phy_addr], 4, PHY_CAP
478
        stdcall phy_write, [ebx + device.phy_addr], 0, PHY_MODE
480
        stdcall phy_write, [ebx + device.phy_addr], 0, PHY_MODE
479
 
481
 
480
      if PHY_MODE = 0x3100
482
      if PHY_MODE = 0x3100
481
        call    phy_mode_chk
483
        call    phy_mode_chk
482
        mov     [ebx + device.phy_mode], ax
484
        mov     [ebx + device.phy_mode], ax
483
        jmp     .phy_readen
485
        jmp     .phy_readen
484
      end if
486
      end if
485
 
487
 
486
      if not (PHY_MODE and 0x0100)
488
      if not (PHY_MODE and 0x0100)
487
        mov     [ebx + device.phy_mode], 0
489
        mov     [ebx + device.phy_mode], 0
488
      end if
490
      end if
489
 
491
 
490
      .phy_readen:
492
  .phy_readen:
491
 
493
 
492
        ; Set duplex mode
494
        ; Set duplex mode
493
        mov     ax, [ebx + device.phy_mode]
495
        mov     ax, [ebx + device.phy_mode]
494
        or      [ebx + device.mcr0], ax
496
        or      [ebx + device.mcr0], ax
495
 
497
 
496
        ; improve performance (by RDC guys)
498
        ; improve performance (by RDC guys)
497
        stdcall phy_read, 30, 17
499
        stdcall phy_read, 30, 17
498
        or      ax, 0x4000
500
        or      ax, 0x4000
499
        stdcall phy_write, 30, 17, eax
501
        stdcall phy_write, 30, 17, eax
500
 
502
 
501
        stdcall phy_read, 30, 17
503
        stdcall phy_read, 30, 17
502
        and     ax, not 0x2000
504
        and     ax, not 0x2000
503
        stdcall phy_write, 30, 17, eax
505
        stdcall phy_write, 30, 17, eax
504
 
506
 
505
        stdcall phy_write, 0, 19, 0x0000
507
        stdcall phy_write, 0, 19, 0x0000
506
        stdcall phy_write, 0, 30, 0x01F0
508
        stdcall phy_write, 0, 30, 0x01F0
507
 
509
 
508
        ; Initialize all Mac registers
510
        ; Initialize all Mac registers
509
        call    init_mac_regs
511
        call    init_mac_regs
510
 
512
 
511
 
513
 
512
align 4
514
align 4
513
reset:
515
reset:
514
 
516
 
515
        DEBUGF  1,"Resetting\n"
517
        DEBUGF  1,"Resetting\n"
516
 
518
 
517
        ; Mask off Interrupt
519
        ; Mask off Interrupt
518
        xor     ax, ax
520
        xor     ax, ax
519
        set_io  [ebx + device.io_addr], 0
521
        set_io  [ebx + device.io_addr], 0
520
        set_io  [ebx + device.io_addr], MIER
522
        set_io  [ebx + device.io_addr], MIER
521
        out     dx, ax
523
        out     dx, ax
522
 
524
 
523
; attach int handler
525
; attach int handler
524
 
526
 
525
        movzx   eax, [ebx + device.irq_line]
527
        movzx   eax, [ebx + device.irq_line]
526
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
528
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
527
        invoke  AttachIntHandler, eax, int_handler, ebx
529
        invoke  AttachIntHandler, eax, int_handler, ebx
528
        test    eax, eax
530
        test    eax, eax
529
        jnz     @f
531
        jnz     @f
530
        DEBUGF  2,"Could not attach int handler!\n"
532
        DEBUGF  2,"Could not attach int handler!\n"
531
        or      eax, -1
533
        or      eax, -1
532
        ret
534
        ret
533
       @@:
535
  @@:
534
 
536
 
535
        ;Reset RDC MAC
537
        ;Reset RDC MAC
536
        mov     eax, MAC_RST
538
        mov     eax, MAC_RST
537
        set_io  [ebx + device.io_addr], 0
539
        set_io  [ebx + device.io_addr], 0
538
        set_io  [ebx + device.io_addr], MCR1
540
        set_io  [ebx + device.io_addr], MCR1
539
        out     dx, ax
541
        out     dx, ax
540
 
542
 
541
        mov     ecx, 2048 ;limit
543
        mov     ecx, 2048 ;limit
542
  .read:
544
  .read:
543
        in      ax, dx
545
        in      ax, dx
544
        test    ax, 0x1
546
        test    ax, 0x1
545
        jnz      @f
547
        jnz      @f
546
        dec     ecx
548
        dec     ecx
547
        test    ecx, ecx
549
        test    ecx, ecx
548
        jnz     .read
550
        jnz     .read
549
  @@:
551
  @@:
550
        ;Reset internal state machine
552
        ;Reset internal state machine
551
        mov     ax,  2
553
        mov     ax,  2
552
        set_io  [ebx + device.io_addr], MAC_SM
554
        set_io  [ebx + device.io_addr], MAC_SM
553
        out     dx, ax
555
        out     dx, ax
554
 
556
 
555
        xor     ax, ax
557
        xor     ax, ax
556
        out     dx, ax
558
        out     dx, ax
557
 
559
 
558
        mov     esi, 5
560
        mov     esi, 5
559
        invoke  Sleep
561
        invoke  Sleep
560
 
562
 
561
        ;MAC Bus Control Register
563
        ;MAC Bus Control Register
562
        mov     ax, MBCR_DEFAULT
564
        mov     ax, MBCR_DEFAULT
563
        set_io  [ebx + device.io_addr], 0
565
        set_io  [ebx + device.io_addr], 0
564
        set_io  [ebx + device.io_addr], MBCR
566
        set_io  [ebx + device.io_addr], MBCR
565
        out     dx, ax
567
        out     dx, ax
566
 
568
 
567
        ;Buffer Size Register
569
        ;Buffer Size Register
568
        mov     ax, MAX_BUF_SIZE
570
        mov     ax, MAX_BUF_SIZE
569
        set_io  [ebx + device.io_addr], MR_BSR
571
        set_io  [ebx + device.io_addr], MR_BSR
570
        out     dx, ax
572
        out     dx, ax
571
 
573
 
572
        ;Write TX ring start address
574
        ;Write TX ring start address
573
        lea     eax, [ebx + device.tx_ring]
575
        lea     eax, [ebx + device.tx_ring]
574
        invoke  GetPhysAddr
576
        invoke  GetPhysAddr
575
        set_io  [ebx + device.io_addr], MTD_SA0
577
        set_io  [ebx + device.io_addr], MTD_SA0
576
        out     dx, ax
578
        out     dx, ax
577
        shr     eax, 16
579
        shr     eax, 16
578
        set_io  [ebx + device.io_addr], MTD_SA1
580
        set_io  [ebx + device.io_addr], MTD_SA1
579
        out     dx, ax
581
        out     dx, ax
580
 
582
 
581
        ;Write RX ring start address
583
        ;Write RX ring start address
582
        lea     eax, [ebx + device.rx_ring]
584
        lea     eax, [ebx + device.rx_ring]
583
        invoke  GetPhysAddr
585
        invoke  GetPhysAddr
584
        set_io  [ebx + device.io_addr], MRD_SA0
586
        set_io  [ebx + device.io_addr], MRD_SA0
585
        out     dx, ax
587
        out     dx, ax
586
        shr     eax, 16
588
        shr     eax, 16
587
        set_io  [ebx + device.io_addr], MRD_SA1
589
        set_io  [ebx + device.io_addr], MRD_SA1
588
        out     dx, ax
590
        out     dx, ax
589
 
591
 
590
        ;Set interrupt waiting time and packet numbers
592
        ;Set interrupt waiting time and packet numbers
591
        xor     ax, ax
593
        xor     ax, ax
592
        set_io  [ebx + device.io_addr], MT_ICR
594
        set_io  [ebx + device.io_addr], MT_ICR
593
        out     dx, ax
595
        out     dx, ax
594
 
596
 
595
        ;Enable interrupts
597
        ;Enable interrupts
596
        mov     ax, INT_MASK
598
        mov     ax, INT_MASK
597
        set_io  [ebx + device.io_addr], MIER
599
        set_io  [ebx + device.io_addr], MIER
598
        out     dx, ax
600
        out     dx, ax
599
 
601
 
600
        ;Enable RX
602
        ;Enable RX
601
        mov     ax, [ebx + device.mcr0]
603
        mov     ax, [ebx + device.mcr0]
602
        or      ax, MCR0_RCVEN
604
        or      ax, MCR0_RCVEN
603
        set_io  [ebx + device.io_addr], 0
605
        set_io  [ebx + device.io_addr], 0
604
        out     dx, ax
606
        out     dx, ax
605
 
607
 
606
        ;Let TX poll the descriptors
608
        ;Let TX poll the descriptors
607
        ;we may got called by tx_timeout which has left some unset tx buffers
609
        ;we may got called by tx_timeout which has left some unset tx buffers
608
        xor     ax, ax
610
        xor     ax, ax
609
        inc     ax
611
        inc     ax
610
        set_io  [ebx + device.io_addr], MTPR
612
        set_io  [ebx + device.io_addr], MTPR
611
        out     dx, ax
613
        out     dx, ax
612
 
614
 
613
; Set the mtu, kernel will be able to send now
615
; Set the mtu, kernel will be able to send now
614
        mov     [ebx + device.mtu], 1514
616
        mov     [ebx + device.mtu], 1514
615
 
617
 
616
; Set link state to unknown
618
; Set link state to unknown
617
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
619
        mov     [ebx + device.state], ETH_LINK_UNKNOWN
618
 
620
 
619
        DEBUGF  1,"Reset ok\n"
621
        DEBUGF  1,"Reset ok\n"
620
        xor     eax, eax
622
        xor     eax, eax
621
        ret
623
        ret
622
 
624
 
623
 
625
 
624
 
626
 
625
align 4
627
align 4
626
init_txbufs:
628
init_txbufs:
627
 
629
 
628
        DEBUGF  1,"Init TxBufs\n"
630
        DEBUGF  1,"Init TxBufs\n"
629
 
631
 
630
        lea     esi, [ebx + device.tx_ring]
632
        lea     esi, [ebx + device.tx_ring]
631
        lea     eax, [ebx + device.tx_ring + sizeof.x_head]
633
        lea     eax, [ebx + device.tx_ring + sizeof.x_head]
632
        invoke  GetPhysAddr
634
        invoke  GetPhysAddr
633
        mov     ecx, TX_RING_SIZE
635
        mov     ecx, TX_RING_SIZE
634
 
636
 
635
    .next_desc:
637
  .next_desc:
636
        mov     [esi + x_head.ndesc], eax
638
        mov     [esi + x_head.ndesc], eax
637
        mov     [esi + x_head.skb_ptr], 0
639
        mov     [esi + x_head.skb_ptr], 0
638
        mov     [esi + x_head.status], DSC_OWNER_MAC
640
        mov     [esi + x_head.status], DSC_OWNER_MAC
639
        add     eax, sizeof.x_head
641
        add     eax, sizeof.x_head
640
        add     esi, sizeof.x_head
642
        add     esi, sizeof.x_head
641
        dec     ecx
643
        dec     ecx
642
        jnz     .next_desc
644
        jnz     .next_desc
643
 
645
 
644
        lea     eax, [ebx + device.tx_ring]
646
        lea     eax, [ebx + device.tx_ring]
645
        invoke  GetPhysAddr
647
        invoke  GetPhysAddr
646
        mov     dword[ebx + device.tx_ring + sizeof.x_head*(TX_RING_SIZE-1) + x_head.ndesc], eax
648
        mov     dword[ebx + device.tx_ring + sizeof.x_head*(TX_RING_SIZE-1) + x_head.ndesc], eax
647
 
649
 
648
        ret
650
        ret
649
 
651
 
650
 
652
 
651
 
653
 
652
align 4
654
align 4
653
init_rxbufs:
655
init_rxbufs:
654
 
656
 
655
        DEBUGF  1,"Init RxBufs\n"
657
        DEBUGF  1,"Init RxBufs\n"
656
 
658
 
657
        lea     esi, [ebx + device.rx_ring]
659
        lea     esi, [ebx + device.rx_ring]
658
        lea     eax, [ebx + device.rx_ring + sizeof.x_head]
660
        lea     eax, [ebx + device.rx_ring + sizeof.x_head]
659
        invoke  GetPhysAddr
661
        invoke  GetPhysAddr
660
        mov     edx, eax
662
        mov     edx, eax
661
        mov     ecx, RX_RING_SIZE
663
        mov     ecx, RX_RING_SIZE
662
 
664
 
663
    .next_desc:
665
  .next_desc:
664
        mov     [esi + x_head.ndesc], edx
666
        mov     [esi + x_head.ndesc], edx
665
 
-
 
666
        push    esi ecx edx
667
        push    esi ecx edx
667
        invoke  KernelAlloc, MAX_BUF_SIZE
668
        invoke  NetAlloc, MAX_BUF_SIZE+NET_BUFF.data
668
        pop     edx ecx esi
669
        pop     edx ecx esi
669
 
-
 
-
 
670
        test    eax, eax
-
 
671
        jz      .out_of_mem
670
        mov     [esi + x_head.skb_ptr], eax
672
        mov     [esi + x_head.skb_ptr], eax
671
        invoke  GetPhysAddr
673
        invoke  GetPhysAddr
-
 
674
        add     eax, NET_BUFF.data
672
        mov     [esi + x_head.buf], eax
675
        mov     [esi + x_head.buf], eax
673
        mov     [esi + x_head.status], DSC_OWNER_MAC
676
        mov     [esi + x_head.status], DSC_OWNER_MAC
674
 
677
 
675
        add     edx, sizeof.x_head
678
        add     edx, sizeof.x_head
676
        add     esi, sizeof.x_head
679
        add     esi, sizeof.x_head
677
 
-
 
678
        dec     ecx
680
        dec     ecx
679
        jnz     .next_desc
681
        jnz     .next_desc
680
 
682
 
681
; complete the ring by linking the last to the first
683
; complete the ring by linking the last to the first
682
        lea     eax, [ebx + device.rx_ring]
684
        lea     eax, [ebx + device.rx_ring]
683
        invoke  GetPhysAddr
685
        invoke  GetPhysAddr
684
        mov     dword[ebx + device.rx_ring + sizeof.x_head*(RX_RING_SIZE-1) + x_head.ndesc], eax
686
        mov     dword[ebx + device.rx_ring + sizeof.x_head*(RX_RING_SIZE-1) + x_head.ndesc], eax
-
 
687
 
-
 
688
        xor     eax, eax
-
 
689
        ret
-
 
690
 
-
 
691
  .out_of_mem:
685
 
692
        or      eax, -1
686
        ret
693
        ret
687
 
694
 
688
 
695
 
689
 
696
 
690
align 4
697
align 4
691
phy_mode_chk:
698
phy_mode_chk:
692
 
699
 
693
        DEBUGF  1,"Checking PHY mode\n"
700
        DEBUGF  1,"Checking PHY mode\n"
694
 
701
 
695
        ; PHY Link Status Check
702
        ; PHY Link Status Check
696
        stdcall phy_read, [ebx + device.phy_addr], MII_BMSR
703
        stdcall phy_read, [ebx + device.phy_addr], MII_BMSR
697
        test    ax, BMSR_LSTATUS
704
        test    ax, BMSR_LSTATUS
698
        jz      .ret_0x8000
705
        jz      .ret_0x8000
699
 
706
 
700
        ; PHY Chip Auto-Negotiation Status
707
        ; PHY Chip Auto-Negotiation Status
701
        test    ax, BMSR_ANEGCOMPLETE
708
        test    ax, BMSR_ANEGCOMPLETE
702
        jnz     .auto_nego
709
        jnz     .auto_nego
703
 
710
 
704
        ; Force Mode
711
        ; Force Mode
705
        stdcall phy_read, [ebx + device.phy_addr], MII_BMCR
712
        stdcall phy_read, [ebx + device.phy_addr], MII_BMCR
706
        test    ax, BMCR_FULLDPLX
713
        test    ax, BMCR_FULLDPLX
707
        jnz     .ret_0x8000
714
        jnz     .ret_0x8000
708
 
715
 
709
  .auto_nego:
716
  .auto_nego:
710
        ; Auto Negotiation Mode
717
        ; Auto Negotiation Mode
711
        stdcall phy_read, [ebx + device.phy_addr], MII_LPA
718
        stdcall phy_read, [ebx + device.phy_addr], MII_LPA
712
        mov     cx, ax
719
        mov     cx, ax
713
        stdcall phy_read, [ebx + device.phy_addr], MII_ADVERTISE
720
        stdcall phy_read, [ebx + device.phy_addr], MII_ADVERTISE
714
        and     ax, cx
721
        and     ax, cx
715
        test    ax, ADVERTISE_10FULL + ADVERTISE_100FULL
722
        test    ax, ADVERTISE_10FULL + ADVERTISE_100FULL
716
        jnz     .ret_0x8000
723
        jnz     .ret_0x8000
717
 
724
 
718
        xor     eax, eax
725
        xor     eax, eax
719
        ret
726
        ret
720
 
727
 
721
  .ret_0x8000:
728
  .ret_0x8000:
722
        mov     eax, 0x8000
729
        mov     eax, 0x8000
723
        ret
730
        ret
724
 
731
 
725
 
732
 
726
 
733
 
727
 
734
 
728
 
735
 
729
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
736
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
730
;;                                         ;;
737
;;                                         ;;
731
;; Transmit                                ;;
738
;; Transmit                                ;;
732
;;                                         ;;
739
;;                                         ;;
733
;; In: pointer to device structure in ebx  ;;
740
;; In: pointer to device structure in ebx  ;;
734
;;                                         ;;
741
;;                                         ;;
735
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
742
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
736
 
743
 
737
proc transmit stdcall bufferptr, buffersize
744
proc transmit stdcall bufferptr
738
 
745
 
739
        pushf
746
        pushf
740
        cli
747
        cli
-
 
748
 
741
 
749
        mov     esi, [bufferptr]
742
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
750
        DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length]
743
        mov     eax, [bufferptr]
751
        lea     eax, [esi + NET_BUFF.data]
744
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
752
        DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
745
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
753
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
746
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
754
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
747
        [eax+13]:2,[eax+12]:2
755
        [eax+13]:2,[eax+12]:2
748
 
756
 
749
        cmp     [buffersize], 1514
757
        cmp     [esi + NET_BUFF.length], 1514
750
        ja      .fail
758
        ja      .fail
751
        cmp     [buffersize], 60
759
        cmp     [esi + NET_BUFF.length], 60
752
        jb      .fail
760
        jb      .fail
753
 
761
 
754
        movzx   edi, [ebx + device.cur_tx]
762
        movzx   edi, [ebx + device.cur_tx]
755
        shl     edi, 5
763
        shl     edi, 5
756
        add     edi, ebx
764
        add     edi, ebx
757
        add     edi, device.tx_ring
765
        add     edi, device.tx_ring
758
 
766
 
759
        DEBUGF  1,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
767
        DEBUGF  1,"TX buffer status: 0x%x\n", [edi + x_head.status]:4
760
 
768
 
761
        test    [edi + x_head.status], DSC_OWNER_MAC    ; check if buffer is available
769
        test    [edi + x_head.status], DSC_OWNER_MAC    ; check if buffer is available
762
        jnz     .wait_to_send
770
        jnz     .wait_to_send
763
 
771
 
764
  .do_send:
772
  .do_send:
765
        DEBUGF  1,"Sending now\n"
773
        DEBUGF  1,"Sending now\n"
-
 
774
 
766
 
775
        mov     [edi + x_head.skb_ptr], esi
767
        mov     eax, [bufferptr]
776
        mov     eax, esi
768
        mov     [edi + x_head.skb_ptr], eax
777
        add     eax, [eax + NET_BUFF.offset]
769
        invoke  GetPhysAddr
778
        invoke  GetPhysAddr
770
        mov     [edi + x_head.buf], eax
779
        mov     [edi + x_head.buf], eax
771
        mov     ecx, [buffersize]
780
        mov     ecx, [esi + NET_BUFF.length]
772
        mov     [edi + x_head.len], cx
781
        mov     [edi + x_head.len], cx
773
        mov     [edi + x_head.status], DSC_OWNER_MAC
782
        mov     [edi + x_head.status], DSC_OWNER_MAC
774
 
783
 
775
        ; Trigger the MAC to check the TX descriptor
784
        ; Trigger the MAC to check the TX descriptor
776
        mov     ax, 0x01
785
        mov     ax, 0x01
777
        set_io  [ebx + device.io_addr], 0
786
        set_io  [ebx + device.io_addr], 0
778
        set_io  [ebx + device.io_addr], MTPR
787
        set_io  [ebx + device.io_addr], MTPR
779
        out     dx, ax
788
        out     dx, ax
780
 
789
 
781
        inc     [ebx + device.cur_tx]
790
        inc     [ebx + device.cur_tx]
782
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
791
        and     [ebx + device.cur_tx], TX_RING_SIZE - 1
783
 
792
 
784
; Update stats
793
; Update stats
785
        inc     [ebx + device.packets_tx]
794
        inc     [ebx + device.packets_tx]
786
        mov     eax, [buffersize]
795
        mov     eax, [esi + NET_BUFF.length]
787
        add     dword[ebx + device.bytes_tx], eax
796
        add     dword[ebx + device.bytes_tx], eax
788
        adc     dword[ebx + device.bytes_tx + 4], 0
797
        adc     dword[ebx + device.bytes_tx + 4], 0
789
 
798
 
790
        popf
799
        popf
791
        xor     eax, eax
800
        xor     eax, eax
792
        ret
801
        ret
793
 
802
 
794
  .wait_to_send:
803
  .wait_to_send:
795
        DEBUGF  1,"Waiting for TX buffer\n"
804
        DEBUGF  1,"Waiting for TX buffer\n"
796
 
-
 
797
        invoke  GetTimerTicks           ; returns in eax
805
        invoke  GetTimerTicks           ; returns in eax
798
        lea     edx, [eax + 100]
806
        lea     edx, [eax + 100]
799
     .l2:
807
  .l2:
-
 
808
        mov     esi, [bufferptr]
800
        test    [edi + x_head.status], DSC_OWNER_MAC
809
        test    [edi + x_head.status], DSC_OWNER_MAC
801
        jz      .do_send
810
        jz      .do_send
-
 
811
        popf
802
        mov     esi, 10
812
        mov     esi, 10
803
        invoke  Sleep
813
        invoke  Sleep
804
        invoke  GetTimerTicks
814
        invoke  GetTimerTicks
-
 
815
        pushf
-
 
816
        cli
805
        cmp     edx, eax
817
        cmp     edx, eax
806
        jb      .l2
818
        jb      .l2
807
 
819
 
808
        DEBUGF  2,"Send timeout\n"
820
        DEBUGF  2,"Send timeout\n"
809
  .fail:
821
  .fail:
810
        DEBUGF  2,"Send failed\n"
822
        DEBUGF  2,"Send failed\n"
811
        invoke  KernelFree, [bufferptr]
823
        invoke  NetFree, [bufferptr]
812
        popf
824
        popf
813
        or      eax, -1
825
        or      eax, -1
814
        ret
826
        ret
815
 
827
 
816
endp
828
endp
817
 
829
 
818
 
830
 
819
 
831
 
820
;;;;;;;;;;;;;;;;;;;;;;;
832
;;;;;;;;;;;;;;;;;;;;;;;
821
;;                   ;;
833
;;                   ;;
822
;; Interrupt handler ;;
834
;; Interrupt handler ;;
823
;;                   ;;
835
;;                   ;;
824
;;;;;;;;;;;;;;;;;;;;;;;
836
;;;;;;;;;;;;;;;;;;;;;;;
825
 
837
 
826
align 4
838
align 4
827
int_handler:
839
int_handler:
828
 
840
 
829
        push    ebx esi edi
841
        push    ebx esi edi
830
 
842
 
831
        DEBUGF  1,"int\n"
843
        DEBUGF  1,"int\n"
832
 
844
 
833
; Find pointer of device wich made IRQ occur
845
; Find pointer of device wich made IRQ occur
834
 
846
 
835
        mov     ecx, [devices]
847
        mov     ecx, [devices]
836
        test    ecx, ecx
848
        test    ecx, ecx
837
        jz      .nothing
849
        jz      .nothing
838
        mov     esi, device_list
850
        mov     esi, device_list
839
  .nextdevice:
851
  .nextdevice:
840
        mov     ebx, [esi]
852
        mov     ebx, [esi]
841
 
853
 
842
        set_io  [ebx + device.io_addr], 0
854
        set_io  [ebx + device.io_addr], 0
843
        set_io  [ebx + device.io_addr], MISR
855
        set_io  [ebx + device.io_addr], MISR
844
        in      ax, dx
856
        in      ax, dx
845
        out     dx, ax                  ; send it back to ACK
857
        out     dx, ax                  ; send it back to ACK
846
        test    ax, ax
858
        test    ax, ax
847
        jnz     .got_it
859
        jnz     .got_it
848
  .continue:
860
  .continue:
849
        add     esi, 4
861
        add     esi, 4
850
        dec     ecx
862
        dec     ecx
851
        jnz     .nextdevice
863
        jnz     .nextdevice
852
  .nothing:
864
  .nothing:
853
        pop     edi esi ebx
865
        pop     edi esi ebx
854
        xor     eax, eax
866
        xor     eax, eax
855
 
867
 
856
        ret                             ; If no device was found, abort
868
        ret                             ; If no device was found, abort
857
 
869
 
858
; At this point, test for all possible reasons, and handle accordingly
870
; At this point, test for all possible reasons, and handle accordingly
859
 
871
 
860
  .got_it:
872
  .got_it:
861
 
873
 
862
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
874
        DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
863
 
875
 
864
        push ax
876
        push ax
865
 
877
 
866
        test    word[esp], RX_FINISH
878
        test    word[esp], RX_FINISH
867
        jz      .no_RX
879
        jz      .no_RX
868
 
880
 
869
        push    ebx
881
        push    ebx
870
  .more_RX:
882
  .more_RX:
871
        pop     ebx
883
        pop     ebx
872
 
884
 
873
        ; Find the current RX descriptor
885
        ; Find the current RX descriptor
874
        movzx   edx, [ebx + device.cur_rx]
886
        movzx   edx, [ebx + device.cur_rx]
875
        shl     edx, 5
887
        shl     edx, 5
876
        lea     edx, [ebx + device.rx_ring + edx]
888
        lea     edx, [ebx + device.rx_ring + edx]
877
 
889
 
878
        ; Check the descriptor status
890
        ; Check the descriptor status
879
        mov     cx, [edx + x_head.status]
891
        mov     cx, [edx + x_head.status]
880
        test    cx, DSC_OWNER_MAC
892
        test    cx, DSC_OWNER_MAC
881
        jnz     .no_RX
893
        jnz     .no_RX
882
 
894
 
883
        DEBUGF  1,"packet status=0x%x\n", cx
895
        DEBUGF  1,"packet status=0x%x\n", cx
884
 
896
 
885
        test    cx, DSC_RX_ERR          ; Global error status set
897
        test    cx, DSC_RX_ERR          ; Global error status set
886
        jnz     .no_RX
898
        jnz     .no_RX
887
 
899
 
888
        ; Packet successfully received
900
        ; Packet successfully received
889
        movzx   ecx, [edx + x_head.len]
901
        movzx   ecx, [edx + x_head.len]
890
        and     ecx, 0xFFF
902
        and     ecx, 0xFFF
891
        sub     ecx, 4                  ; Do not count the CRC
903
        sub     ecx, 4                  ; Do not count the CRC
-
 
904
 
-
 
905
        DEBUGF  1,"packet ptr=0x%x size=%u\n", [edx + x_head.skb_ptr], ecx
892
 
906
 
893
        ; Update stats
907
        ; Update stats
894
        add     dword[ebx + device.bytes_rx], ecx
908
        add     dword[ebx + device.bytes_rx], ecx
895
        adc     dword[ebx + device.bytes_rx + 4], 0
909
        adc     dword[ebx + device.bytes_rx + 4], 0
896
        inc     dword[ebx + device.packets_rx]
910
        inc     dword[ebx + device.packets_rx]
897
 
-
 
898
        ; Push packet size and pointer, kernel will need it..
911
 
-
 
912
        push    ebx
899
        push    ebx
913
        ; Push packet ptr and return addr for Eth_input
-
 
914
        push    .more_RX
-
 
915
        mov     eax, [edx + x_head.skb_ptr]
-
 
916
        push    eax
-
 
917
        mov     [eax + NET_BUFF.length], ecx
-
 
918
        mov     [eax + NET_BUFF.device], ebx
900
        push    .more_RX
-
 
901
 
-
 
902
        push    ecx
-
 
903
        push    [edx + x_head.skb_ptr]
-
 
904
 
-
 
905
        DEBUGF  1,"packet ptr=0x%x\n", [edx + x_head.skb_ptr]
919
        mov     [eax + NET_BUFF.offset], NET_BUFF.data
906
 
920
 
907
        ; reset the RX descriptor
921
        ; reset the RX descriptor (alloc new buffer)
908
        push    edx
922
        push    edx
909
        invoke  KernelAlloc, MAX_BUF_SIZE
923
        invoke  NetAlloc, MAX_BUF_SIZE+NET_BUFF.data
910
        pop     edx
924
        pop     edx
911
        mov     [edx + x_head.skb_ptr], eax
925
        mov     [edx + x_head.skb_ptr], eax
912
        invoke  GetPhysAddr
926
        invoke  GetPhysAddr
-
 
927
        add     eax, NET_BUFF.data
913
        mov     [edx + x_head.buf], eax
928
        mov     [edx + x_head.buf], eax
914
        mov     [edx + x_head.status], DSC_OWNER_MAC
929
        mov     [edx + x_head.status], DSC_OWNER_MAC
915
 
930
 
916
        ; Use next descriptor next time
931
        ; Use next descriptor next time
917
        inc     [ebx + device.cur_rx]
932
        inc     [ebx + device.cur_rx]
918
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
933
        and     [ebx + device.cur_rx], RX_RING_SIZE - 1
919
 
934
 
920
        ; At last, send packet to kernel
935
        ; At last, send packet to kernel
921
        jmp     [Eth_input]
936
        jmp     [EthInput]
922
 
937
 
923
 
938
 
924
  .no_RX:
939
  .no_RX:
925
 
-
 
926
        test    word[esp], TX_FINISH
940
        test    word[esp], TX_FINISH
927
        jz      .no_TX
941
        jz      .no_TX
928
 
942
 
929
      .loop_tx:
943
  .loop_tx:
930
        movzx   edi, [ebx + device.last_tx]
944
        movzx   edi, [ebx + device.last_tx]
931
        shl     edi, 5
945
        shl     edi, 5
932
        lea     edi, [ebx + device.tx_ring + edi]
946
        lea     edi, [ebx + device.tx_ring + edi]
933
 
947
 
934
        test    [edi + x_head.status], DSC_OWNER_MAC
948
        test    [edi + x_head.status], DSC_OWNER_MAC
935
        jnz     .no_TX
949
        jnz     .no_TX
936
 
950
 
937
        cmp     [edi + x_head.skb_ptr], 0
951
        cmp     [edi + x_head.skb_ptr], 0
938
        je      .no_TX
952
        je      .no_TX
939
 
953
 
940
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + x_head.skb_ptr]
954
        DEBUGF  1,"Freeing buffer 0x%x\n", [edi + x_head.skb_ptr]
941
 
955
 
942
        push    [edi + x_head.skb_ptr]
956
        push    [edi + x_head.skb_ptr]
943
        mov     [edi + x_head.skb_ptr], 0
957
        mov     [edi + x_head.skb_ptr], 0
944
        invoke  KernelFree
958
        invoke  NetFree
945
 
959
 
946
        inc     [ebx + device.last_tx]
960
        inc     [ebx + device.last_tx]
947
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
961
        and     [ebx + device.last_tx], TX_RING_SIZE - 1
948
 
962
 
949
        jmp     .loop_tx
963
        jmp     .loop_tx
950
 
964
 
951
  .no_TX:
965
  .no_TX:
952
        test    word[esp], RX_NO_DESC
966
        test    word[esp], RX_NO_DESC
953
        jz      .no_rxdesc
967
        jz      .no_rxdesc
954
 
968
 
955
        DEBUGF  2, "No more RX descriptors!\n"
969
        DEBUGF  2, "No more RX descriptors!\n"
956
 
970
 
957
  .no_rxdesc:
971
  .no_rxdesc:
958
        test    word[esp], RX_FIFO_FULL
972
        test    word[esp], RX_FIFO_FULL
959
        jz      .no_rxfifo
973
        jz      .no_rxfifo
960
 
974
 
961
        DEBUGF  2, "RX FIFO full!\n"
975
        DEBUGF  2, "RX FIFO full!\n"
962
 
976
 
963
  .no_rxfifo:
977
  .no_rxfifo:
964
        test    word[esp], RX_EARLY
978
        test    word[esp], RX_EARLY
965
        jz      .no_rxearly
979
        jz      .no_rxearly
966
 
980
 
967
        DEBUGF  2, "RX early\n"
981
        DEBUGF  2, "RX early\n"
968
 
982
 
969
  .no_rxearly:
983
  .no_rxearly:
970
        test    word[esp], TX_EARLY
984
        test    word[esp], TX_EARLY
971
        jz      .no_txearly
985
        jz      .no_txearly
972
 
986
 
973
        DEBUGF  2, "TX early\n"
987
        DEBUGF  2, "TX early\n"
974
 
988
 
975
  .no_txearly:
989
  .no_txearly:
976
        test    word[esp], EVENT_OVRFL
990
        test    word[esp], EVENT_OVRFL
977
        jz      .no_ovrfl
991
        jz      .no_ovrfl
978
 
992
 
979
        DEBUGF  2, "Event counter overflow!\n"
993
        DEBUGF  2, "Event counter overflow!\n"
980
 
994
 
981
  .no_ovrfl:
995
  .no_ovrfl:
982
        test    word[esp], LINK_CHANGED
996
        test    word[esp], LINK_CHANGED
983
        jz      .no_link
997
        jz      .no_link
984
 
998
 
985
        DEBUGF  2, "Link changed\n"
999
        DEBUGF  2, "Link changed\n"
986
 
1000
 
987
  .no_link:
1001
  .no_link:
988
        pop     ax
1002
        pop     ax
989
 
1003
 
990
        pop     edi esi ebx
1004
        pop     edi esi ebx
991
 
1005
 
992
        ret
1006
        ret
993
 
1007
 
994
 
1008
 
995
 
1009
 
996
 
1010
 
997
align 4
1011
align 4
998
init_mac_regs:
1012
init_mac_regs:
999
 
1013
 
1000
        DEBUGF  1,"initializing MAC regs\n"
1014
        DEBUGF  1,"initializing MAC regs\n"
1001
 
1015
 
1002
        ; MAC operation register
1016
        ; MAC operation register
1003
        mov     ax, 1
1017
        mov     ax, 1
1004
        set_io  [ebx + device.io_addr], 0
1018
        set_io  [ebx + device.io_addr], 0
1005
        set_io  [ebx + device.io_addr], MCR1
1019
        set_io  [ebx + device.io_addr], MCR1
1006
        out     dx, ax
1020
        out     dx, ax
1007
        ; Reset MAC
1021
        ; Reset MAC
1008
        mov     ax, 2
1022
        mov     ax, 2
1009
        set_io  [ebx + device.io_addr], MAC_SM
1023
        set_io  [ebx + device.io_addr], MAC_SM
1010
        out     dx, ax
1024
        out     dx, ax
1011
        ; Reset internal state machine
1025
        ; Reset internal state machine
1012
        xor     ax, ax
1026
        xor     ax, ax
1013
        out     dx, ax
1027
        out     dx, ax
1014
        mov     esi, 5
1028
        mov     esi, 5
1015
        invoke  Sleep
1029
        invoke  Sleep
1016
 
1030
 
1017
        call    read_mac
1031
        call    read_mac
1018
 
1032
 
1019
        ret
1033
        ret
1020
 
1034
 
1021
 
1035
 
1022
 
1036
 
1023
 
1037
 
1024
; Read a word data from PHY Chip
1038
; Read a word data from PHY Chip
1025
 
1039
 
1026
align 4
1040
align 4
1027
proc  phy_read stdcall, phy_addr:dword, reg:dword
1041
proc  phy_read stdcall, phy_addr:dword, reg:dword
1028
 
1042
 
1029
        DEBUGF  1,"PHY read, addr=0x%x reg=0x%x\n", [phy_addr]:8, [reg]:8
1043
        DEBUGF  1,"PHY read, addr=0x%x reg=0x%x\n", [phy_addr]:8, [reg]:8
1030
 
1044
 
1031
        mov     eax, [phy_addr]
1045
        mov     eax, [phy_addr]
1032
        shl     eax, 8
1046
        shl     eax, 8
1033
        add     eax, [reg]
1047
        add     eax, [reg]
1034
        add     eax, MDIO_READ
1048
        add     eax, MDIO_READ
1035
        set_io  [ebx + device.io_addr], 0
1049
        set_io  [ebx + device.io_addr], 0
1036
        set_io  [ebx + device.io_addr], MMDIO
1050
        set_io  [ebx + device.io_addr], MMDIO
1037
        out     dx, ax
1051
        out     dx, ax
1038
 
1052
 
1039
        ;Wait for the read bit to be cleared.
1053
        ;Wait for the read bit to be cleared.
1040
        mov     ecx, 2048 ;limit
1054
        mov     ecx, 2048 ;limit
1041
  .read:
1055
  .read:
1042
        in      ax, dx
1056
        in      ax, dx
1043
        test    ax, MDIO_READ
1057
        test    ax, MDIO_READ
1044
        jz      @f
1058
        jz      @f
1045
        dec     ecx
1059
        dec     ecx
1046
        jnz     .read
1060
        jnz     .read
1047
  @@:
1061
  @@:
1048
 
1062
 
1049
        set_io  [ebx + device.io_addr],   MMRD
1063
        set_io  [ebx + device.io_addr],   MMRD
1050
        in      ax, dx
1064
        in      ax, dx
1051
        and     eax, 0xFFFF
1065
        and     eax, 0xFFFF
1052
 
1066
 
1053
        DEBUGF  1,"PHY read, val=0x%x\n", eax:4
1067
        DEBUGF  1,"PHY read, val=0x%x\n", eax:4
1054
 
1068
 
1055
        ret
1069
        ret
1056
 
1070
 
1057
endp
1071
endp
1058
 
1072
 
1059
 
1073
 
1060
 
1074
 
1061
 
1075
 
1062
; Write a word data to PHY Chip
1076
; Write a word data to PHY Chip
1063
 
1077
 
1064
align 4
1078
align 4
1065
proc  phy_write stdcall, phy_addr:dword, reg:dword, val:dword
1079
proc  phy_write stdcall, phy_addr:dword, reg:dword, val:dword
1066
 
1080
 
1067
        DEBUGF  1,"PHY write, addr=0x%x reg=0x%x val=0x%x\n", \
1081
        DEBUGF  1,"PHY write, addr=0x%x reg=0x%x val=0x%x\n", \
1068
        [phy_addr]:8, [reg]:8, [val]:8
1082
        [phy_addr]:8, [reg]:8, [val]:8
1069
 
1083
 
1070
        mov     eax, [val]
1084
        mov     eax, [val]
1071
        set_io  [ebx + device.io_addr], 0
1085
        set_io  [ebx + device.io_addr], 0
1072
        set_io  [ebx + device.io_addr], MMWD
1086
        set_io  [ebx + device.io_addr], MMWD
1073
        out     dx, ax
1087
        out     dx, ax
1074
 
1088
 
1075
        ;Write the command to the MDIO bus
1089
        ;Write the command to the MDIO bus
1076
        mov     eax, [phy_addr]
1090
        mov     eax, [phy_addr]
1077
        shl     eax, 8
1091
        shl     eax, 8
1078
        add     eax, [reg]
1092
        add     eax, [reg]
1079
        add     eax, MDIO_WRITE
1093
        add     eax, MDIO_WRITE
1080
        set_io  [ebx + device.io_addr], MMDIO
1094
        set_io  [ebx + device.io_addr], MMDIO
1081
        out     dx, ax
1095
        out     dx, ax
1082
 
1096
 
1083
        ;Wait for the write bit to be cleared.
1097
        ;Wait for the write bit to be cleared.
1084
        mov     ecx, 2048 ;limit
1098
        mov     ecx, 2048 ;limit
1085
  .write:
1099
  .write:
1086
        in      ax, dx
1100
        in      ax, dx
1087
        test    ax, MDIO_WRITE
1101
        test    ax, MDIO_WRITE
1088
        jz      @f
1102
        jz      @f
1089
        dec     ecx
1103
        dec     ecx
1090
        jnz     .write
1104
        jnz     .write
1091
  @@:
1105
  @@:
1092
 
1106
 
1093
        DEBUGF  1,"PHY write ok\n"
1107
        DEBUGF  1,"PHY write ok\n"
1094
 
1108
 
1095
        ret
1109
        ret
1096
endp
1110
endp
1097
 
1111
 
1098
 
1112
 
1099
 
1113
 
1100
align 4
1114
align 4
1101
read_mac:
1115
read_mac:
1102
 
1116
 
1103
        DEBUGF  1,"Reading MAC:\n"
1117
        DEBUGF  1,"Reading MAC:\n"
1104
 
1118
 
1105
        mov     cx, 3
1119
        mov     cx, 3
1106
        lea     edi, [ebx + device.mac]
1120
        lea     edi, [ebx + device.mac]
1107
        set_io  [ebx + device.io_addr], 0
1121
        set_io  [ebx + device.io_addr], 0
1108
        set_io  [ebx + device.io_addr], MID_0L
1122
        set_io  [ebx + device.io_addr], MID_0L
1109
     .mac:
1123
  .loop:
1110
        in      ax, dx
1124
        in      ax, dx
1111
        stosw
1125
        stosw
1112
        inc     dx
1126
        inc     dx
1113
        inc     dx
1127
        inc     dx
1114
        dec     cx
1128
        dec     cx
1115
        jnz     .mac
1129
        jnz     .loop
1116
 
1130
 
1117
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
1131
        DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
1118
        [edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2
1132
        [edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2
1119
 
1133
 
1120
        ret
1134
        ret
1121
 
1135
 
1122
 
1136
 
1123
 
1137
 
1124
 
1138
 
1125
; End of code
1139
; End of code
1126
 
1140
 
1127
data fixups
1141
data fixups
1128
end data
1142
end data
1129
 
1143
 
1130
include '../peimport.inc'
1144
include '../peimport.inc'
1131
 
1145
 
1132
my_service      db 'R6040',0                    ; max 16 chars include zero
1146
my_service      db 'R6040',0                    ; max 16 chars include zero
1133
 
1147
 
1134
include_debug_strings
1148
include_debug_strings
1135
 
1149
 
1136
align 4
1150
align 4
1137
devices         dd 0
1151
devices         dd 0
1138
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
1152
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling