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