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

Last change on this file since 754 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
RevLine 
[258]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>
[437]10#include <cma_driver.h>
[258]11#include <utils.h>
[456]12#include <tty0.h>
[437]13#include <ctx_handler.h>
14#include <vmem.h>
[258]15
16#if !defined(GIET_USE_IOMMU)
17# error: You must define GIET_USE_IOMMU in the giet_config.h file
18#endif
19
[320]20#if !defined(SEG_NIC_BASE)
21# error: You must define SEG_NIC_BASE in the hard_config.h file
22#endif
23
[258]24#if !defined(NB_NIC_CHANNELS)
25# error: You must define NB_NIC_CHANNELS in the hard_config.h file
26#endif
27
[437]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
[258]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
[295]52///////////////////////////////////////////////////////////////////////////////
[437]53// This low_level function returns the value contained in a channel register.
[295]54///////////////////////////////////////////////////////////////////////////////
[437]55unsigned int _nic_get_channel_register( unsigned int channel,
56                                        unsigned int index )
[295]57{
[320]58    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
[456]59                           NIC_CHANNEL_SPAN * channel + 0x1000 + index;
[295]60    return _io_extended_read( vaddr );
61}
62
63///////////////////////////////////////////////////////////////////////////////
[437]64// This low-level function set a new value in a channel register.
[295]65///////////////////////////////////////////////////////////////////////////////
[437]66void _nic_set_channel_register( unsigned int channel,
67                                unsigned int index,
68                                unsigned int value ) 
[295]69{
[320]70    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
[456]71                           NIC_CHANNEL_SPAN * channel + 0x1000 + index;
[295]72    _io_extended_write( vaddr, value );
73}
74
[437]75///////////////////////////////////////////////////////////////////////////////
76// This low_level function returns the value contained in a global register.
77///////////////////////////////////////////////////////////////////////////////
78unsigned int _nic_get_global_register( unsigned int index )
[258]79{
[437]80    unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 
[456]81                           NIC_CHANNEL_SPAN * 8 + index;
[437]82    return _io_extended_read( vaddr );
83}
[258]84
[437]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 + 
[456]92                           NIC_CHANNEL_SPAN * 8 + index;
[437]93    _io_extended_write( vaddr, value );
94}
95
96////////////////////////////////////////////
[456]97int _nic_global_init( unsigned int bc_enable,
98                      unsigned int bypass_enable,
99                      unsigned int tdm_enable,
100                      unsigned int tdm_period )
[437]101{
102    _nic_set_global_register( NIC_G_BC_ENABLE    , bc_enable );
103    _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable );
[456]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 );   
[437]108
[258]109    return 0;
110}
[437]111
112////////////////////////////////////////////
[448]113int _nic_channel_start( unsigned int channel,
114                        unsigned int is_rx,
115                        unsigned int mac4,
116                        unsigned int mac2 )
[258]117{
[456]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   
[437]125    unsigned int base     = SEG_NIC_BASE;
126    unsigned int extend   = (X_IO << Y_WIDTH) + Y_IO;
[258]127
[613]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
[448]138    if ( is_rx )
[437]139    {
[613]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     );
[456]154        _nic_set_channel_register( channel, NIC_RX_RUN      , 1             );
[437]155    }
[448]156    else
[437]157    {
[613]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     );
[456]172        _nic_set_channel_register( channel, NIC_TX_RUN      , 1             );
[437]173    }
174
[258]175    return 0;
176}
[437]177
[448]178////////////////////////////////////////////
179int _nic_channel_stop( unsigned int channel,
180                       unsigned int is_rx )
[258]181{
[448]182    if ( is_rx )  _nic_set_channel_register( channel, NIC_RX_RUN, 0 );
183    else          _nic_set_channel_register( channel, NIC_TX_RUN, 0 );
[258]184
[448]185    return 0;   
[258]186}
187
[437]188
189
190////////////////////////////////////////////////////////////////////////////////////////////
191//            Interrupt Service Routines
192////////////////////////////////////////////////////////////////////////////////////////////
193
194////////////////////////////////////////
[295]195void _nic_rx_isr( unsigned int irq_type,
196                  unsigned int irq_id,
197                  unsigned int channel )
198{
[437]199    _puts("[NIC WARNING] RX buffers are full for NIC channel ");
200    _putd( channel );
201    _puts("\n");
[295]202}
[258]203
[437]204////////////////////////////////////////
[295]205void _nic_tx_isr( unsigned int irq_type,
206                  unsigned int irq_id,
207                  unsigned int channel )
208{
[437]209    _puts("[NIC WARNING] TX buffers are full for NIC channel ");
210    _putd( channel );
211    _puts("\n");
[295]212}
213
[258]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.