Subversion Repositories Kolibri OS

Rev

Rev 4334 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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