OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.swp.api/] [openmcapi/] [1.0/] [libmcapi/] [mcapi/] [pkt_snd.c] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
/*
2
 * Copyright (c) 2010, Mentor Graphics Corporation
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
 
31
 
32
#include <openmcapi.h>
33
 
34
/*************************************************************************
35
*
36
*   FUNCTION
37
*
38
*       pkt_send
39
*
40
*   DESCRIPTION
41
*
42
*       Send a packet over a connected channel.  Called by both
43
*       blocking and non-blocking transmission routines.
44
*
45
*   INPUTS
46
*
47
*       send_handle             The transmission handle.
48
*       *buffer                 A pointer to the data to transmit.
49
*       buffer_size             The number of bytes of data to transmit.
50
*       *request                A pointer to memory that will be filled in
51
*                               with data relevant to the operation, so the
52
*                               status of the operation can later be checked.
53
*       *mcapi_status           A pointer to memory that will be filled in
54
*                               with the status of the call.
55
*       timeout                 The amount of time to block for the operation
56
*                               to complete.
57
*
58
*   OUTPUTS
59
*
60
*       None.
61
*
62
*************************************************************************/
63
void pkt_send(mcapi_pktchan_send_hndl_t send_handle, void *buffer,
64
              size_t buffer_size, mcapi_request_t *request,
65
              mcapi_status_t *mcapi_status, mcapi_uint32_t timeout)
