Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  Broadcom NetXtreme 57xx driver for KolibriOS                   ;;
7
;;                                                                 ;;
8
;;                                                                 ;;
9
;;          GNU GENERAL PUBLIC LICENSE                             ;;
10
;;             Version 2, June 1991                                ;;
11
;;                                                                 ;;
12
;; Broadcom's programmers's manual for the BCM57xx                 ;;
13
;; http://www.broadcom.com/collateral/pg/57XX-PG105-R.pdf          ;;
14
;;                                                                 ;;
15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16
 
17
        ; TODO: make better use of the available descriptors
18
 
19
format MS COFF
20
 
21
        API_VERSION             = 0x01000100
22
        DRIVER_VERSION          = 5
23
 
24
        MAX_DEVICES             = 16
25
 
26
        DEBUG                   = 1
27
        __DEBUG__               = 1
28
        __DEBUG_LEVEL__         = 2
29
 
30
 
31
include '../proc32.inc'
32
include '../imports.inc'
33
include '../fdo.inc'
34
include '../netdrv.inc'
35
 
36
public START
37
public service_proc
38
public version
39
 
40
 
41
virtual at ebx
42
        device:
43
        ETH_DEVICE
44
 
45
        .mmio_addr      dd ?
46
        .pci_bus        dd ?
47
        .pci_dev        dd ?
48
        .irq_line       db ?
49
 
50
        .cur_tx         dd ?
51
        .last_tx        dd ?
52
 
53
                        rb 0x100 - (($ - device) and 0xff)
54
        .rx_desc        rd 256/8
55
 
56
                        rb 0x100 - (($ - device) and 0xff)
57
        .tx_desc        rd 256/8
58
 
59
        sizeof.device_struct = $ - device
60
 
61
end virtual
62
 
63
section '.flat' code readable align 16
64
 
65
 
66
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
67
;;                        ;;
68
;; proc START             ;;
69
;;                        ;;
70
;; (standard driver proc) ;;
71
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
72
 
73
align 4
74
proc START stdcall, state:dword
75
 
76
        cmp [state], 1
77
        jne .exit
78
 
79
  .entry:
80
 
81
        DEBUGF  2,"Loading %s driver\n", my_service
82
        stdcall RegService, my_service, service_proc
83
        ret
84
 
85
  .fail:
86
  .exit:
87
        xor eax, eax
88
        ret
89
 
90
endp
91
 
92
 
93
 
94
 
95
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
96
;;                        ;;
97
;; proc SERVICE_PROC      ;;
98
;;                        ;;
99
;; (standard driver proc) ;;
100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101
 
102
align 4
103
proc service_proc stdcall, ioctl:dword
104
 
105
        mov     edx, [ioctl]
106
        mov     eax, [IOCTL.io_code]
107
 
108
;------------------------------------------------------
109
 
110
        cmp     eax, 0 ;SRV_GETVERSION
111
        jne     @F
112
 
113
        cmp     [IOCTL.out_size], 4
114
        jb      .fail
115
        mov     eax, [IOCTL.output]
116
        mov     [eax], dword API_VERSION
117
 
118
        xor     eax, eax
119
        ret
120
 
121
;------------------------------------------------------
122
  @@:
123
        cmp     eax, 1 ;SRV_HOOK
124
        jne     .fail
125
 
126
        cmp     [IOCTL.inp_size], 3                     ; Data input must be at least 3 bytes
127
        jb      .fail
128
 
129
        mov     eax, [IOCTL.input]
130
        cmp     byte [eax], 1                           ; 1 means device number and bus number (pci) are given
131
        jne     .fail                                   ; other types arent supported for this card yet
132
 
133
; check if the device is already listed
134
 
135
        mov     esi, device_list
136
        mov     ecx, [devices]
137
        test    ecx, ecx
138
        jz      .firstdevice
139
 
140
;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
141
        mov     ax, [eax+1]                             ;
142
  .nextdevice:
143
        mov     ebx, [esi]
144
        cmp     al, byte [device.pci_bus]
145
        jne     .next
