Subversion Repositories Kolibri OS

Rev

Rev 5522 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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