• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HPMicro
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include "lwip/tcpip.h"
18 #include "ohos_init.h"
19 #include "hpm_lwip.h"
20 #include "ethernetif.h"
21 #include "lwip/tcpip.h"
22 #include <los_task.h>
23 
24 
25 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
26 __RW enet_rx_desc_t rxDescTab0[ENET_RX_BUFF_COUNT] ; /* Ethernet Rx DMA Descriptor */
27 
28 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
29 __RW enet_tx_desc_t txDescTab0[ENET_TX_BUFF_COUNT] ; /* Ethernet Tx DMA Descriptor */
30 
31 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
32 __RW uint8_t rxBuff0[ENET_RX_BUFF_COUNT][ENET_RX_BUFF_SIZE]; /* Ethernet Receive Buffer */
33 
34 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
35 __RW uint8_t txBuff0[ENET_TX_BUFF_COUNT][ENET_TX_BUFF_SIZE]; /* Ethernet Transmit Buffer */
36 
37 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
38 __RW enet_rx_desc_t rxDescTab1[ENET_RX_BUFF_COUNT] ; /* Ethernet Rx DMA Descriptor */
39 
40 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
41 __RW enet_tx_desc_t txDescTab1[ENET_TX_BUFF_COUNT] ; /* Ethernet Tx DMA Descriptor */
42 
43 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
44 __RW uint8_t rxBuff1[ENET_RX_BUFF_COUNT][ENET_RX_BUFF_SIZE]; /* Ethernet Receive Buffer */
45 
46 static ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
47 __RW uint8_t txBuff1[ENET_TX_BUFF_COUNT][ENET_TX_BUFF_SIZE]; /* Ethernet Transmit Buffer */
48 
49 
50 struct HpmEnetDevice enetDev[2] = {
51     [0] = {
52         .isEnable = 1,
53         .isDefault = 1,
54         .name = "geth",
55         .base = BOARD_ENET_RGMII,
56         .irqNum = IRQn_ENET0,
57         .infType = enet_inf_rgmii,
58         .macAddr = {0x98, 0x2C, 0xBC, 0xB1, 0x9F, 0x15},
59         .ip = {10, 10, 10, 224},
60         .netmask = {255, 255, 255, 0},
61         .gw = {10, 10, 10, 1},
62         .desc = {
63             .tx_desc_list_head = txDescTab0,
64             .rx_desc_list_head = rxDescTab0,
65             .tx_buff_cfg = {
66                 .buffer = (uint32_t)txBuff0,
67                 .count = ENET_TX_BUFF_COUNT,
68                 .size = ENET_TX_BUFF_SIZE,
69             },
70              .rx_buff_cfg = {
71                 .buffer = (uint32_t)rxBuff0,
72                 .count = ENET_RX_BUFF_COUNT,
73                 .size = ENET_RX_BUFF_SIZE,
74             },
75 
76         },
77     },
78     [1] = {
79         .isEnable = 0,
80         .isDefault = 1,
81         .name = "eth",
82         .base = BOARD_ENET_RMII,
83         .irqNum = IRQn_ENET1,
84         .infType = enet_inf_rmii,
85         .macAddr = {0x98, 0x2C, 0xBC, 0xB1, 0x9F, 0x17},
86         .ip = {10, 10, 10, 223},
87         .netmask = {255, 255, 255, 0},
88         .gw = {10, 10, 10, 1},
89         .desc = {
90             .tx_desc_list_head = txDescTab1,
91             .rx_desc_list_head = rxDescTab1,
92             .tx_buff_cfg = {
93                 .buffer = (uint32_t)txBuff1,
94                 .count = ENET_TX_BUFF_COUNT,
95                 .size = ENET_TX_BUFF_SIZE,
96             },
97              .rx_buff_cfg = {
98                 .buffer = (uint32_t)rxBuff1,
99                 .count = ENET_RX_BUFF_COUNT,
100                 .size = ENET_RX_BUFF_SIZE,
101             },
102         },
103     },
104 };
105 
106 
enetDevInit(struct HpmEnetDevice * dev)107 void enetDevInit(struct HpmEnetDevice *dev)
108 {
109     if (!dev->isEnable) {
110         return 0;
111     }
112 
113     board_init_enet_pins(dev->base);
114     board_reset_enet_phy(dev->base);
115 
116     if (dev->infType == enet_inf_rmii) {
117         board_init_enet_rmii_reference_clock(dev->base, BOARD_ENET_RMII_INT_REF_CLK);
118     }
119 
120     if (dev->infType == enet_inf_rgmii) {
121         board_init_enet_rgmii_clock_delay(dev->base);
122     }
123 
124     memset(dev->desc.rx_desc_list_head, 0x00, sizeof(enet_rx_desc_t) * dev->desc.rx_buff_cfg.count);
125     memset(dev->desc.tx_desc_list_head, 0x00, sizeof(enet_tx_desc_t) * dev->desc.tx_buff_cfg.count);
126 
127     enet_mac_config_t macCfg;
128     macCfg.mac_addr_high[0] = dev->macAddr[5];
129     macCfg.mac_addr_high[0] <<= 8;
130     macCfg.mac_addr_high[0] |= dev->macAddr[4];
131 
132     macCfg.mac_addr_low[0]  = dev->macAddr[3];
133     macCfg.mac_addr_low[0] <<= 8;
134     macCfg.mac_addr_low[0] |= dev->macAddr[2];
135     macCfg.mac_addr_low[0] <<= 8;
136     macCfg.mac_addr_low[0] |= dev->macAddr[1];
137     macCfg.mac_addr_low[0] <<= 8;
138     macCfg.mac_addr_low[0] |= dev->macAddr[0];
139     macCfg.valid_max_count  = 1;
140 
141     /* Set DMA PBL */
142     macCfg.dma_pbl = enet_pbl_32;
143     /* Set SARC */
144     macCfg.sarc = enet_sarc_replace_mac0;
145     macCfg.valid_max_count  = 1;
146 
147     enet_int_config_t int_config = {.int_enable = 0, .int_mask = 0};
148 
149     /* Set the interrupt enable mask */
150     int_config.int_enable = enet_normal_int_sum_en    /* Enable normal interrupt summary */
151                           | enet_receive_int_en;      /* Enable receive interrupt */
152     int_config.int_mask = enet_rgsmii_int_mask; /* Disable RGSMII interrupt */
153     int_config.mmc_intr_mask_rx = 0x03ffffff;   /* Disable all mmc rx interrupt events */
154     int_config.mmc_intr_mask_tx = 0x03ffffff;   /* Disable all mmc tx interrupt events */
155 
156     enet_tx_control_config_t enet_tx_control_config;
157 
158     /*Get a default control config for tx descriptor */
159     enet_get_default_tx_control_config(dev->base, &enet_tx_control_config);
160 
161     /* Set the control config for tx descriptor */
162     memcpy(&dev->desc.tx_control_config, &enet_tx_control_config, sizeof(enet_tx_control_config_t));
163 
164     /* Initialize enet controller */
165     enet_controller_init(dev->base, dev->infType, &dev->desc, &macCfg, &int_config);
166     /* Disable LPI interrupt */
167     enet_disable_lpi_interrupt(dev->base);
168 
169     if (dev->infType == enet_inf_rgmii) {
170         rtl8211_config_t phyConfig;
171         rtl8211_reset(dev->base);
172         rtl8211_basic_mode_default_config(dev->base, &phyConfig);
173         rtl8211_basic_mode_init(dev->base, &phyConfig);
174     }
175 
176     if (dev->infType == enet_inf_rmii) {
177         rtl8201_config_t phyConfig;
178         rtl8201_reset(dev->base);
179         rtl8201_basic_mode_default_config(dev->base, &phyConfig);
180         rtl8201_basic_mode_init(dev->base, &phyConfig);
181     }
182 
183     ip_addr_t ipaddr;
184     ip_addr_t netmask;
185     ip_addr_t gw;
186 
187     IP_ADDR4(&ipaddr, dev->ip[0], dev->ip[1], dev->ip[2], dev->ip[3]);
188     IP_ADDR4(&netmask, dev->netmask[0], dev->netmask[1], dev->netmask[2], dev->netmask[3]);
189     IP_ADDR4(&gw, dev->gw[0], dev->gw[1], dev->gw[2], dev->gw[3]);
190 
191     netif_add(&dev->netif, &ipaddr, &netmask, &gw, dev, ethernetif_init, tcpip_input);
192 
193     if (dev->isDefault) {
194         netif_set_default(&dev->netif);
195     }
196 
197     netif_set_up(&dev->netif);
198 }
199 
200 void ethernetif_phy_adaptive_thread_start(void);
201 
HpmLwipInit(void)202 void HpmLwipInit(void)
203 {
204     printf("HpmLwipInit...\n");
205 
206     tcpip_init(NULL, NULL);
207 
208     enetDevInit(&enetDev[0]);
209     enetDevInit(&enetDev[1]);
210     ethernetif_phy_adaptive_thread_start();
211 }
212 
enet_self_adaptive_port_speed(struct HpmEnetDevice * dev)213 void enet_self_adaptive_port_speed(struct HpmEnetDevice *dev)
214 {
215     enet_phy_status_t status = {0};
216     enet_phy_status_t *last_status = &dev->last_status;
217 
218     enet_line_speed_t line_speed[] = {enet_line_speed_10mbps, enet_line_speed_100mbps, enet_line_speed_1000mbps};
219     char *speed_str[] = {"10Mbps", "100Mbps", "1000Mbps"};
220     char *duplex_str[] = {"Half duplex", "Full duplex"};
221 
222     if (!dev->isEnable)
223         return;
224 
225     if (dev->infType == enet_inf_rgmii)
226         rtl8211_get_phy_status(dev->base, &status);
227 
228     if (dev->infType == enet_inf_rmii)
229         rtl8201_get_phy_status(dev->base, &status);
230 
231     if (memcmp(last_status, &status, sizeof(enet_phy_status_t)) != 0) {
232         memcpy(last_status, &status, sizeof(enet_phy_status_t));
233         if (status.enet_phy_link) {
234             printf("Link Status: Up\n");
235             printf("Link Speed:  %s\n", speed_str[status.enet_phy_speed]);
236             printf("Link Duplex: %s\n", duplex_str[status.enet_phy_duplex]);
237             enet_set_line_speed(dev->base, line_speed[status.enet_phy_speed]);
238             enet_set_duplex_mode(dev->base, status.enet_phy_duplex);
239         } else {
240             printf("Link Status: Down\n");
241         }
242     }
243 }
244 
ethernetif_phy_adaptive_thread(UINT32 arg)245 static VOID *ethernetif_phy_adaptive_thread(UINT32 arg)
246 {
247     struct netif *netif = (struct netif *)arg;
248     struct HpmEnetDevice *devs = (struct netif *)arg;
249     printf("ethernetif_adaptive_thread run...\n");
250 
251     while (1) {
252         enet_self_adaptive_port_speed(&devs[0]);
253         enet_self_adaptive_port_speed(&devs[1]);
254         sleep(1);
255     }
256 }
257 
ethernetif_phy_adaptive_thread_start(void)258 void ethernetif_phy_adaptive_thread_start(void)
259 {
260     UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID;
261     UINT32 ret;
262     TSK_INIT_PARAM_S task = {0};
263     /* Create host Task */
264     task.pfnTaskEntry = (TSK_ENTRY_FUNC)ethernetif_phy_adaptive_thread;
265     task.uwStackSize = 4096;
266     task.pcName = "phy";
267     task.usTaskPrio = 3;
268     task.uwArg = (UINTPTR)enetDev;
269     task.uwResved = LOS_TASK_STATUS_DETACHED;
270     ret = LOS_TaskCreate(&taskID, &task);
271     if (ret != LOS_OK) {
272         LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
273         return -1;
274     }
275 }
276 
277 APP_SERVICE_INIT(HpmLwipInit);
278