• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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 
16 #include <cerrno>
17 #include <cstdint>
18 #include <fcntl.h>
19 #include <sys/socket.h>
20 #include <netlink/genl/genl.h>
21 #include <netlink/genl/family.h>
22 #include <netlink/genl/ctrl.h>
23 #include <linux/rtnetlink.h>
24 #include <netpacket/packet.h>
25 #include <linux/filter.h>
26 #include <linux/errqueue.h>
27 #include <linux/pkt_sched.h>
28 #include <netlink/object-api.h>
29 #include <netlink/netlink.h>
30 #include <netlink/socket.h>
31 #include <unistd.h>
32 #include "sync.h"
33 #include "wifi_hal.h"
34 #include "common.h"
35 #include "cpp_bindings.h"
36 #include <sys/stat.h>
37 
38 #define ARRAYSIZE(a)    (unsigned char)(sizeof(a) / sizeof((a)[0]))
39 
40 #define HAL_VERSION "DEFAULT vendor HAL"
41 
42 typedef enum {
43     LOGGER_ATTRIBUTE_INVALID            = 0,
44     LOGGER_ATTRIBUTE_DRIVER_VER         = 1,
45     LOGGER_ATTRIBUTE_FW_VER         = 2,
46     LOGGER_ATTRIBUTE_RING_ID            = 3,
47     LOGGER_ATTRIBUTE_RING_NAME          = 4,
48     LOGGER_ATTRIBUTE_RING_FLAGS         = 5,
49     LOGGER_ATTRIBUTE_LOG_LEVEL          = 6,
50     LOGGER_ATTRIBUTE_LOG_TIME_INTVAL        = 7,
51     LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE      = 8,
52     LOGGER_ATTRIBUTE_FW_DUMP_LEN        = 9,
53     LOGGER_ATTRIBUTE_FW_DUMP_DATA       = 10,
54     LOGGER_ATTRIBUTE_FW_ERR_CODE        = 11,
55     LOGGER_ATTRIBUTE_RING_DATA           = 12,
56     LOGGER_ATTRIBUTE_RING_STATUS        = 13,
57     LOGGER_ATTRIBUTE_RING_NUM           = 14,
58     LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN        = 15,
59     LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA       = 16,
60     LOGGER_ATTRIBUTE_PKT_FATE_NUM       = 17,
61     LOGGER_ATTRIBUTE_PKT_FATE_DATA      = 18,
62     LOGGER_ATTRIBUTE_HANG_REASON        = 19,
63     /* Add new attributes just above this */
64     LOGGER_ATTRIBUTE_MAX
65 } LOGGER_ATTRIBUTE;
66 
67 constexpr int32_t HAL_RESTART_ID = 2;
68 
69 class SetRestartHandler : public WifiCommand {
70     VendorHalRestartHandler mHandler;
71     char *mBuff;
72 public:
SetRestartHandler(wifiHandle handle,int id,VendorHalRestartHandler handler)73     SetRestartHandler(wifiHandle handle, int id, VendorHalRestartHandler handler)
74         : WifiCommand("SetRestartHandler", handle, id), mHandler(handler), mBuff(nullptr)
75     { }
Start()76     int Start()
77     {
78         HDF_LOGI("Start Restart Handler");
79         RegisterVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED);
80         return HAL_SUCCESS;
81     }
Cancel()82     int Cancel() override
83     {
84         HDF_LOGI("Clear Restart Handler");
85 
86         /* unregister alert handler */
87         UnregisterVendorHandler(BRCM_OUI, BRCM_VENDOR_EVENT_HANGED);
88         WifiUnregisterCmd(WifiHandle(), Id());
89         HDF_LOGI("Success to clear restarthandler");
90         return HAL_SUCCESS;
91     }
92 
HandleResponse(WifiEvent & reply)93     int HandleResponse(WifiEvent& reply) override
94     {
95         /* Nothing to do on response! */
96         return NL_OK;
97     }
98 
HandleEvent(WifiEvent & event)99     int HandleEvent(WifiEvent& event) override
100     {
101         nlattr *vendorData = event.GetAttribute(NL80211_ATTR_VENDOR_DATA);
102         int len = event.GetVendorDataLen();
103         int eventId = event.GetVendorSubcmd();
104         HDF_LOGI("Got event: %d", eventId);
105 
106         if (vendorData == nullptr || len == 0) {
107             HDF_LOGE("No Debug data found");
108             return NL_SKIP;
109         }
110         if (eventId == BRCM_VENDOR_EVENT_HANGED) {
111             for (NlIterator it(vendorData); it.HasNext(); it.Next()) {
112                 if (it.GetType() == LOGGER_ATTRIBUTE_HANG_REASON) {
113                     mBuff = (char *)it.GetData();
114                 } else {
115                     HDF_LOGI("Ignoring invalid attribute type = %d, size = %d",
116                         it.GetType(), it.GetLen());
117                 }
118             }
119 
120             if (*mHandler.onVendorHalRestart) {
121                 (*mHandler.onVendorHalRestart)(mBuff);
122                 HDF_LOGI("Hang event received.");
123             } else {
124                 HDF_LOGI("No Restart handler registered");
125             }
126         }
127         return NL_OK;
128     }
129 };
130 
131 class SubSystemRestart : public WifiCommand {
132 public:
SubSystemRestart(wifiInterfaceHandle iface)133     explicit SubSystemRestart(wifiInterfaceHandle iface)
134         : WifiCommand("SubSystemRestart", iface, 0)
135     { }
136 
CreateRequest(WifiRequest & request)137     int CreateRequest(WifiRequest& request)
138     {
139         int result = request.Create(HAL_OUI, WIFI_SUBCMD_TRIGGER_SSR);
140         if (result < 0) {
141             return result;
142         }
143 
144         nlattr *data = request.AttrStart(NL80211_ATTR_VENDOR_DATA);
145 
146         request.AttrEnd(data);
147         return HAL_SUCCESS;
148     }
149 
Create()150     int Create() override
151     {
152         WifiRequest request(FamilyId(), IfaceId());
153 
154         int result = CreateRequest(request);
155         if (result < 0) {
156             HDF_LOGE("Failed to create ssr request result = %d\n", result);
157             return result;
158         }
159 
160         result = RequestResponse(request);
161         if (result != HAL_SUCCESS) {
162             HDF_LOGE("Failed to register ssr response; result = %d\n", result);
163         }
164         return result;
165     }
166 
167 protected:
HandleResponse(WifiEvent & reply)168     int HandleResponse(WifiEvent& reply) override
169     {
170         /* Nothing to do on response! */
171         return NL_OK;
172     }
173 
HandleEvent(WifiEvent & event)174     int HandleEvent(WifiEvent& event) override
175     {
176         /* NO events to handle here! */
177         return NL_SKIP;
178     }
179 };
180 
VendorHalSetRestartHandler(wifiHandle handle,VendorHalRestartHandler handler)181 WifiError VendorHalSetRestartHandler(wifiHandle handle, VendorHalRestartHandler handler)
182 {
183     HalInfo *info = nullptr;
184 
185     info = (HalInfo *)handle;
186     if (info == nullptr) {
187         HDF_LOGE("Could not find hal info\n");
188         return HAL_UNKNOWN;
189     }
190 
191     SetRestartHandler *cmd = new SetRestartHandler(handle, HAL_RESTART_ID, handler);
192     NULL_CHECK_RETURN(cmd, "memory allocation failure", HAL_OUT_OF_MEMORY);
193     WifiError result = WifiRegisterCmd(handle, HAL_RESTART_ID, cmd);
194     if (result != HAL_SUCCESS) {
195         cmd->ReleaseRef();
196         return result;
197     }
198 
199     result = (WifiError)cmd->Start();
200     if (result != HAL_SUCCESS) {
201         WifiUnregisterCmd(handle, HAL_RESTART_ID);
202         cmd->ReleaseRef();
203         return result;
204     }
205 
206     /* Cache the handler to use it for trigger subsystem restart */
207     HDF_LOGI("Register SSR handler");
208     info->restartHandler = handler;
209     return result;
210 }
211 
TriggerVendorHalRestart(wifiHandle handle)212 WifiError TriggerVendorHalRestart(wifiHandle handle)
213 {
214     WifiError result = HAL_SUCCESS;
215     HalInfo *info = nullptr;
216     char errorStr[20];
217     SubSystemRestart *cmd = nullptr;
218     wifiInterfaceHandle *ifaceHandles = nullptr;
219     wifiInterfaceHandle wlan0Handle;
220     int numIfaceHandles = 0;
221 
222     info = (HalInfo *)handle;
223     if (handle == NULL || info == nullptr) {
224         HDF_LOGE("Could not find hal info\n");
225         result = HAL_UNKNOWN;
226         goto exit;
227     }
228 
229     HDF_LOGI("Trigger subsystem restart\n");
230 
231     wlan0Handle = WifiGetWlanInterface((wifiHandle)handle, ifaceHandles, numIfaceHandles);
232 
233     cmd = new SubSystemRestart(wlan0Handle);
234     NULL_CHECK_RETURN(cmd, "memory allocation failure", HAL_OUT_OF_MEMORY);
235 
236     result = (WifiError)cmd->Create();
237     if (result != HAL_SUCCESS) {
238         cmd->ReleaseRef();
239         if (strncpy_s(errorStr, sizeof(errorStr), "HAL_UNKNOWN", sizeof("HAL_UNKNOWN")) != EOK) {
240             return result;
241         }
242         HDF_LOGE("Failed to create SSR");
243         return result;
244     }
245 
246     if (strncpy_s(errorStr, sizeof(errorStr), "HAL_SUCCESS", sizeof("HAL_SUCCESS")) != EOK) {
247         goto exit;
248     }
249 
250 exit:
251     if (cmd != nullptr) {
252         cmd->ReleaseRef();
253     }
254     if (info->restartHandler.onVendorHalRestart) {
255         HDF_LOGI("Trigger ssr handler registered handler");
256         (info->restartHandler.onVendorHalRestart)(errorStr);
257     } else {
258         HDF_LOGI("No trigger ssr handler registered");
259     }
260     return result;
261 }