146
        cmp     ah, byte [device.pci_dev]
147
        je      .find_devicenum                         ; Device is already loaded, let's find it's device number
148
  .next:
149
        add     esi, 4
150
        loop    .nextdevice
151
 
152
 
153
; This device doesnt have its own eth_device structure yet, lets create one
154
  .firstdevice:
155
        cmp     [devices], MAX_DEVICES                  ; First check if the driver can handle one more card
156
        jae     .fail
157
 
158
        allocate_and_clear ebx, sizeof.device_struct, .fail      ; Allocate the buffer for device structure
159
 
160
; Fill in the direct call addresses into the struct
161
 
162
        mov     [device.reset], reset
163
        mov     [device.transmit], transmit
164
        mov     [device.unload], unload
165
        mov     [device.name], my_service
166
 
167
; save the pci bus and device numbers
168
 
169
        mov     eax, [IOCTL.input]
170
        movzx   ecx, byte [eax+1]
171
        mov     [device.pci_bus], ecx
172
        movzx   ecx, byte [eax+2]
173
        mov     [device.pci_dev], ecx
174
 
175
; Now, it's time to find the base mmio addres of the PCI device
176
 
177
        PCI_find_mmio32
178
 
179
; Create virtual mapping of the physical memory
180
 
181
        push    1Bh             ; PG_SW+PG_NOCACHE
182
        push    10000h          ; size of the map
183
        push    eax
184
        call    MapIoMem
185
        mov     [device.mmio_addr], eax
186
 
187
; We've found the mmio address, find IRQ now
188
 
189
        PCI_find_irq
190
 
191
        DEBUGF  1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\
192
        [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.mmio_addr]:8
193
 
194
; Ok, the eth_device structure is ready, let's probe the device
195
        call    probe                                                   ; this function will output in eax
196
        test    eax, eax
197
        jnz     .err                                                    ; If an error occured, exit
198
 
199
        mov     eax, [devices]                                          ; Add the device structure to our device list
200
        mov     [device_list+4*eax], ebx                                ; (IRQ handler uses this list to find device)
201
        inc     [devices]                                               ;
202
 
203
        mov     [device.type], NET_TYPE_ETH
204
        call    NetRegDev
205
 
206
        cmp     eax, -1
207
        je      .destroy
208
 
209
        ret
210
 
211
; If the device was already loaded, find the device number and return it in eax
212
 
213
  .find_devicenum:
214
        DEBUGF  1,"Trying to find device number of already registered device\n"
215
        call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
216
                                                                        ; into a device number in edi
217
        mov     eax, edi                                                ; Application wants it in eax instead
218
        DEBUGF  1,"Kernel says: %u\n", eax
219
        ret
220
 
221
; If an error occured, remove all allocated data and exit (returning -1 in eax)
222
 
223
  .destroy:
224
        ; todo: reset device into virgin state
225
 
226
  .err:
227
        stdcall KernelFree, ebx
228
 
229
  .fail:
230
        or      eax, -1
231
        ret
232
 
233
;------------------------------------------------------
234
endp
235
 
236
 
237
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
238
;;                                                                        ;;
239
;;        Actual Hardware dependent code starts here                      ;;
240
;;                                                                        ;;
241
;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
242
 
243
 
244
align 4
245
unload:
246
        ; TODO: (in this particular order)
247
        ;
248
        ; - Stop the device
249
        ; - Detach int handler
250
        ; - Remove device from local list (device_list)
251
        ; - call unregister function in kernel
252
        ; - Remove all allocated structures and buffers the card used
253
 
254
        or      eax, -1
255
 
256
ret
257
 
258
 
259
 
260
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261
;;
262
;;  probe: enables the device (if it really is I8254X)
263
;;
264
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
265
align 4
266
probe:
267
 
268
        DEBUGF  1,"Probe\n"
269
 
270
        PCI_make_bus_master
271
 
272
        ; TODO: validate the device
273
 
274
 
275
 
276
 
277
 
278
align 4
279
reset:
280
 
281
        DEBUGF  1,"Reset\n"
