@@ -1039,12 +1039,50 @@ void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
10391039 }
10401040}
10411041
1042+ static void brcmf_escan_prep (struct brcmf_cfg80211_info * cfg ,
1043+ struct brcmf_scan_params_v2_le * params_le ,
1044+ struct cfg80211_scan_request * request );
1045+
1046+ static void brcmf_scan_params_v2_to_v1 (struct brcmf_scan_params_v2_le * params_v2_le ,
1047+ struct brcmf_scan_params_le * params_le )
1048+ {
1049+ size_t params_size ;
1050+ u32 ch ;
1051+ int n_channels , n_ssids ;
1052+
1053+ memcpy (& params_le -> ssid_le , & params_v2_le -> ssid_le ,
1054+ sizeof (params_le -> ssid_le ));
1055+ memcpy (& params_le -> bssid , & params_v2_le -> bssid ,
1056+ sizeof (params_le -> bssid ));
1057+
1058+ params_le -> bss_type = params_v2_le -> bss_type ;
1059+ params_le -> scan_type = le32_to_cpu (params_v2_le -> scan_type );
1060+ params_le -> nprobes = params_v2_le -> nprobes ;
1061+ params_le -> active_time = params_v2_le -> active_time ;
1062+ params_le -> passive_time = params_v2_le -> passive_time ;
1063+ params_le -> home_time = params_v2_le -> home_time ;
1064+ params_le -> channel_num = params_v2_le -> channel_num ;
1065+
1066+ ch = le32_to_cpu (params_v2_le -> channel_num );
1067+ n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK ;
1068+ n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT ;
1069+
1070+ params_size = sizeof (u16 ) * n_channels ;
1071+ if (n_ssids > 0 ) {
1072+ params_size = roundup (params_size , sizeof (u32 ));
1073+ params_size += sizeof (struct brcmf_ssid_le ) * n_ssids ;
1074+ }
1075+
1076+ memcpy (& params_le -> channel_list [0 ],
1077+ & params_v2_le -> channel_list [0 ], params_size );
1078+ }
1079+
10421080s32 brcmf_notify_escan_complete (struct brcmf_cfg80211_info * cfg ,
10431081 struct brcmf_if * ifp , bool aborted ,
10441082 bool fw_abort )
10451083{
10461084 struct brcmf_pub * drvr = cfg -> pub ;
1047- struct brcmf_scan_params_le params_le ;
1085+ struct brcmf_scan_params_v2_le params_v2_le ;
10481086 struct cfg80211_scan_request * scan_request ;
10491087 u64 reqid ;
10501088 u32 bucket ;
@@ -1063,20 +1101,23 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
10631101 if (fw_abort ) {
10641102 /* Do a scan abort to stop the driver's scan engine */
10651103 brcmf_dbg (SCAN , "ABORT scan in firmware\n" );
1066- memset (& params_le , 0 , sizeof (params_le ));
1067- eth_broadcast_addr (params_le .bssid );
1068- params_le .bss_type = DOT11_BSSTYPE_ANY ;
1069- params_le .scan_type = 0 ;
1070- params_le .channel_num = cpu_to_le32 (1 );
1071- params_le .nprobes = cpu_to_le32 (1 );
1072- params_le .active_time = cpu_to_le32 (-1 );
1073- params_le .passive_time = cpu_to_le32 (-1 );
1074- params_le .home_time = cpu_to_le32 (-1 );
1075- /* Scan is aborted by setting channel_list[0] to -1 */
1076- params_le .channel_list [0 ] = cpu_to_le16 (-1 );
1104+
1105+ brcmf_escan_prep (cfg , & params_v2_le , NULL );
1106+
10771107 /* E-Scan (or anyother type) can be aborted by SCAN */
1078- err = brcmf_fil_cmd_data_set (ifp , BRCMF_C_SCAN ,
1079- & params_le , sizeof (params_le ));
1108+ if (brcmf_feat_is_enabled (ifp , BRCMF_FEAT_SCAN_V2 )) {
1109+ err = brcmf_fil_cmd_data_set (ifp , BRCMF_C_SCAN ,
1110+ & params_v2_le ,
1111+ sizeof (params_v2_le ));
1112+ } else {
1113+ struct brcmf_scan_params_le params_le ;
1114+
1115+ brcmf_scan_params_v2_to_v1 (& params_v2_le , & params_le );
1116+ err = brcmf_fil_cmd_data_set (ifp , BRCMF_C_SCAN ,
1117+ & params_le ,
1118+ sizeof (params_le ));
1119+ }
1120+
10801121 if (err )
10811122 bphy_err (drvr , "Scan abort failed\n" );
10821123 }
@@ -1296,7 +1337,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
12961337}
12971338
12981339static void brcmf_escan_prep (struct brcmf_cfg80211_info * cfg ,
1299- struct brcmf_scan_params_le * params_le ,
1340+ struct brcmf_scan_params_v2_le * params_le ,
13001341 struct cfg80211_scan_request * request )
13011342{
13021343 u32 n_ssids ;
@@ -1305,9 +1346,14 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
13051346 s32 offset ;
13061347 u16 chanspec ;
13071348 char * ptr ;
1349+ int length ;
13081350 struct brcmf_ssid_le ssid_le ;
13091351
13101352 eth_broadcast_addr (params_le -> bssid );
1353+
1354+ length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE ;
1355+
1356+ params_le -> version = cpu_to_le16 (BRCMF_SCAN_PARAMS_VERSION_V2 );
13111357 params_le -> bss_type = DOT11_BSSTYPE_ANY ;
13121358 params_le -> scan_type = BRCMF_SCANTYPE_ACTIVE ;
13131359 params_le -> channel_num = 0 ;
@@ -1317,13 +1363,23 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
13171363 params_le -> home_time = cpu_to_le32 (-1 );
13181364 memset (& params_le -> ssid_le , 0 , sizeof (params_le -> ssid_le ));
13191365
1366+ /* Scan abort */
1367+ if (!request ) {
1368+ length += sizeof (u16 );
1369+ params_le -> channel_num = cpu_to_le32 (1 );
1370+ params_le -> channel_list [0 ] = cpu_to_le16 (-1 );
1371+ params_le -> length = cpu_to_le16 (length );
1372+ return ;
1373+ }
1374+
13201375 n_ssids = request -> n_ssids ;
13211376 n_channels = request -> n_channels ;
13221377
13231378 /* Copy channel array if applicable */
13241379 brcmf_dbg (SCAN , "### List of channelspecs to scan ### %d\n" ,
13251380 n_channels );
13261381 if (n_channels > 0 ) {
1382+ length += roundup (sizeof (u16 ) * n_channels , sizeof (u32 ));
13271383 for (i = 0 ; i < n_channels ; i ++ ) {
13281384 chanspec = channel_to_chanspec (& cfg -> d11inf ,
13291385 request -> channels [i ]);
@@ -1334,12 +1390,14 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
13341390 } else {
13351391 brcmf_dbg (SCAN , "Scanning all channels\n" );
13361392 }
1393+
13371394 /* Copy ssid array if applicable */
13381395 brcmf_dbg (SCAN , "### List of SSIDs to scan ### %d\n" , n_ssids );
13391396 if (n_ssids > 0 ) {
1340- offset = offsetof(struct brcmf_scan_params_le , channel_list ) +
1397+ offset = offsetof(struct brcmf_scan_params_v2_le , channel_list ) +
13411398 n_channels * sizeof (u16 );
13421399 offset = roundup (offset , sizeof (u32 ));
1400+ length += sizeof (ssid_le ) * n_ssids ,
13431401 ptr = (char * )params_le + offset ;
13441402 for (i = 0 ; i < n_ssids ; i ++ ) {
13451403 memset (& ssid_le , 0 , sizeof (ssid_le ));
@@ -1357,8 +1415,9 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
13571415 }
13581416 } else {
13591417 brcmf_dbg (SCAN , "Performing passive scan\n" );
1360- params_le -> scan_type = BRCMF_SCANTYPE_PASSIVE ;
1418+ params_le -> scan_type = cpu_to_le32 ( BRCMF_SCANTYPE_PASSIVE ) ;
13611419 }
1420+ params_le -> length = cpu_to_le16 (length );
13621421 /* Adding mask to channel numbers */
13631422 params_le -> channel_num =
13641423 cpu_to_le32 ((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT ) |
@@ -1370,8 +1429,8 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
13701429 struct cfg80211_scan_request * request )
13711430{
13721431 struct brcmf_pub * drvr = cfg -> pub ;
1373- s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1374- offsetof(struct brcmf_escan_params_le , params_le );
1432+ s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1433+ offsetof(struct brcmf_escan_params_le , params_v2_le );
13751434 struct brcmf_escan_params_le * params ;
13761435 s32 err = 0 ;
13771436
@@ -1391,8 +1450,22 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
13911450 goto exit ;
13921451 }
13931452 BUG_ON (params_size + sizeof ("escan" ) >= BRCMF_DCMD_MEDLEN );
1394- brcmf_escan_prep (cfg , & params -> params_le , request );
1395- params -> version = cpu_to_le32 (BRCMF_ESCAN_REQ_VERSION );
1453+ brcmf_escan_prep (cfg , & params -> params_v2_le , request );
1454+
1455+ params -> version = cpu_to_le32 (BRCMF_ESCAN_REQ_VERSION_V2 );
1456+
1457+ if (!brcmf_feat_is_enabled (ifp , BRCMF_FEAT_SCAN_V2 )) {
1458+ struct brcmf_escan_params_le * params_v1 ;
1459+
1460+ params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE ;
1461+ params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE ;
1462+ params_v1 = kzalloc (params_size , GFP_KERNEL );
1463+ params_v1 -> version = cpu_to_le32 (BRCMF_ESCAN_REQ_VERSION );
1464+ brcmf_scan_params_v2_to_v1 (& params -> params_v2_le , & params_v1 -> params_le );
1465+ kfree (params );
1466+ params = params_v1 ;
1467+ }
1468+
13961469 params -> action = cpu_to_le16 (WL_ESCAN_ACTION_START );
13971470 params -> sync_id = cpu_to_le16 (0x1234 );
13981471
0 commit comments