1 /*
2 * Copyright (c) 2021-2023 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 <sys/stat.h>
22 #include <osal_mem.h>
23 #include <stub_collector.h>
24 #include "v1_1/iwlan_interface.h"
25 #include "wlan_impl.h"
26
27 struct HdfWlanInterfaceHost {
28 struct IDeviceIoService ioService;
29 struct IWlanInterface *service;
30 struct HdfRemoteService **stubObject;
31 };
32
WlanInterfaceDriverDispatch(struct HdfDeviceIoClient * client,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)33 static int32_t WlanInterfaceDriverDispatch(
34 struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
35 {
36 struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF(
37 client->device->service, struct HdfWlanInterfaceHost, ioService);
38 if (wlaninterfaceHost->service == NULL || wlaninterfaceHost->stubObject == NULL) {
39 HDF_LOGE("%{public}s: invalid service obj", __func__);
40 return HDF_ERR_INVALID_OBJECT;
41 }
42
43 struct HdfRemoteService *stubObj = *wlaninterfaceHost->stubObject;
44 if (stubObj == NULL || stubObj->dispatcher == NULL || stubObj->dispatcher->Dispatch == NULL) {
45 return HDF_ERR_INVALID_OBJECT;
46 }
47
48 return stubObj->dispatcher->Dispatch((struct HdfRemoteService *)stubObj->target, cmdId, data, reply);
49 }
50
HdfWlanInterfaceDriverInit(struct HdfDeviceObject * deviceObject)51 static int HdfWlanInterfaceDriverInit(struct HdfDeviceObject *deviceObject)
52 {
53 int32_t ret;
54 HDF_LOGI("HdfWlanInterfaceDriverInit enter.");
55 struct HdfWlanStubData *stubData = HdfStubDriver();
56 DListHeadInit(&stubData->remoteListHead);
57 ret = OsalMutexInit(&stubData->mutex);
58 if (ret != HDF_SUCCESS) {
59 HDF_LOGE("%{public}s: Mutex init failed, error code: %{public}d", __func__, ret);
60 return HDF_FAILURE;
61 }
62 if (WlanInterfaceServiceInit() != HDF_SUCCESS) {
63 HDF_LOGE("%{public}s: wlan interface service init failed!", __func__);
64 OsalMutexDestroy(&stubData->mutex);
65 return HDF_FAILURE;
66 }
67 return HDF_SUCCESS;
68 }
69
HdfWlanInterfaceDriverBind(struct HdfDeviceObject * deviceObject)70 static int HdfWlanInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
71 {
72 HDF_LOGI("HdfWlanInterfaceDriverBind enter.");
73
74 int32_t ret = HdfDeviceObjectSetInterfaceDesc(deviceObject, IWLANINTERFACE_INTERFACE_DESC);
75 if (ret != HDF_SUCCESS) {
76 HDF_LOGE("failed to set interface descriptor of device object");
77 return ret;
78 }
79
80 struct HdfWlanInterfaceHost *wlaninterfaceHost =
81 (struct HdfWlanInterfaceHost *)OsalMemAlloc(sizeof(struct HdfWlanInterfaceHost));
82 if (wlaninterfaceHost == NULL) {
83 HDF_LOGE("HdfWlanInterfaceDriverBind OsalMemAlloc HdfWlanInterfaceHost failed!");
84 return HDF_FAILURE;
85 }
86
87 struct IWlanInterface *serviceImpl = IWlanInterfaceGet(true);
88 struct HdfRemoteService **stubObj = StubCollectorGetOrNewObject(IWLANINTERFACE_INTERFACE_DESC, serviceImpl);
89 if (stubObj == NULL) {
90 OsalMemFree(wlaninterfaceHost);
91 IWlanInterfaceRelease(serviceImpl, true);
92 return HDF_FAILURE;
93 }
94
95 wlaninterfaceHost->ioService.Dispatch = WlanInterfaceDriverDispatch;
96 wlaninterfaceHost->ioService.Open = NULL;
97 wlaninterfaceHost->ioService.Release = NULL;
98 wlaninterfaceHost->service = serviceImpl;
99 wlaninterfaceHost->stubObject = stubObj;
100 deviceObject->service = &wlaninterfaceHost->ioService;
101 return HDF_SUCCESS;
102 }
103
HdfWlanInterfaceDriverRelease(struct HdfDeviceObject * deviceObject)104 static void HdfWlanInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
105 {
106 HDF_LOGI("HdfWlanInterfaceDriverRelease enter.");
107 struct HdfWlanRemoteNode *pos = NULL;
108 struct HdfWlanRemoteNode *tmp = NULL;
109 struct HdfWlanStubData *stubData = HdfStubDriver();
110 if (stubData == NULL) {
111 HDF_LOGE("%{public}s: stubData is NUll!", __func__);
112 return;
113 }
114
115 DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &stubData->remoteListHead, struct HdfWlanRemoteNode, node) {
116 DListRemove(&(pos->node));
117 OsalMemFree(pos);
118 }
119 OsalMutexDestroy(&stubData->mutex);
120 struct HdfWlanInterfaceHost *wlaninterfaceHost = CONTAINER_OF(
121 deviceObject->service, struct HdfWlanInterfaceHost, ioService);
122 StubCollectorRemoveObject(IWLANINTERFACE_INTERFACE_DESC, wlaninterfaceHost->service);
123 IWlanInterfaceRelease(wlaninterfaceHost->service, true);
124 OsalMemFree(wlaninterfaceHost);
125 }
126
127 struct HdfDriverEntry g_wlaninterfaceDriverEntry = {
128 .moduleVersion = 1,
129 .moduleName = "wlan_service",
130 .Bind = HdfWlanInterfaceDriverBind,
131 .Init = HdfWlanInterfaceDriverInit,
132 .Release = HdfWlanInterfaceDriverRelease,
133 };
134
135 HDF_INIT(g_wlaninterfaceDriverEntry);