Subversion Repositories Kolibri OS

Rev

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

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