1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
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 <fcntl.h>
16 #include <hdf_base.h>
17 #include <hdf_device_desc.h>
18 #include <hdf_device_object.h>
19 #include <hdf_log.h>
20 #include <sys/ioctl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <signal.h>
24 #include <osal_mem.h>
25 #include <stub_collector.h>
26
27 #include "v1_0/iethernet.h"
28 #include "ethernet_impl.h"
29
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #endif
33 #define LOG_TAG "EthernetDriver"
34 #ifdef LOG_DOMAIN
35 #undef LOG_DOMAIN
36 #endif
37 #define LOG_DOMAIN 0xD0015b0
38
39 struct HdfEthernetInterfaceHost {
40 struct IDeviceIoService ioService;
41 struct IEthernet *service;
42 struct HdfRemoteService **stubObject;
43 };
44
45 static pthread_rwlock_t g_rwLock = PTHREAD_RWLOCK_INITIALIZER;
46 static int g_stop = 0;
47
HdfEthernetStubDriver(void)48 struct HdfEthernetStubData *HdfEthernetStubDriver(void)
49 {
50 static struct HdfEthernetStubData registerManager;
51 return ®isterManager;
52 }
53
EthernetDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)54 static int32_t EthernetDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
55 struct HdfSBuf *reply)
56 {
57 HDF_LOGI("EthernetDriverDispatch enter.");
58 pthread_rwlock_rdlock(&g_rwLock);
59 if (g_stop == 1 || client == NULL || client->device == NULL ||
60 client->device->service == NULL) {
61 pthread_rwlock_unlock(&g_rwLock);
62 HDF_LOGE("%{public}s: client or client.device or service is nullptr", __func__);
63 return HDF_FAILURE;
64 }
65 struct HdfEthernetInterfaceHost *ethernetHost = CONTAINER_OF(
66 client->device->service, struct HdfEthernetInterfaceHost, ioService);
67 if (ethernetHost == NULL || ethernetHost->service == NULL || ethernetHost->stubObject == NULL) {
68 HDF_LOGE("%{public}s: invalid service obj", __func__);
69 pthread_rwlock_unlock(&g_rwLock);
70 return HDF_ERR_INVALID_OBJECT;
71 }
72
73 struct HdfRemoteService *stubObj = *ethernetHost->stubObject;
74 if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) {
75 pthread_rwlock_unlock(&g_rwLock);
76 return HDF_ERR_INVALID_OBJECT;
77 }
78 int ret = stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply);
79 pthread_rwlock_unlock(&g_rwLock);
80 return ret;
81 }
82
HdfEthernetDriverInit(struct HdfDeviceObject * deviceObject)83 static int HdfEthernetDriverInit(struct HdfDeviceObject *deviceObject)
84 {
85 int32_t ret;
86 HDF_LOGI("HdfEthernetDriverInit enter.");
87 struct HdfEthernetStubData *stubData = HdfEthernetStubDriver();
88 DListHeadInit(&stubData->remoteListHead);
89 ret = OsalMutexInit(&stubData->mutex);
90 if (ret != HDF_SUCCESS) {
91 HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret);
92 return HDF_FAILURE;
93 }
94 return HDF_SUCCESS;
95 }
96
HdfEthernetDriverBind(struct HdfDeviceObject * deviceObject)97 static int HdfEthernetDriverBind(struct HdfDeviceObject *deviceObject)
98 {
99 HDF_LOGI("HdfEthernetDriverBind enter.");
100 int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IETHERNET_INTERFACE_DESC);
101 if (ret != HDF_SUCCESS) {
102 HDF_LOGE("failed to set interface descriptor of device object");
103 return ret;
104 }
105 struct HdfEthernetInterfaceHost *ethernetHost =
106 (struct HdfEthernetInterfaceHost *)OsalMemAlloc(sizeof(struct HdfEthernetInterfaceHost));
107 if (ethernetHost == NULL) {
108 HDF_LOGE("HdfEthernetDriverBind OsalMemAlloc Host failed!");
109 return HDF_FAILURE;
110 }
111
112 struct IEthernet *serviceImpl = IEthernetGet(true);
113 struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IETHERNET_INTERFACE_DESC, serviceImpl);
114 if (stubObj == NULL) {
115 OsalMemFree(ethernetHost);
116 ethernetHost = NULL;
117 IEthernetRelease(serviceImpl, true);
118 return HDF_FAILURE;
119 }
120
121 ethernetHost->ioService.Dispatch = EthernetDriverDispatch;
122 ethernetHost->ioService.Open = NULL;
123 ethernetHost->ioService.Release = NULL;
124 ethernetHost->service = serviceImpl;
125 ethernetHost->stubObject = stubObj;
126 deviceObject->service = ðernetHost->ioService;
127 return HDF_SUCCESS;
128 }
129
HdfEthernetDriverRelease(struct HdfDeviceObject * deviceObject)130 static void HdfEthernetDriverRelease(struct HdfDeviceObject *deviceObject)
131 {
132 HDF_LOGI("HdfEthernetDriverRelease enter.");
133 struct HdfEthernetRemoteNode *pos = NULL;
134 struct HdfEthernetRemoteNode *tmp = NULL;
135 pthread_rwlock_wrlock(&g_rwLock);
136 if (deviceObject == NULL) {
137 HDF_LOGI("deviceObject is NULL.");
138 pthread_rwlock_unlock(&g_rwLock);
139 return;
140 }
141 g_stop = 1;
142 struct HdfEthernetStubData *stubData = HdfEthernetStubDriver();
143 if (stubData == NULL) {
144 HDF_LOGE("%{public}s: stubData is NUll!", __func__);
145 pthread_rwlock_unlock(&g_rwLock);
146 return;
147 }
148
149 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfEthernetRemoteNode, node) {
150 DListRemove(&(pos->node));
151 OsalMemFree(pos);
152 pos = NULL;
153 }
154 OsalMutexDestroy(&stubData->mutex);
155 struct HdfEthernetInterfaceHost *ethernetHost = CONTAINER_OF(
156 deviceObject->service, struct HdfEthernetInterfaceHost, ioService);
157 StubCollectorRemoveObject(IETHERNET_INTERFACE_DESC, ethernetHost->service);
158 ethernetHost->stubObject = NULL;
159 IEthernetRelease(ethernetHost->service, true);
160 OsalMemFree(ethernetHost);
161 ethernetHost = NULL;
162 if (deviceObject->service != NULL) {
163 deviceObject->service = NULL;
164 }
165 pthread_rwlock_unlock(&g_rwLock);
166 }
167
168 struct HdfDriverEntry g_ethernetDriverEntry = {
169 .moduleVersion = 1,
170 .moduleName = "ethernet_service",
171 .Bind = HdfEthernetDriverBind,
172 .Init = HdfEthernetDriverInit,
173 .Release = HdfEthernetDriverRelease,
174 };
175
176 HDF_INIT(g_ethernetDriverEntry);
177