282
 
283
        movzx   eax, [device.irq_line]
284
        DEBUGF  1,"Attaching int handler to irq %x\n", eax:1
285
        stdcall AttachIntHandler, eax, int_handler, dword 0
286
        test    eax, eax
287
        jnz     @f
288
        DEBUGF  1,"\nCould not attach int handler!\n"
289
;        or      eax, -1
290
;        ret
291
  @@:
292
 
293
        call    read_mac
294
 
295
; Set the mtu, kernel will be able to send now
296
        mov     [device.mtu], 1514
297
 
298
; Set link state to unknown
299
        mov     [device.state], ETH_LINK_UNKOWN
300
 
301
        ret
302
 
303
 
304
 
305
 
306
align 4
307
read_mac:
308
 
309
        DEBUGF  1,"Read MAC\n"
310
 
311
        mov     esi, [device.mmio_addr]
312
        lea     edi, [device.mac]
313
        movsd
314
        movsw
315
 
316
  .mac_ok:
317
        DEBUGF  1,"MAC = %x-%x-%x-%x-%x-%x\n",\
318
        [device.mac+0]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2
319
 
320
        ret
321
 
322
 
323
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
324
;;                                         ;;
325
;; Transmit                                ;;
326
;;                                         ;;
327
;; In: buffer pointer in [esp+4]           ;;
328
;;     size of buffer in [esp+8]           ;;
329
;;     pointer to device structure in ebx  ;;
330
;;                                         ;;
331
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
332
align 4
333
transmit:
334
        DEBUGF  2,"\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8]
335
        mov     eax, [esp+4]
336
        DEBUGF  2,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
337
        [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
338
        [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
339
        [eax+13]:2,[eax+12]:2
340
 
341
        cmp     dword [esp + 8], 1514
342
        ja      .fail
343
        cmp     dword [esp + 8], 60
344
        jb      .fail
345
 
346
 
347
 
348
 
349
; Update stats
350
        inc     [device.packets_tx]
351
        mov     eax, [esp + 8]
352
        add     dword [device.bytes_tx], eax
353
        adc     dword [device.bytes_tx + 4], 0
354
 
355
        ret     8
356
 
357
  .fail:
358
        DEBUGF  1,"Send failed\n"
359
        ret     8
360
 
361
 
362
;;;;;;;;;;;;;;;;;;;;;;;
363
;;                   ;;
364
;; Interrupt handler ;;
365
;;                   ;;
366
;;;;;;;;;;;;;;;;;;;;;;;
367
 
368
align 4
369
int_handler:
370
 
371
        push    ebx esi edi
372
 
373
        DEBUGF  1,"\n%s int\n", my_service
374
;-------------------------------------------
375
; Find pointer of device wich made IRQ occur
376
 
377
        mov     ecx, [devices]
378
        test    ecx, ecx
379
        jz      .nothing
380
        mov     esi, device_list
381
  .nextdevice:
382
        mov     ebx, [esi]
383
 
384
;        mov     edi, [device.mmio_addr]
385
;        mov     eax, [edi + REG_ICR]
386
        test    eax, eax
387
        jnz     .got_it
388
  .continue:
389
        add     esi, 4
390
        dec     ecx
391
        jnz     .nextdevice
392
  .nothing:
393
        pop     edi esi ebx
394
        xor     eax, eax
395
 
396
        ret
397
 
398
  .got_it:
399
 
400
        DEBUGF  1,"Device: %x Status: %x ", ebx, eax
401
 
402
        pop     edi esi ebx
403
        xor     eax, eax
404
        inc     eax
405
 
406
        ret
407
 
408
 
409
 
410
 
411
; End of code
412
 
413
section '.data' data readable writable align 16
414
align 4
415
 
416
devices         dd 0
417
version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
418
my_service      db 'BCM57XX',0                   ; max 16 chars include zero
419
 
420
include_debug_strings                           ; All data wich FDO uses will be included here
421
 
422
device_list     rd MAX_DEVICES                  ; This list contains all pointers to device structures the driver is handling
423