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

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

ファイルヘッダーの更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.4 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-2019 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 "btstack/utils.h"
95#include "btstack-config.h"
96#include "if_btusb.h"
97#include "iodefine.h"
98
99#ifdef _MSC_VER
100#include <stdlib.h>
101#endif
102
103extern uint8_t mac_addr[ETHER_ADDR_LEN];
104
105/*
106 * ネットワークインタフェースのソフトウェア情報
107 */
108
109/* ネットワークインタフェースに依存するソフトウェア情報 */
110
111static T_MBED_SOFTC mbed_softc;
112
113/* ネットワークインタフェースに依存しないソフトウェア情報 */
114
115T_IF_SOFTC if_softc = {
116 {0,}, /* ネットワークインタフェースのアドレス */
117 0, /* 送信タイムアウト */
118 &mbed_softc, /* ディバイス依存のソフトウェア情報 */
119 SEM_IF_MBED_SBUF_READY, /* 送信セマフォ */
120 SEM_IF_MBED_RBUF_READY, /* 受信セマフォ */
121
122#ifdef SUPPORT_INET6
123
124 IF_MADDR_INIT, /* マルチキャストアドレスリスト */
125
126#endif /* of #ifdef SUPPORT_INET6 */
127};
128
129/*
130 * 局所変数
131 */
132
133static void if_mbed_stop(T_MBED_SOFTC *sc);
134static void if_mbed_init_sub(T_IF_SOFTC *ic);
135
136#ifdef SUPPORT_INET6
137
138static uint32_t ds_crc(uint8_t *addr);
139static void ds_getmcaf(T_IF_SOFTC *ic, uint32_t *mcaf);
140
141/*
142 * ds_crc -- イーサネットアドレスの CRC を計算する。
143 */
144
145#define POLYNOMIAL 0x04c11db6
146
147static uint32_t
148ds_crc(uint8_t *addr)
149{
150 uint32_t crc = ULONG_C(0xffffffff);
151 int_t carry, len, bit;
152 uint8_t byte;
153
154 for (len = ETHER_ADDR_LEN; len-- > 0; ) {
155 byte = *addr++;
156 for (bit = 8; bit-- > 0; ) {
157 carry = ((crc & ULONG_C(0x80000000)) ? 1 : 0) ^ (byte & UINT_C(0x01));
158 crc <<= 1;
159 byte >>= 1;
160 if (carry)
161 crc = (crc ^ POLYNOMIAL) | carry;
162 }
163 }
164 return crc;
165}
166
167#undef POLYNOMIAL
168
169/*
170 * ds_getmcaf -- マルチキャストアドレスのリストからマルチキャストアドレス
171 * フィルタを計算する。
172 */
173
174static void
175ds_getmcaf(T_IF_SOFTC *ic, uint32_t *mcaf)
176{
177 uint32_t count, index;
178 uint8_t *af = (uint8_t*)mcaf;
179
180 mcaf[0] = mcaf[1] = 0;
181
182 for (count = MAX_IF_MADDR_CNT; count-- > 0; ) {
183 index = ds_crc(ic->maddrs[count].lladdr) >> 26;
184 af[index >> 3] |= 1 << (index & 7);
185 }
186}
187
188/*
189 * mbed_setrcr -- 受信構成レジスタ (RCR) を設定する。
190 */
191
192static void
193if_mbed_setrcr(T_IF_SOFTC *ic)
194{
195}
196
197/*
198 * mbed_addmulti -- マルチキャストアドレスを追加する。
199 */
200
201ER
202if_mbed_addmulti(T_IF_SOFTC *ic)
203{
204 if_mbed_setrcr(ic);
205 return E_OK;
206}
207
208#endif /* of #ifdef SUPPORT_INET6 */
209
210/*
211 * mbed_stop -- ネットワークインタフェースを停止する。
212 *
213 * 注意: NIC 割り込み禁止状態で呼び出すこと。
214 */
215
216static void
217if_mbed_stop(T_MBED_SOFTC *sc)
218{
219 ethernetext_start_stop(0);
220}
221
222static void rza1_recv_callback(void)
223{
224 sig_sem(if_softc.semid_rxb_ready);
225}
226
227#define EDMAC_EESIPR_INI_TRANS (0xF4380000)
228#define EDMAC_EESIPR_INI_RECV (0x0205001F) /* 0x02000000 : Detect reception suspended */
229 /* 0x00040000 : Detect frame reception */
230 /* 0x00010000 : Receive FIFO overflow */
231 /* 0x00000010 : Residual bit frame reception */
232 /* 0x00000008 : Long frame reception */
233 /* 0x00000004 : Short frame reception */
234 /* 0x00000002 : PHY-LSI reception error */
235 /* 0x00000001 : Receive frame CRC error */
236#define EDMAC_EESIPR_INI_EtherC (0x00400000) /* 0x00400000 : E-MAC status register */
237
238static void
239if_mbed_init_sub(T_IF_SOFTC *ic)
240{
241 ethernet_cfg_t ethcfg;
242
243 /* Initialize the hardware */
244 ethcfg.int_priority = 6;
245 ethcfg.recv_cb = &rza1_recv_callback;
246 ethcfg.ether_mac = (char *)ic->ifaddr.lladdr;
247 ethernetext_init(&ethcfg);
248}
249
250/*
251 * mbed_reset -- ネットワークインタフェースをリセットする。
252 */
253
254void
255if_mbed_reset(T_IF_SOFTC *ic)
256{
257 btusb_reset(ic);
258
259 ethernetext_start_stop(0);
260
261 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);
262 if_mbed_stop(ic->sc);
263 if_mbed_init_sub(ic);
264
265 ethernetext_start_stop(1);
266}
267
268/*
269 * get_mbed_softc -- ネットワークインタフェースのソフトウェア情報を返す。
270 */
271
272T_IF_SOFTC *
273if_mbed_get_softc(void)
274{
275 return &if_softc;
276}
277
278/*
279 * mbed_watchdog -- ネットワークインタフェースのワッチドッグタイムアウト
280 */
281
282void
283if_mbed_watchdog(T_IF_SOFTC *ic)
284{
285 if_mbed_reset(ic);
286}
287
288/*
289 * mbed_probe -- ネットワークインタフェースの検出
290 */
291
292void
293if_mbed_probe(T_IF_SOFTC *ic)
294{
295 btusb_probe(ic);
296#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
297 netif->hwaddr[0] = MBED_MAC_ADDR_0;
298 netif->hwaddr[1] = MBED_MAC_ADDR_1;
299 netif->hwaddr[2] = MBED_MAC_ADDR_2;
300 netif->hwaddr[3] = MBED_MAC_ADDR_3;
301 netif->hwaddr[4] = MBED_MAC_ADDR_4;
302 netif->hwaddr[5] = MBED_MAC_ADDR_5;
303#else
304 mbed_mac_address((char *)ic->ifaddr.lladdr);
305#endif
306}
307
308/*
309 * mbed_init -- ネットワークインタフェースの初期化
310 */
311
312void
313if_mbed_init(T_IF_SOFTC *ic)
314{
315 btusb_init(ic);
316
317 /* mbed_init 本体を呼び出す。*/
318 if_mbed_init_sub(ic);
319
320 act_tsk(IF_MBED_PHY_TASK);
321
322 ethernet_set_link(-1, 0);
323
324 ETHER.EESIPR0 |= EDMAC_EESIPR_INI_TRANS;
325}
326
327void if_mbed_phy_task(intptr_t arg)
328{
329 T_IFNET *ether = ether_get_ifnet();
330 int32_t connect_sts = 0; /* 0: disconnect, 1:connect */
331 int32_t link_sts;
332 int32_t link_mode_new = NEGO_FAIL;
333 int32_t link_mode_old = NEGO_FAIL;
334
335 while (1) {
336 link_sts = ethernet_link();
337 if (link_sts == 1) {
338 link_mode_new = ethernetext_chk_link_mode();
339 if (link_mode_new != link_mode_old) {
340 if (connect_sts == 1) {
341 ether_set_link_down(ether);
342 }
343 if (link_mode_new != NEGO_FAIL) {
344 ethernetext_set_link_mode(link_mode_new | PROMISCUOUS_MODE);
345 ETHER.EESIPR0 |= EDMAC_EESIPR_INI_TRANS;
346 ether_set_link_up(ether);
347 connect_sts = 1;
348 }
349 }
350 }
351 else {
352 if (connect_sts != 0) {
353 ether_set_link_down(ether);
354 link_mode_new = NEGO_FAIL;
355 connect_sts = 0;
356 }
357 }
358 link_mode_old = link_mode_new;
359 dly_tsk(PHY_TASK_WAIT);
360 }
361}
362
363/*
364 * mbed_read -- フレームの読み込み
365 */
366
367T_NET_BUF *
368if_mbed_read(T_IF_SOFTC *ic)
369{
370 T_NET_BUF *input = NULL, *forward = NULL;
371 uint_t align;
372 int len;
373 uint8_t *dst;
374 ER error;
375
376 len = ethernet_receive();
377 if (len <= 0)
378 return NULL;
379
380 align = ((((len - sizeof(T_IF_HDR)) + 3) >> 2) << 2) + sizeof(T_IF_HDR);
381 if ((error = tget_net_buf(&input, align, TMO_IF_MBED_GET_NET_BUF)) == E_OK && input != NULL) {
382 dst = input->buf + IF_ETHER_NIC_HDR_ALIGN;
383 input->len = ethernet_read((char *)dst, len);
384 }
385 else {
386 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_IN_ERR_PACKETS], 1);
387 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_NO_BUFS], 1);
388 }
389
390 if ((error = tget_net_buf(&forward, align, TMO_IF_MBED_GET_NET_BUF)) == E_OK && forward != NULL) {
391 dst = forward->buf + IF_ETHER_NIC_HDR_ALIGN;
392 memcpy(dst, input->buf + IF_ETHER_NIC_HDR_ALIGN, input->len);
393 forward->len = input->len;
394 int rel = btusb_start(ic, forward);
395 if (rel) {
396 rel_net_buf(forward);
397 }
398 }
399
400 sig_sem(ic->semid_rxb_ready);
401
402 return input;
403}
404
405/*
406 * mbed_start -- 送信フレームをバッファリングする。
407 */
408
409void
410if_mbed_start(T_IF_SOFTC *ic, T_NET_BUF *output)
411{
412 uint_t align;
413 int32_t len, res, pos;
414 T_NET_BUF *forward = NULL;
415 uint8_t *dst;
416 ER error;
417
418 align = ((((output->len - sizeof(T_IF_HDR)) + 3) >> 2) << 2) + sizeof(T_IF_HDR);
419 if ((error = tget_net_buf(&forward, align, TMO_IF_MBED_GET_NET_BUF)) == E_OK && forward != NULL) {
420 dst = forward->buf + IF_ETHER_NIC_HDR_ALIGN;
421 memcpy(dst, output->buf + IF_ETHER_NIC_HDR_ALIGN, output->len);
422 forward->len = output->len;
423 int rel = btusb_start(ic, forward);
424 if (rel) {
425 rel_net_buf(forward);
426 }
427 }
428
429 for (res = output->len, pos = 0; res > 0; res -= len, pos += len) {
430 len = ethernet_write(output->buf + IF_ETHER_NIC_HDR_ALIGN + pos, res);
431 if (len == 0) {
432 syslog(LOG_WARNING, "ethernet_write => 0");
433 break;
434 }
435 }
436
437 if (ethernet_send() == 0) {
438 syslog(LOG_WARNING, "ethernet_send => 0");
439 }
440}
441
442/*
443 * MBED Ethernet Controler 送受信割り込みハンドラ
444 */
445
446void
447if_mbed_eth_handler(void)
448{
449 uint32_t stat_edmac;
450 uint32_t stat_etherc;
451 ER ret;
452
453 /* Clear the interrupt request flag */
454 stat_edmac = (ETHER.EESR0 & ETHER.EESIPR0); /* Targets are restricted to allowed interrupts */
455 ETHER.EESR0 = stat_edmac;
456 /* Reception-related */
457 if (stat_edmac & EDMAC_EESIPR_INI_RECV) {
458 ret = isig_sem(if_softc.semid_rxb_ready);
459 if (ret != E_OK)
460 syslog(LOG_INFO, "semid_rxb_ready %d %x", ret, stat_edmac & EDMAC_EESIPR_INI_RECV);
461 }
462 if (stat_edmac & EDMAC_EESIPR_INI_TRANS) {
463 ret = isig_sem(if_softc.semid_txb_ready);
464 if (ret != E_OK)
465 syslog(LOG_INFO, "semid_txb_ready %d %x", ret, stat_edmac & EDMAC_EESIPR_INI_TRANS);
466 }
467 /* E-MAC-related */
468 if (stat_edmac & EDMAC_EESIPR_INI_EtherC) {
469 /* Clear the interrupt request flag */
470 stat_etherc = (ETHER.ECSR0 & ETHER.ECSIPR0); /* Targets are restricted to allowed interrupts */
471 ETHER.ECSR0 = stat_etherc;
472 }
473}
Note: See TracBrowser for help on using the repository browser.