1 /****************************************************************************
3 * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
7 #include <scsc/scsc_logring.h>
13 #ifdef CONFIG_SCSC_SMAPPER
14 #include "hip4_smapper.h"
17 /* SAP implementations container. Local and static to hip */
18 static struct hip_sap
{
19 struct sap_api
*sap
[SAP_TOTAL
];
22 /* Register SAP with HIP layer */
23 int slsi_hip_sap_register(struct sap_api
*sap_api
)
25 u8
class = sap_api
->sap_class
;
27 if (class >= SAP_TOTAL
)
30 hip_sap_cont
.sap
[class] = sap_api
;
35 /* UNregister SAP with HIP layer */
36 int slsi_hip_sap_unregister(struct sap_api
*sap_api
)
38 u8
class = sap_api
->sap_class
;
40 if (class >= SAP_TOTAL
)
43 hip_sap_cont
.sap
[class] = NULL
;
48 int slsi_hip_sap_setup(struct slsi_dev
*sdev
)
50 /* Execute callbacks to intorm Supported version */
52 u32 conf_hip4_ver
= 0;
54 conf_hip4_ver
= scsc_wifi_get_hip_config_version(&sdev
->hip4_inst
.hip_control
->init
);
56 /* We enforce that all the SAPs are registered at this point */
57 if ((!hip_sap_cont
.sap
[SAP_MLME
]) || (!hip_sap_cont
.sap
[SAP_MA
]) ||
58 (!hip_sap_cont
.sap
[SAP_DBG
]) || (!hip_sap_cont
.sap
[SAP_TST
]))
61 if (hip_sap_cont
.sap
[SAP_MLME
]->sap_version_supported
) {
62 if (conf_hip4_ver
== 4)
63 version
= scsc_wifi_get_hip_config_version_4_u16(&sdev
->hip4_inst
.hip_control
->config_v4
, sap_mlme_ver
);
64 if (conf_hip4_ver
== 5)
65 version
= scsc_wifi_get_hip_config_version_5_u16(&sdev
->hip4_inst
.hip_control
->config_v5
, sap_mlme_ver
);
66 if (hip_sap_cont
.sap
[SAP_MLME
]->sap_version_supported(version
))
72 if (hip_sap_cont
.sap
[SAP_MA
]->sap_version_supported
) {
73 if (conf_hip4_ver
== 4)
74 version
= scsc_wifi_get_hip_config_version_4_u16(&sdev
->hip4_inst
.hip_control
->config_v4
, sap_ma_ver
);
75 if (conf_hip4_ver
== 5)
76 version
= scsc_wifi_get_hip_config_version_5_u16(&sdev
->hip4_inst
.hip_control
->config_v5
, sap_ma_ver
);
77 if (hip_sap_cont
.sap
[SAP_MA
]->sap_version_supported(version
))
83 if (hip_sap_cont
.sap
[SAP_DBG
]->sap_version_supported
) {
84 if (conf_hip4_ver
== 4)
85 version
= scsc_wifi_get_hip_config_version_4_u16(&sdev
->hip4_inst
.hip_control
->config_v4
, sap_debug_ver
);
86 if (conf_hip4_ver
== 5)
87 version
= scsc_wifi_get_hip_config_version_5_u16(&sdev
->hip4_inst
.hip_control
->config_v5
, sap_debug_ver
);
88 if (hip_sap_cont
.sap
[SAP_DBG
]->sap_version_supported(version
))
94 if (hip_sap_cont
.sap
[SAP_TST
]->sap_version_supported
) {
95 if (conf_hip4_ver
== 4)
96 version
= scsc_wifi_get_hip_config_version_4_u16(&sdev
->hip4_inst
.hip_control
->config_v4
, sap_test_ver
);
97 if (conf_hip4_ver
== 5)
98 version
= scsc_wifi_get_hip_config_version_5_u16(&sdev
->hip4_inst
.hip_control
->config_v5
, sap_test_ver
);
99 if (hip_sap_cont
.sap
[SAP_TST
]->sap_version_supported(version
))
109 static int slsi_hip_service_notifier(struct notifier_block
*nb
, unsigned long event
, void *data
)
111 struct slsi_dev
*sdev
= (struct slsi_dev
*)data
;
117 /* We enforce that all the SAPs are registered at this point */
118 if ((!hip_sap_cont
.sap
[SAP_MLME
]) || (!hip_sap_cont
.sap
[SAP_MA
]) ||
119 (!hip_sap_cont
.sap
[SAP_DBG
]) || (!hip_sap_cont
.sap
[SAP_TST
]))
122 /* Check whether any sap is interested in the notifications */
123 for (i
= 0; i
< SAP_TOTAL
; i
++)
124 if (hip_sap_cont
.sap
[i
]->sap_notifier
) {
125 if (hip_sap_cont
.sap
[i
]->sap_notifier(sdev
, event
))
131 SLSI_INFO(sdev
, "Freeze HIP4\n");
132 mutex_lock(&sdev
->hip
.hip_mutex
);
133 hip4_freeze(&sdev
->hip4_inst
);
134 mutex_unlock(&sdev
->hip
.hip_mutex
);
137 case SCSC_WIFI_FAILURE_RESET
:
138 SLSI_INFO(sdev
, "Set HIP4 up again\n");
139 mutex_lock(&sdev
->hip
.hip_mutex
);
140 hip4_setup(&sdev
->hip4_inst
);
141 mutex_unlock(&sdev
->hip
.hip_mutex
);
144 case SCSC_WIFI_SUSPEND
:
145 SLSI_INFO(sdev
, "Suspend HIP4\n");
146 mutex_lock(&sdev
->hip
.hip_mutex
);
147 hip4_suspend(&sdev
->hip4_inst
);
148 mutex_unlock(&sdev
->hip
.hip_mutex
);
151 case SCSC_WIFI_RESUME
:
152 SLSI_INFO(sdev
, "Resume HIP4\n");
153 mutex_lock(&sdev
->hip
.hip_mutex
);
154 hip4_resume(&sdev
->hip4_inst
);
155 mutex_unlock(&sdev
->hip
.hip_mutex
);
158 case SCSC_WIFI_SUBSYSTEM_RESET
:
159 case SCSC_WIFI_CHIP_READY
:
163 SLSI_INFO(sdev
, "Unknown event code %lu\n", event
);
170 static struct notifier_block cm_nb
= {
171 .notifier_call
= slsi_hip_service_notifier
,
174 int slsi_hip_init(struct slsi_dev
*sdev
, struct device
*dev
)
176 SLSI_UNUSED_PARAMETER(dev
);
178 memset(&sdev
->hip4_inst
, 0, sizeof(sdev
->hip4_inst
));
180 sdev
->hip
.sdev
= sdev
;
181 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STOPPED
);
182 mutex_init(&sdev
->hip
.hip_mutex
);
184 /* Register with the service notifier to receiver
185 * asynchronus messages such as SCSC_WIFI_STOP(Freeze), SCSC_WIFI_FAILURE_RESET i
187 slsi_wlan_service_notifier_register(&cm_nb
);
192 void slsi_hip_deinit(struct slsi_dev
*sdev
)
194 slsi_wlan_service_notifier_unregister(&cm_nb
);
195 mutex_destroy(&sdev
->hip
.hip_mutex
);
198 int slsi_hip_start(struct slsi_dev
*sdev
)
200 if (!sdev
->maxwell_core
) {
201 SLSI_ERR(sdev
, "Maxwell core does not exist\n");
205 SLSI_DBG4(sdev
, SLSI_HIP_INIT_DEINIT
, "[1/3]. Update HIP state (SLSI_HIP_STATE_STARTING)\n");
206 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STARTING
);
208 SLSI_DBG4(sdev
, SLSI_HIP_INIT_DEINIT
, "[2/3]. Initialise HIP\n");
209 if (hip4_init(&sdev
->hip4_inst
)) {
210 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STOPPED
);
211 SLSI_ERR(sdev
, "hip4_init failed\n");
215 SLSI_DBG4(sdev
, SLSI_HIP_INIT_DEINIT
, "[3/3]. Update HIP state (SLSI_HIP_STATE_STARTED)\n");
216 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STARTED
);
222 int slsi_hip_rx(struct slsi_dev
*sdev
, struct sk_buff
*skb
)
226 /* We enforce that all the SAPs are registered at this point */
227 if ((!hip_sap_cont
.sap
[SAP_MLME
]) || (!hip_sap_cont
.sap
[SAP_MA
]) ||
228 (!hip_sap_cont
.sap
[SAP_DBG
]) || (!hip_sap_cont
.sap
[SAP_TST
]))
231 /* Here we push a copy of the bare RECEIVED skb data also to the
232 * logring as a binary record.
233 * Note that bypassing UDI subsystem as a whole means we are losing:
234 * UDI filtering / UDI Header INFO / UDI QueuesFrames Throttling /
235 * UDI Skb Asynchronous processing
236 * We keep split DATA/CTRL path.
239 SCSC_BIN_TAG_DEBUG(BIN_WIFI_DATA_RX
, skb
->data
, skb
->len
);
241 SCSC_BIN_TAG_DEBUG(BIN_WIFI_CTRL_RX
, skb
->data
, skb
->len
);
242 /* Udi test : If pid in UDI range then pass to UDI and ignore */
243 slsi_log_clients_log_signal_fast(sdev
, &sdev
->log_clients
, skb
, SLSI_LOG_DIRECTION_TO_HOST
);
244 pid
= fapi_get_u16(skb
, receiver_pid
);
245 if (pid
>= SLSI_TX_PROCESS_ID_UDI_MIN
&& pid
<= SLSI_TX_PROCESS_ID_UDI_MAX
) {
251 return hip_sap_cont
.sap
[SAP_MA
]->sap_handler(sdev
, skb
);
253 if (fapi_is_mlme(skb
))
254 return hip_sap_cont
.sap
[SAP_MLME
]->sap_handler(sdev
, skb
);
256 if (fapi_is_debug(skb
))
257 return hip_sap_cont
.sap
[SAP_DBG
]->sap_handler(sdev
, skb
);
259 if (fapi_is_test(skb
))
260 return hip_sap_cont
.sap
[SAP_TST
]->sap_handler(sdev
, skb
);
265 /* Only DATA plane will look at the returning FB to account BoT */
266 int slsi_hip_tx_done(struct slsi_dev
*sdev
, u16 colour
)
268 return hip_sap_cont
.sap
[SAP_MA
]->sap_txdone(sdev
, colour
);
271 int slsi_hip_setup(struct slsi_dev
*sdev
)
273 /* Setup hip4 after initialization */
274 return hip4_setup(&sdev
->hip4_inst
);
277 #ifdef CONFIG_SCSC_SMAPPER
278 int slsi_hip_consume_smapper_entry(struct slsi_dev
*sdev
, struct sk_buff
*skb
)
280 return hip4_smapper_consume_entry(sdev
, &sdev
->hip4_inst
, skb
);
283 struct sk_buff
*slsi_hip_get_skb_from_smapper(struct slsi_dev
*sdev
, struct sk_buff
*skb
)
285 return hip4_smapper_get_skb(sdev
, &sdev
->hip4_inst
, skb
);
288 void *slsi_hip_get_skb_data_from_smapper(struct slsi_dev
*sdev
, struct sk_buff
*skb
)
290 return hip4_smapper_get_skb_data(sdev
, &sdev
->hip4_inst
, skb
);
294 int slsi_hip_stop(struct slsi_dev
*sdev
)
296 mutex_lock(&sdev
->hip
.hip_mutex
);
297 SLSI_DBG4(sdev
, SLSI_HIP_INIT_DEINIT
, "Update HIP state (SLSI_HIP_STATE_STOPPING)\n");
298 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STOPPING
);
300 hip4_deinit(&sdev
->hip4_inst
);
302 SLSI_DBG4(sdev
, SLSI_HIP_INIT_DEINIT
, "Update HIP state (SLSI_HIP_STATE_STOPPED)\n");
303 atomic_set(&sdev
->hip
.hip_state
, SLSI_HIP_STATE_STOPPED
);
305 mutex_unlock(&sdev
->hip
.hip_mutex
);