source: soft/giet_vm/giet_drivers/nic_driver.c @ 652

Last change on this file since 652 was 613, checked in by bellefin, 9 years ago

NIC driver: update the channel registers of the NIC component (add the status variable and change the descriptor structure)

File size: 7.7 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : nic_driver.c
3// Date     : 23/05/2013
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <giet_config.h>
9#include <nic_driver.h>
10#include <cma_driver.h>
11#include <utils.h>
12#include <tty0.h>
13#include <ctx_handler.h>
14#include <vmem.h>
15
16#if !defined(GIET_USE_IOMMU)
17# error: You must define GIET_USE_IOMMU in the giet_config.h file
18#endif
19
20#if !defined(SEG_NIC_BASE)
21# error: You must define SEG_NIC_BASE in the hard_config.h file
22#endif
23
24#if !defined(NB_NIC_CHANNELS)
25# error: You must define NB_NIC_CHANNELS in the hard_config.h file
26#endif
27
28#if !defined(X_IO)
29# error: You must define X_IO in the hard_config.h file
30#endif
31
32#if !defined(Y_IO)
33# error: You must define Y_IO in the hard_config.h file
34#endif
35
36#if ( NB_NIC_CHANNELS > 8 )
37# error: NB_NIC_CHANNELS cannot be larger than 8
38#endif
39
40#if !defined(NB_CMA_CHANNELS)
41# error: You must define NB_CMA_CHANNELS in the hard_config.h file
42#endif
43
44#if ( NB_CMA_CHANNELS > 8 )
45# error: NB_CMA_CHANNELS cannot be larger than 8
46#endif
47
48#if !defined( USE_IOB )
49# error: You must define USE_IOB in the hard_config.h file
50#endif
51
52///////////////////////////////////////////////////////////////////////////////
53// This low_level function returns the value contained in a channel register.
54///////////////////////////////////////////////////////////////////////////////
55unsigned int _nic_get_channel_register( unsigned int channel,
56                                        unsigned int index )
57{
58    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
59                           NIC_CHANNEL_SPAN * channel + 0x1000 + index;
60    return _io_extended_read( vaddr );
61}
62
63///////////////////////////////////////////////////////////////////////////////
64// This low-level function set a new value in a channel register.
65///////////////////////////////////////////////////////////////////////////////
66void _nic_set_channel_register( unsigned int channel,
67                                unsigned int index,
68                                unsigned int value ) 
69{
70    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
71                           NIC_CHANNEL_SPAN * channel + 0x1000 + index;
72    _io_extended_write( vaddr, value );
73}
74
75///////////////////////////////////////////////////////////////////////////////
76// This low_level function returns the value contained in a global register.
77///////////////////////////////////////////////////////////////////////////////
78unsigned int _nic_get_global_register( unsigned int index )
79{
80    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
81                           NIC_CHANNEL_SPAN * 8 + index;
82    return _io_extended_read( vaddr );
83}
84
85///////////////////////////////////////////////////////////////////////////////
86// This low-level function set a new value in a global register.
87///////////////////////////////////////////////////////////////////////////////
88void _nic_set_global_register( unsigned int index,
89                               unsigned int value ) 
90{
91    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
92                           NIC_CHANNEL_SPAN * 8 + index;
93    _io_extended_write( vaddr, value );
94}
95
96////////////////////////////////////////////
97int _nic_global_init( unsigned int bc_enable,
98                      unsigned int bypass_enable,
99                      unsigned int tdm_enable,
100                      unsigned int tdm_period )
101{
102    _nic_set_global_register( NIC_G_BC_ENABLE    , bc_enable );
103    _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable );
104    _nic_set_global_register( NIC_G_TDM_ENABLE   , tdm_enable );
105    _nic_set_global_register( NIC_G_TDM_PERIOD   , tdm_period );
106    _nic_set_global_register( NIC_G_VIS          , 0 );     // channels activated later
107    _nic_set_global_register( NIC_G_ON           , 1 );   
108
109    return 0;
110}
111
112////////////////////////////////////////////
113int _nic_channel_start( unsigned int channel,
114                        unsigned int is_rx,
115                        unsigned int mac4,
116                        unsigned int mac2 )
117{
118    unsigned int vis = _nic_get_global_register( NIC_G_VIS );
119    vis |= (0x1 << channel );
120
121    _nic_set_global_register( NIC_G_MAC_4 + channel, mac4 );
122    _nic_set_global_register( NIC_G_MAC_2 + channel, mac2 );
123    _nic_set_global_register( NIC_G_VIS            , vis );
124   
125    unsigned int base     = SEG_NIC_BASE;
126    unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
127
128    unsigned int buf_0_addr;
129    unsigned int buf_1_addr;
130    unsigned int sts_0_addr;
131    unsigned int sts_1_addr;
132
133    unsigned int desc_lo_0;
134    unsigned int desc_lo_1;
135    unsigned int desc_hi_0;
136    unsigned int desc_hi_1;
137
138    if ( is_rx )
139    {
140        buf_0_addr = base;
141        buf_1_addr = base + 0x1000;
142        sts_0_addr = base + 0x4000;
143        sts_1_addr = base + 0x4040;
144
145        desc_lo_0 = (sts_0_addr >> 6) + ((buf_0_addr & 0xFC0) << 20);
146        desc_lo_1 = (sts_1_addr >> 6) + ((buf_1_addr & 0xFC0) << 20);
147        desc_hi_0 = ((buf_0_addr & 0xFFFFF000) >> 12) + ((extend & 0xFFF) << 20);
148        desc_hi_1 = ((buf_1_addr & 0xFFFFF000) >> 12) + ((extend & 0xFFF) << 20);
149
150        _nic_set_channel_register( channel, NIC_RX_DESC_LO_0, desc_lo_0     );
151        _nic_set_channel_register( channel, NIC_RX_DESC_LO_1, desc_lo_1     );
152        _nic_set_channel_register( channel, NIC_RX_DESC_HI_0, desc_hi_0     );
153        _nic_set_channel_register( channel, NIC_RX_DESC_HI_1, desc_hi_1     );
154        _nic_set_channel_register( channel, NIC_RX_RUN      , 1             );
155    }
156    else
157    {
158        buf_0_addr = base + 0x2000;
159        buf_1_addr = base + 0x3000;
160        sts_0_addr = base + 0x4080;
161        sts_1_addr = base + 0x40c0;
162
163        desc_lo_0 = (sts_0_addr >> 6) + ((buf_0_addr & 0xFC0) << 20);
164        desc_lo_1 = (sts_1_addr >> 6) + ((buf_1_addr & 0xFC0) << 20);
165        desc_hi_0 = ((buf_0_addr & 0xFFFFF000) >> 12) + ((extend & 0xFFF) << 20);
166        desc_hi_1 = ((buf_1_addr & 0xFFFFF000) >> 12) + ((extend & 0xFFF) << 20);
167
168        _nic_set_channel_register( channel, NIC_TX_DESC_LO_0, desc_lo_0     );
169        _nic_set_channel_register( channel, NIC_TX_DESC_LO_1, desc_lo_1     );
170        _nic_set_channel_register( channel, NIC_TX_DESC_HI_0, desc_hi_0     );
171        _nic_set_channel_register( channel, NIC_TX_DESC_HI_1, desc_hi_1     );
172        _nic_set_channel_register( channel, NIC_TX_RUN      , 1             );
173    }
174
175    return 0;
176}
177
178////////////////////////////////////////////
179int _nic_channel_stop( unsigned int channel,
180                       unsigned int is_rx )
181{
182    if ( is_rx )  _nic_set_channel_register( channel, NIC_RX_RUN, 0 );
183    else          _nic_set_channel_register( channel, NIC_TX_RUN, 0 );
184
185    return 0;   
186}
187
188
189
190////////////////////////////////////////////////////////////////////////////////////////////
191//            Interrupt Service Routines
192////////////////////////////////////////////////////////////////////////////////////////////
193
194////////////////////////////////////////
195void _nic_rx_isr( unsigned int irq_type,
196                  unsigned int irq_id,
197                  unsigned int channel )
198{
199    _puts("[NIC WARNING] RX buffers are full for NIC channel ");
200    _putd( channel );
201    _puts("\n");
202}
203
204////////////////////////////////////////
205void _nic_tx_isr( unsigned int irq_type,
206                  unsigned int irq_id,
207                  unsigned int channel )
208{
209    _puts("[NIC WARNING] TX buffers are full for NIC channel ");
210    _putd( channel );
211    _puts("\n");
212}
213
214// Local Variables:
215// tab-width: 4
216// c-basic-offset: 4
217// c-file-offsets:((innamespace . 0)(inline-open . 0))
218// indent-tabs-mode: nil
219// End:
220// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
221
Note: See TracBrowser for help on using the repository browser.