66
{
67
    MCAPI_GLOBAL_DATA   *node_data;
68
    MCAPI_ENDPOINT      *tx_endp_ptr = MCAPI_NULL;
69
    MCAPI_BUFFER        *tx_buf;
70
    mcapi_port_t        port_id;
71
    mcapi_node_t        node_id;
72
 
73
    /* Validate the status parameter. */
74
    if (mcapi_status)
75
    {
76
        /* Validate the input parameters. */
77
        if ( (request) && ((buffer) || ((!buffer) && (buffer_size == 0))) )
78
        {
79
            /* Lock the global data structure. */
80
            mcapi_lock_node_data();
81
 
82
            /* Get a pointer to the global node list. */
83
            node_data = mcapi_get_node_data();
84
 
85
            /* Get a pointer to the endpoint that is sending data. */
86
            tx_endp_ptr = mcapi_decode_local_endpoint(node_data, &node_id,
87
                                                      &port_id,
88
                                                      send_handle,
89
                                                      mcapi_status);
90
 
91
            /* Ensure the transmit endpoint is valid. */
92
            if (tx_endp_ptr)
93
            {
94
                /* Ensure the length of the buffer is valid. */
95
                if (buffer_size + MCAPI_HEADER_LEN <=
96
                    tx_endp_ptr->mcapi_route->mcapi_rt_int->mcapi_max_buf_size)
97
                {
98
                    /* Ensure this is a send handle and the connection
99
                     * is still good.
100
                     */
101
                    if ( (tx_endp_ptr->mcapi_state & MCAPI_ENDP_TX) &&
102
                         (tx_endp_ptr->mcapi_state & MCAPI_ENDP_CONNECTED) )
103
                    {
104
                        /* Ensure the handle is for a packet channel. */
105
                        if (tx_endp_ptr->mcapi_chan_type == MCAPI_CHAN_PKT_TYPE)
106
                        {
107
                            /* Get a transmission buffer. */
108
                            tx_buf = tx_endp_ptr->mcapi_route->mcapi_rt_int->
109
                                mcapi_get_buffer(tx_endp_ptr->mcapi_foreign_node_id,
110
                                                 buffer_size + MCAPI_HEADER_LEN,
111
                                                 tx_endp_ptr->mcapi_priority);
112
 
113
                            if (tx_buf)
114
                            {
115
                                /* Save a pointer to the tx interface. */
116
                                tx_buf->mcapi_dev_ptr =
117
                                    (MCAPI_POINTER)(tx_endp_ptr->mcapi_route->mcapi_rt_int);
118
 
119
                                /* Initialize the request structure. */
120
                                mcapi_init_request(request, MCAPI_REQ_TX_FIN);
121
 
122
                                /* Set up the request structure. */
123
                                request->mcapi_target_endp = send_handle;
124
 
125
                                /* Set the source node in the packet. */
126
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_SRC_NODE_OFFSET,
127
                                            tx_endp_ptr->mcapi_node_id);
128
 
129
                                /* Set the source port in the packet. */
130
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_SRC_PORT_OFFSET,
131
                                            tx_endp_ptr->mcapi_port_id);
132
 
133
                                /* Set the destination node in the packet. */
134
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_DEST_NODE_OFFSET,
135
                                            tx_endp_ptr->mcapi_foreign_node_id);
136
 
137
                                /* Set the destination port in the packet. */
138
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_DEST_PORT_OFFSET,
139
                                            tx_endp_ptr->mcapi_foreign_port_id);
140
 
141
                                /* Set the priority of the packet. */
142
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_PRIO_OFFSET,
143
                                            tx_endp_ptr->mcapi_priority);
144
 
145
                                /* Zero out the unused bits. */
146
                                MCAPI_PUT16(tx_buf->buf_ptr, MCAPI_UNUSED_OFFSET, 0);
147
 
148
                                /* Copy the data into the MCAPI buffer. */
149
                                memcpy(&tx_buf->buf_ptr[MCAPI_HEADER_LEN], buffer,
150
                                       buffer_size);
151
 
152
                                /* Set the length of the data in the buffer. */
153
                                tx_buf->buf_size = buffer_size + MCAPI_HEADER_LEN;
154
 
155
                                /* Pass the data to the transport layer driver. */
156
                                *mcapi_status = tx_endp_ptr->mcapi_route->mcapi_rt_int->
157
                                    mcapi_tx_output(tx_buf, buffer_size,
158
                                                    tx_endp_ptr->mcapi_priority,
159
                                                    tx_endp_ptr);
160
 
161
                                /* The data was transmitted. */
162
                                if (*mcapi_status == MCAPI_SUCCESS)
163
                                {
164
                                    /* Set the status to success. */
165
                                    request->mcapi_status = MCAPI_SUCCESS;
166
 
167
                                    /* Record the number of bytes sent. */
168
                                    request->mcapi_byte_count = buffer_size;
169
                                }
170
 
171
                                /* The data could not be transmitted. */
172
                                else
173
                                {
174
                                    request->mcapi_status = *mcapi_status;
175
 
176
                                    /* Indicate that no data was sent. */
177
                                    request->mcapi_byte_count = 0;
178
 
179
                                    /* Return the transmission buffer to the list
180
                                     * of free buffers in the system.
181
                                     */
182
                                    ((MCAPI_INTERFACE*)(tx_buf->mcapi_dev_ptr))->
183
                                        mcapi_recover_buffer(tx_buf);
184
                                }
185
                            }
186
 
187
                            /* There are no transmission buffers available to
188
                             * process this request.
189
                             */
190
                            else
191
                            {
192
                                *mcapi_status = MCAPI_ERR_TRANSMISSION;
193
                            }
194
                        }
195
 
196
                        /* Trying to send a packet over a scalar channel. */
197
                        else
198
                        {
199
                            *mcapi_status = MCAPI_ERR_CHAN_TYPE;
200
                        }
201
                    }
202
 
203
                    /* Attempting to send over a receive channel. */
204
                    else
205
                    {
206
                        /* If this is a receive channel. */
207
                        if (tx_endp_ptr->mcapi_state & MCAPI_ENDP_RX)
208
                        {
209
                            *mcapi_status = MCAPI_ERR_CHAN_DIRECTION;
210
                        }
211
 
212
                        /* Otherwise, the connection has been closed. */
213
                        else
214
                        {
215
                            *mcapi_status = MCAPI_ERR_CHAN_INVALID;
216
                        }
217
                    }
218
                }
219
 
220
                /* The data size is too big. */
221
                else
222
                {
223
                    *mcapi_status = MCAPI_ERR_PKT_SIZE;
224
                }
225
            }
226
 
227
            /* One of the endpoints is invalid. */
228
            else
229
            {
230
                *mcapi_status = MCAPI_ERR_CHAN_INVALID;
231
            }
232
 
233
            /* Unlock the global data structure. */
234
            mcapi_unlock_node_data();
235
        }
236
 
237
        /* The buffer is invalid. */
238
        else
239
        {
240
            *mcapi_status = MCAPI_ERR_PARAMETER;
241
        }
242
    }
243
 
244
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.