source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tinet/netdev/if_mbed/if_mbed.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.6 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 * Copyright (C) 2014 Cores Co., Ltd. Japan
7 *
8 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17 * の無保証規定を掲載すること.
18 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20 * と.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24 * 報告すること.
25 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29 * 免責すること.
30 *
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35 * の責任を負わない.
36 *
37 * @(#) $Id$
38 */
39
40/*
41 * Copyright (c) 1995, David Greenman
42 * All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice unmodified, this list of conditions, and the following
49 * disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * $FreeBSD: src/sys/i386/isa/if_ed.c,v 1.148.2.4 1999/09/25 13:08:18 nyan Exp $
67 */
68
69#define CAST(type, val) ((type)(val))
70
71#include <kernel.h>
72#include <sil.h>
73#include <t_syslog.h>
74#include "kernel_cfg.h"
75#include "kernel/kernel_impl.h"
76
77#include <tinet_defs.h>
78#include <tinet_config.h>
79
80#include <net/if.h>
81#include <net/ethernet.h>
82#include <net/if_arp.h>
83#include <net/net.h>
84#include <net/net_timer.h>
85#include <net/net_count.h>
86#include <net/net_buf.h>
87#include <net/ethernet.h>
88
89#include "mbed_interface.h"
90#include "ethernet_api.h"
91#include "ethernetext_api.h"
92#include <string.h>
93#include "if_mbed.h"
94#include "iodefine.h"
95
96#ifdef _MSC_VER
97#include <stdlib.h>
98#endif
99
100extern uint8_t mac_addr[ETHER_ADDR_LEN];
101
102/*
103 * ネットワークインタフェースに依存するソフトウェア情報
104 */
105
106typedef struct t_mbed_softc {
107 bool_t link_pre;
108 bool_t link_now;
109 bool_t over_flow;
110} T_MBED_SOFTC;
111
112/*
113 * ネットワークインタフェースのソフトウェア情報
114 */
115
116/* ネットワークインタフェースに依存するソフトウェア情報 */
117
118static T_MBED_SOFTC mbed_softc;
119
120/* ネットワークインタフェースに依存しないソフトウェア情報 */
121
122T_IF_SOFTC if_softc = {
123 {0,}, /* ネットワークインタフェースのアドレス */
124 0, /* 送信タイムアウト */
125 &mbed_softc, /* ディバイス依存のソフトウェア情報 */
126 SEM_IF_MBED_SBUF_READY, /* 送信セマフォ */
127 SEM_IF_MBED_RBUF_READY, /* 受信セマフォ */
128
129#ifdef SUPPORT_INET6
130
131 IF_MADDR_INIT, /* マルチキャストアドレスリスト */
132
133#endif /* of #ifdef SUPPORT_INET6 */
134};
135
136/*
137 * 局所変数
138 */
139
140static void if_mbed_stop(T_MBED_SOFTC *sc);
141static void if_mbed_init_sub(T_IF_SOFTC *ic);
142
143#ifdef SUPPORT_INET6
144
145static uint32_t ds_crc(uint8_t *addr);
146static void ds_getmcaf(T_IF_SOFTC *ic, uint32_t *mcaf);
147
148/*
149 * ds_crc -- イーサネットアドレスの CRC を計算する。
150 */
151
152#define POLYNOMIAL 0x04c11db6
153
154static uint32_t
155ds_crc(uint8_t *addr)
156{
157 uint32_t crc = ULONG_C(0xffffffff);
158 int_t carry, len, bit;
159 uint8_t byte;
160
161 for (len = ETHER_ADDR_LEN; len-- > 0; ) {
162 byte = *addr++;
163 for (bit = 8; bit-- > 0; ) {
164 carry = ((crc & ULONG_C(0x80000000)) ? 1 : 0) ^ (byte & UINT_C(0x01));
165 crc <<= 1;
166 byte >>= 1;
167 if (carry)
168 crc = (crc ^ POLYNOMIAL) | carry;
169 }
170 }
171 return crc;
172}
173
174#undef POLYNOMIAL
175
176/*
177 * ds_getmcaf -- マルチキャストアドレスのリストからマルチキャストアドレス
178 * フィルタを計算する。
179 */
180
181static void
182ds_getmcaf(T_IF_SOFTC *ic, uint32_t *mcaf)
183{
184 uint32_t count, index;
185 uint8_t *af = (uint8_t*)mcaf;
186
187 mcaf[0] = mcaf[1] = 0;
188
189 for (count = MAX_IF_MADDR_CNT; count-- > 0; ) {
190 index = ds_crc(ic->maddrs[count].lladdr) >> 26;
191 af[index >> 3] |= 1 << (index & 7);
192 }
193}
194
195/*
196 * mbed_setrcr -- 受信構成レジスタ (RCR) を設定する。
197 */
198
199static void
200if_mbed_setrcr(T_IF_SOFTC *ic)
201{
202}
203
204/*
205 * mbed_addmulti -- マルチキャストアドレスを追加する。
206 */
207
208ER
209if_mbed_addmulti(T_IF_SOFTC *ic)
210{
211 if_mbed_setrcr(ic);
212 return E_OK;
213}
214
215#endif /* of #ifdef SUPPORT_INET6 */
216
217/*
218 * mbed_stop -- ネットワークインタフェースを停止する。
219 *
220 * 注意: NIC 割り込み禁止状態で呼び出すこと。
221 */
222
223static void
224if_mbed_stop(T_MBED_SOFTC *sc)
225{
226 ethernetext_start_stop(0);
227}
228
229static void rza1_recv_callback(void)
230{
231 sig_sem(if_softc.semid_rxb_ready);
232}
233
234#define EDMAC_EESIPR_INI_TRANS (0xF4380000)
235#define EDMAC_EESIPR_INI_RECV (0x0205001F) /* 0x02000000 : Detect reception suspended */
236 /* 0x00040000 : Detect frame reception */
237 /* 0x00010000 : Receive FIFO overflow */
238 /* 0x00000010 : Residual bit frame reception */
239 /* 0x00000008 : Long frame reception */
240 /* 0x00000004 : Short frame reception */
241 /* 0x00000002 : PHY-LSI reception error */
242 /* 0x00000001 : Receive frame CRC error */
243#define EDMAC_EESIPR_INI_EtherC (0x00400000) /* 0x00400000 : E-MAC status register */
244
245static void
246if_mbed_init_sub(T_IF_SOFTC *ic)
247{
248 ethernet_cfg_t ethcfg;
249
250 /* Initialize the hardware */
251 ethcfg.int_priority = 6;
252 ethcfg.recv_cb = &rza1_recv_callback;
253 ethcfg.ether_mac = (char *)ic->ifaddr.lladdr;
254 ethernetext_init(&ethcfg);
255}
256
257/*
258 * mbed_reset -- ネットワークインタフェースをリセットする。
259 */
260
261void
262if_mbed_reset(T_IF_SOFTC *ic)
263{
264 ethernetext_start_stop(0);
265
266 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);
267 if_mbed_stop(ic->sc);
268 if_mbed_init_sub(ic);
269
270 ethernetext_start_stop(1);
271}
272
273/*
274 * get_mbed_softc -- ネットワークインタフェースのソフトウェア情報を返す。
275 */
276
277T_IF_SOFTC *
278if_mbed_get_softc(void)
279{
280 return &if_softc;
281}
282
283/*
284 * mbed_watchdog -- ネットワークインタフェースのワッチドッグタイムアウト
285 */
286
287void
288if_mbed_watchdog(T_IF_SOFTC *ic)
289{
290 if_mbed_reset(ic);
291}
292
293/*
294 * mbed_probe -- ネットワークインタフェースの検出
295 */
296
297void
298if_mbed_probe(T_IF_SOFTC *ic)
299{
300#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
301 netif->hwaddr[0] = MBED_MAC_ADDR_0;
302 netif->hwaddr[1] = MBED_MAC_ADDR_1;
303 netif->hwaddr[2] = MBED_MAC_ADDR_2;
304 netif->hwaddr[3] = MBED_MAC_ADDR_3;
305 netif->hwaddr[4] = MBED_MAC_ADDR_4;
306 netif->hwaddr[5] = MBED_MAC_ADDR_5;
307#else
308 mbed_mac_address((char *)ic->ifaddr.lladdr);
309#endif
310}
311
312/*
313 * mbed_init -- ネットワークインタフェースの初期化
314 */
315
316void
317if_mbed_init(T_IF_SOFTC *ic)
318{
319 /* mbed_init 本体を呼び出す。*/
320 if_mbed_init_sub(ic);
321
322 act_tsk(IF_MBED_PHY_TASK);
323
324 ethernet_set_link(-1, 0);
325
326 ETHER.EESIPR0 |= EDMAC_EESIPR_INI_TRANS;
327}
328
329void if_mbed_phy_task(intptr_t arg)
330{
331 T_IFNET *ether = ether_get_ifnet();
332 int32_t connect_sts = 0; /* 0: disconnect, 1:connect */
333 int32_t link_sts;
334 int32_t link_mode_new = NEGO_FAIL;
335 int32_t link_mode_old = NEGO_FAIL;
336
337 while (1) {
338 link_sts = ethernet_link();
339 if (link_sts == 1) {
340 link_mode_new = ethernetext_chk_link_mode();
341 if (link_mode_new != link_mode_old) {
342 if (connect_sts == 1) {
343 ether_set_link_down(ether);
344 }
345 if (link_mode_new != NEGO_FAIL) {
346 ethernetext_set_link_mode(link_mode_new);
347 ETHER.EESIPR0 |= EDMAC_EESIPR_INI_TRANS;
348 ether_set_link_up(ether);
349 connect_sts = 1;
350 }
351 }
352 }
353 else {
354 if (connect_sts != 0) {
355 ether_set_link_down(ether);
356 link_mode_new = NEGO_FAIL;
357 connect_sts = 0;
358 }
359 }
360 link_mode_old = link_mode_new;
361 dly_tsk(PHY_TASK_WAIT);
362 }
363}
364
365/*
366 * mbed_read -- フレームの読み込み
367 */
368
369T_NET_BUF *
370if_mbed_read(T_IF_SOFTC *ic)
371{
372 T_NET_BUF *input = NULL;
373 uint_t align;
374 int len;
375 uint8_t *dst;
376 ER error;
377
378 len = ethernet_receive();
379 if (len <= 0)
380 return NULL;
381
382 align = ((((len - sizeof(T_IF_HDR)) + 3) >> 2) << 2) + sizeof(T_IF_HDR);
383 if ((error = tget_net_buf(&input, align, TMO_IF_MBED_GET_NET_BUF)) == E_OK && input != NULL) {
384 dst = input->buf + IF_ETHER_NIC_HDR_ALIGN;
385 input->len = ethernet_read((char *)dst, len);
386 }
387 else {
388 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);
389 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_NO_BUFS], 1);
390 }
391
392 sig_sem(ic->semid_rxb_ready);
393
394 return input;
395}
396
397/*
398 * mbed_start -- 送信フレームをバッファリングする。
399 */
400
401void
402if_mbed_start(T_IF_SOFTC *ic, T_NET_BUF *output)
403{
404 int32_t len, res, pos;
405
406 for (res = output->len, pos = 0; res > 0; res -= len, pos += len) {
407 len = ethernet_write((char *)output->buf + IF_ETHER_NIC_HDR_ALIGN + pos, res);
408 if (len == 0) {
409 syslog(LOG_WARNING, "ethernet_write => 0");
410 break;
411 }
412 }
413
414 if (ethernet_send() == 0) {
415 syslog(LOG_WARNING, "ethernet_send => 0");
416 }
417}
418
419/*
420 * MBED Ethernet Controler 送受信割り込みハンドラ
421 */
422
423void
424if_mbed_eth_handler(void)
425{
426 uint32_t stat_edmac;
427 uint32_t stat_etherc;
428 ER ret;
429
430 /* Clear the interrupt request flag */
431 stat_edmac = (ETHER.EESR0 & ETHER.EESIPR0); /* Targets are restricted to allowed interrupts */
432 ETHER.EESR0 = stat_edmac;
433 /* Reception-related */
434 if (stat_edmac & EDMAC_EESIPR_INI_RECV) {
435 ret = isig_sem(if_softc.semid_rxb_ready);
436 if (ret != E_OK)
437 syslog(LOG_INFO, "semid_rxb_ready %d %x", ret, stat_edmac & EDMAC_EESIPR_INI_RECV);
438 }
439 if (stat_edmac & EDMAC_EESIPR_INI_TRANS) {
440 ret = isig_sem(if_softc.semid_txb_ready);
441 if (ret != E_OK)
442 syslog(LOG_INFO, "semid_txb_ready %d %x", ret, stat_edmac & EDMAC_EESIPR_INI_TRANS);
443 }
444 /* E-MAC-related */
445 if (stat_edmac & EDMAC_EESIPR_INI_EtherC) {
446 /* Clear the interrupt request flag */
447 stat_etherc = (ETHER.ECSR0 & ETHER.ECSIPR0); /* Targets are restricted to allowed interrupts */
448 ETHER.ECSR0 = stat_etherc;
449 }
450}
Note: See TracBrowser for help on using the repository browser.