diff options
Diffstat (limited to 'SOURCES')
37 files changed, 1256 insertions, 4563 deletions
diff --git a/SOURCES/0001-amd-hdr.patch b/SOURCES/0001-amd-hdr.patch index 7e0717f..6c0deff 100644 --- a/SOURCES/0001-amd-hdr.patch +++ b/SOURCES/0001-amd-hdr.patch @@ -1,17 +1,18 @@ -From 414938db7a335d0ba6579abf402cfaafdc98bae7 Mon Sep 17 00:00:00 2001 -From: Peter Jung <admin@ptr1337.dev> -Date: Wed, 29 Nov 2023 19:55:12 +0100 -Subject: [PATCH 1/7] amd-hdr +From a890fe8f821eab96408c2263320e1106d5263f10 Mon Sep 17 00:00:00 2001 +From: Thomas Crider <gloriouseggroll@gmail.com> +Date: Wed, 6 Dec 2023 17:09:52 -0500 +Subject: [PATCH] hdr -Signed-off-by: Peter Jung <admin@ptr1337.dev> --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 71 ++ - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 34 +- + drivers/gpu/drm/amd/display/Kconfig | 7 + + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 35 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 100 +++ - .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 805 ++++++++++++++++-- + .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 812 ++++++++++++++++-- .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 72 ++ - .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 224 ++++- - .../amd/display/dc/dcn10/dcn10_cm_common.c | 95 ++- + .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 234 ++++- + .../amd/display/dc/dcn10/dcn10_cm_common.c | 95 +- + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 14 +- .../drm/amd/display/dc/dcn30/dcn30_hwseq.c | 37 + .../drm/amd/display/dc/dcn30/dcn30_hwseq.h | 3 + .../drm/amd/display/dc/dcn301/dcn301_init.c | 2 +- @@ -24,10 +25,10 @@ Signed-off-by: Peter Jung <admin@ptr1337.dev> include/drm/drm_plane.h | 7 + include/drm/drm_property.h | 6 + include/uapi/drm/drm_mode.h | 8 + - 19 files changed, 1441 insertions(+), 90 deletions(-) + 21 files changed, 1473 insertions(+), 97 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h -index 32fe05c810c6f..84bf501b02f4c 100644 +index 32fe05c81..84bf501b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -343,6 +343,77 @@ struct amdgpu_mode_info { @@ -108,15 +109,39 @@ index 32fe05c810c6f..84bf501b02f4c 100644 }; #define AMDGPU_MAX_BL_LEVEL 0xFF +diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig +index 901d1961b..49523fa82 100644 +--- a/drivers/gpu/drm/amd/display/Kconfig ++++ b/drivers/gpu/drm/amd/display/Kconfig +@@ -51,4 +51,11 @@ config DRM_AMD_SECURE_DISPLAY + This option enables the calculation of crc of specific region via + debugfs. Cooperate with specific DMCU FW. + ++config DRM_AMD_COLOR_STEAMDECK ++ bool "Enable color calibration features for Steam Deck" ++ depends on DRM_AMD_DC ++ help ++ Choose this option if you want to use AMDGPU features for broader ++ color management support on Steam Deck. ++ + endmenu diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index deedcd9978459..572c71a54df42 100644 +index deedcd997..ccd99545b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -4022,6 +4022,11 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) +@@ -2963,6 +2963,7 @@ static int dm_resume(void *handle) + dc_stream_release(dm_new_crtc_state->stream); + dm_new_crtc_state->stream = NULL; + } ++ dm_new_crtc_state->base.color_mgmt_changed = true; + } + + for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) { +@@ -4022,6 +4023,11 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) return r; } -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK + if (amdgpu_dm_create_color_properties(adev)) + return -ENOMEM; +#endif @@ -124,7 +149,7 @@ index deedcd9978459..572c71a54df42 100644 r = amdgpu_dm_audio_init(adev); if (r) { dc_release_state(state->context); -@@ -5094,7 +5099,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, +@@ -5094,7 +5100,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, * Always set input transfer function, since plane state is refreshed * every time. */ @@ -135,7 +160,7 @@ index deedcd9978459..572c71a54df42 100644 if (ret) return ret; -@@ -8117,6 +8124,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, +@@ -8117,6 +8125,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction; bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func; bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; @@ -146,7 +171,7 @@ index deedcd9978459..572c71a54df42 100644 } amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, -@@ -8328,6 +8339,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, +@@ -8328,6 +8340,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, &acrtc_state->stream->csc_color_matrix; bundle->stream_update.out_transfer_func = acrtc_state->stream->out_transfer_func; @@ -157,7 +182,7 @@ index deedcd9978459..572c71a54df42 100644 } acrtc_state->stream->abm_level = acrtc_state->abm_level; -@@ -9516,6 +9531,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, +@@ -9516,6 +9532,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, * when a modeset is needed, to ensure it gets reprogrammed. */ if (dm_new_crtc_state->base.color_mgmt_changed || @@ -165,7 +190,7 @@ index deedcd9978459..572c71a54df42 100644 drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state); if (ret) -@@ -9583,6 +9599,10 @@ static bool should_reset_plane(struct drm_atomic_state *state, +@@ -9583,6 +9600,10 @@ static bool should_reset_plane(struct drm_atomic_state *state, */ for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) { struct amdgpu_framebuffer *old_afb, *new_afb; @@ -176,7 +201,7 @@ index deedcd9978459..572c71a54df42 100644 if (other->type == DRM_PLANE_TYPE_CURSOR) continue; -@@ -9619,6 +9639,18 @@ static bool should_reset_plane(struct drm_atomic_state *state, +@@ -9619,6 +9640,18 @@ static bool should_reset_plane(struct drm_atomic_state *state, old_other_state->color_encoding != new_other_state->color_encoding) return true; @@ -196,7 +221,7 @@ index deedcd9978459..572c71a54df42 100644 if (!old_other_state->fb || !new_other_state->fb) continue; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h -index 9e4cc5eeda767..24c87f425afbb 100644 +index 9e4cc5eed..24c87f425 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -33,6 +33,8 @@ @@ -339,7 +364,7 @@ index 9e4cc5eeda767..24c87f425afbb 100644 void amdgpu_dm_update_connector_after_detect( diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c -index a4cb23d059bd6..0442eeaa97637 100644 +index a4cb23d05..10fef576c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -72,6 +72,7 @@ @@ -354,7 +379,7 @@ index a4cb23d059bd6..0442eeaa97637 100644 setup_x_points_distribution(); } -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK +/* Pre-defined Transfer Functions (TF) + * + * AMD driver supports pre-defined mathematical functions for transferring @@ -462,54 +487,54 @@ index a4cb23d059bd6..0442eeaa97637 100644 + + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_DEGAMMA_LUT", 0); ++ "VALVE1_PLANE_DEGAMMA_LUT", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_degamma_lut_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX); ++ "VALVE1_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_degamma_lut_size_property = prop; + + prop = amdgpu_create_tf_property(adev_to_drm(adev), -+ "AMD_PLANE_DEGAMMA_TF", ++ "VALVE1_PLANE_DEGAMMA_TF", + amdgpu_eotf); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_degamma_tf_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), -+ 0, "AMD_PLANE_HDR_MULT", 0, U64_MAX); ++ 0, "VALVE1_PLANE_HDR_MULT", 0, U64_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_hdr_mult_property = prop; + + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_CTM", 0); ++ "VALVE1_PLANE_CTM", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_ctm_property = prop; + + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_SHAPER_LUT", 0); ++ "VALVE1_PLANE_SHAPER_LUT", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); ++ "VALVE1_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_size_property = prop; + + prop = amdgpu_create_tf_property(adev_to_drm(adev), -+ "AMD_PLANE_SHAPER_TF", ++ "VALVE1_PLANE_SHAPER_TF", + amdgpu_inv_eotf); + if (!prop) + return -ENOMEM; @@ -517,41 +542,41 @@ index a4cb23d059bd6..0442eeaa97637 100644 + + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_LUT3D", 0); ++ "VALVE1_PLANE_LUT3D", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_lut3d_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX); ++ "VALVE1_PLANE_LUT3D_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_lut3d_size_property = prop; + + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, -+ "AMD_PLANE_BLEND_LUT", 0); ++ "VALVE1_PLANE_BLEND_LUT", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_blend_lut_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, -+ "AMD_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX); ++ "VALVE1_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_blend_lut_size_property = prop; + + prop = amdgpu_create_tf_property(adev_to_drm(adev), -+ "AMD_PLANE_BLEND_TF", ++ "VALVE1_PLANE_BLEND_TF", + amdgpu_eotf); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_blend_tf_property = prop; + + prop = amdgpu_create_tf_property(adev_to_drm(adev), -+ "AMD_CRTC_REGAMMA_TF", ++ "VALVE1_CRTC_REGAMMA_TF", + amdgpu_inv_eotf); + if (!prop) + return -ENOMEM; @@ -583,8 +608,7 @@ index a4cb23d059bd6..0442eeaa97637 100644 + matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]); + } +} - -- matrix[i].value = val; ++ +/** + * __drm_ctm2_to_dc_matrix - converts a DRM CTM2 to a DC CSC float matrix + * @ctm: DRM color transformation matrix @@ -596,7 +620,8 @@ index a4cb23d059bd6..0442eeaa97637 100644 + struct fixed31_32 *matrix) +{ + int i; -+ + +- matrix[i].value = val; + /* + * DRM gives a 3x3 matrix, but DC wants 3x4. Assuming we're operating + * with homogeneous coordinates, augment the matrix with 0's. @@ -729,15 +754,15 @@ index a4cb23d059bd6..0442eeaa97637 100644 - gamma->num_entries = lut_size; + gamma->type = GAMMA_CUSTOM; + gamma->num_entries = lut_size; - -- __drm_lut_to_dc_gamma(lut, gamma, false); ++ + __drm_lut_to_dc_gamma(lut, gamma, false); + } +- __drm_lut_to_dc_gamma(lut, gamma, false); ++ res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != NULL); + - res = mod_color_calculate_degamma_params(NULL, func, gamma, true); - dc_gamma_release(&gamma); -+ res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != NULL); -+ + if (gamma) + dc_gamma_release(&gamma); @@ -1064,7 +1089,7 @@ index a4cb23d059bd6..0442eeaa97637 100644 /* * For legacy gamma support we need the regamma input * in linear space. Assume that the input is sRGB. -@@ -577,14 +1053,213 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, +@@ -577,14 +1053,220 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, dc_plane_state->in_transfer_func->tf = tf; if (tf != TRANSFER_FUNCTION_SRGB && @@ -1145,8 +1170,15 @@ index a4cb23d059bd6..0442eeaa97637 100644 + int ret; + + /* We have nothing to do here, return */ ++ /* ++ * JoshA: WE HAVE TO DO THIS EVERY TIME. ++ * It's on a new dc_plane_state allocation, none of this data is here! ++ * !!!!!!!! ++ * This was always true before we duped properties due to LUCK and the ++ * properties matching. + if (!plane_state->color_mgmt_changed) + return 0; ++ */ + + dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult); + @@ -1285,7 +1317,7 @@ index a4cb23d059bd6..0442eeaa97637 100644 + dc_plane_state, color_caps); +} diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c -index 97b7a0b8a1c26..a05c210754d44 100644 +index 97b7a0b8a..f1707c774 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -260,6 +260,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc) @@ -1300,7 +1332,7 @@ index 97b7a0b8a1c26..a05c210754d44 100644 } #endif -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK +/** + * drm_crtc_additional_color_mgmt - enable additional color properties + * @crtc: DRM CRTC @@ -1371,7 +1403,7 @@ index 97b7a0b8a1c26..a05c210754d44 100644 #if defined(CONFIG_DEBUG_FS) .late_register = amdgpu_dm_crtc_late_register, #endif -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK + .atomic_set_property = amdgpu_dm_atomic_crtc_set_property, + .atomic_get_property = amdgpu_dm_atomic_crtc_get_property, +#endif @@ -1382,14 +1414,14 @@ index 97b7a0b8a1c26..a05c210754d44 100644 drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK + dm_crtc_additional_color_mgmt(&acrtc->base); +#endif return 0; fail: diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index cc74dd69acf2b..17719e15cbe58 100644 +index cc74dd69a..2ed20e6e4 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1333,8 +1333,14 @@ static void dm_drm_plane_reset(struct drm_plane *plane) @@ -1409,20 +1441,30 @@ index cc74dd69acf2b..17719e15cbe58 100644 } static struct drm_plane_state * -@@ -1354,6 +1360,22 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) +@@ -1354,6 +1360,32 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) dc_plane_state_retain(dm_plane_state->dc_state); } -+ if (dm_plane_state->degamma_lut) -+ drm_property_blob_get(dm_plane_state->degamma_lut); -+ if (dm_plane_state->ctm) -+ drm_property_blob_get(dm_plane_state->ctm); -+ if (dm_plane_state->shaper_lut) -+ drm_property_blob_get(dm_plane_state->shaper_lut); -+ if (dm_plane_state->lut3d) -+ drm_property_blob_get(dm_plane_state->lut3d); -+ if (dm_plane_state->blend_lut) -+ drm_property_blob_get(dm_plane_state->blend_lut); ++ if (old_dm_plane_state->degamma_lut) { ++ drm_property_blob_get(old_dm_plane_state->degamma_lut); ++ dm_plane_state->degamma_lut = old_dm_plane_state->degamma_lut; ++ } ++ if (old_dm_plane_state->ctm) { ++ drm_property_blob_get(old_dm_plane_state->ctm); ++ dm_plane_state->ctm = old_dm_plane_state->ctm; ++ } ++ if (old_dm_plane_state->shaper_lut) { ++ drm_property_blob_get(old_dm_plane_state->shaper_lut); ++ dm_plane_state->shaper_lut = old_dm_plane_state->shaper_lut; ++ } ++ if (old_dm_plane_state->lut3d) { ++ drm_property_blob_get(old_dm_plane_state->lut3d); ++ dm_plane_state->lut3d = old_dm_plane_state->lut3d; ++ } ++ if (old_dm_plane_state->blend_lut) { ++ drm_property_blob_get(old_dm_plane_state->blend_lut); ++ dm_plane_state->blend_lut = old_dm_plane_state->blend_lut; ++ } + + dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; + dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; @@ -1432,7 +1474,7 @@ index cc74dd69acf2b..17719e15cbe58 100644 return &dm_plane_state->base; } -@@ -1421,12 +1443,203 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, +@@ -1421,12 +1453,203 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, { struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); @@ -1453,7 +1495,7 @@ index cc74dd69acf2b..17719e15cbe58 100644 drm_atomic_helper_plane_destroy_state(plane, state); } -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK +static void +dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, + struct drm_plane *plane) @@ -1636,29 +1678,29 @@ index cc74dd69acf2b..17719e15cbe58 100644 static const struct drm_plane_funcs dm_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, -@@ -1435,6 +1648,10 @@ static const struct drm_plane_funcs dm_plane_funcs = { +@@ -1435,6 +1658,10 @@ static const struct drm_plane_funcs dm_plane_funcs = { .atomic_duplicate_state = dm_drm_plane_duplicate_state, .atomic_destroy_state = dm_drm_plane_destroy_state, .format_mod_supported = dm_plane_format_mod_supported, -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK + .atomic_set_property = dm_atomic_plane_set_property, + .atomic_get_property = dm_atomic_plane_get_property, +#endif }; int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, -@@ -1514,6 +1731,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, +@@ -1514,6 +1741,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, drm_plane_helper_add(plane, &dm_plane_helper_funcs); -+#ifdef AMD_PRIVATE_COLOR ++#ifdef CONFIG_DRM_AMD_COLOR_STEAMDECK + dm_atomic_plane_attach_color_mgmt_properties(dm, plane); +#endif /* Create (reset) the plane state */ if (plane->funcs->reset) plane->funcs->reset(plane); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c -index 3538973bd0c6c..04b2e04b68f33 100644 +index 3538973bd..04b2e04b6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -349,20 +349,37 @@ bool cm_helper_translate_curve_to_hw_format(struct dc_context *ctx, @@ -1775,8 +1817,46 @@ index 3538973bd0c6c..04b2e04b68f33 100644 j++; } } +diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +index 79befa17b..4daf8621b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +@@ -2486,17 +2486,17 @@ void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx) + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; + + +- if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { ++ if (pipe_ctx->plane_state && ++ pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) { + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; + for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) + adjust.temperature_matrix[i] = +- pipe_ctx->stream->gamut_remap_matrix.matrix[i]; +- } else if (pipe_ctx->plane_state && +- pipe_ctx->plane_state->gamut_remap_matrix.enable_remap == true) { ++ pipe_ctx->plane_state->gamut_remap_matrix.matrix[i]; ++ } else if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; + for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) + adjust.temperature_matrix[i] = +- pipe_ctx->plane_state->gamut_remap_matrix.matrix[i]; ++ pipe_ctx->stream->gamut_remap_matrix.matrix[i]; + } + + pipe_ctx->plane_res.dpp->funcs->dpp_set_gamut_remap(pipe_ctx->plane_res.dpp, &adjust); +@@ -2942,8 +2942,8 @@ void dcn10_program_pipe( + hws->funcs.set_hdr_multiplier(pipe_ctx); + + if (pipe_ctx->plane_state->update_flags.bits.full_update || +- pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || +- pipe_ctx->plane_state->update_flags.bits.gamma_change) ++ pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || ++ pipe_ctx->plane_state->update_flags.bits.gamma_change) + hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); + + /* dcn10_translate_regamma_to_hw_format takes 750us to finish diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c -index 255713ec29bb0..fce9b33c0f881 100644 +index 255713ec2..fce9b33c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -186,6 +186,43 @@ bool dcn30_set_input_transfer_func(struct dc *dc, @@ -1824,7 +1904,7 @@ index 255713ec29bb0..fce9b33c0f881 100644 struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h -index ce19c54097f8b..e557e2b986187 100644 +index ce19c5409..e557e2b98 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.h @@ -58,6 +58,9 @@ bool dcn30_set_blend_lut(struct pipe_ctx *pipe_ctx, @@ -1838,7 +1918,7 @@ index ce19c54097f8b..e557e2b986187 100644 struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream); diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c -index 61205cdbe2d5a..fdbe3d42cd7b6 100644 +index 61205cdbe..fdbe3d42c 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -33,7 +33,7 @@ @@ -1851,7 +1931,7 @@ index 61205cdbe2d5a..fdbe3d42cd7b6 100644 .power_down_on_boot = dcn10_power_down_on_boot, .apply_ctx_to_hw = dce110_apply_ctx_to_hw, diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h -index d4cf7ead1d877..84da1dd34efd1 100644 +index d4cf7ead1..84da1dd34 100644 --- a/drivers/gpu/drm/amd/display/include/fixed31_32.h +++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h @@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL }; @@ -1874,7 +1954,7 @@ index d4cf7ead1d877..84da1dd34efd1 100644 * @brief * Initialization routines diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c -index dc01c43f61930..d72c22dcf6855 100644 +index dc01c43f6..d72c22dcf 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -221,7 +221,7 @@ static int malidp_crtc_atomic_check_ctm(struct drm_crtc *crtc, @@ -1887,7 +1967,7 @@ index dc01c43f61930..d72c22dcf6855 100644 ctm = (struct drm_color_ctm *)state->ctm->data; for (i = 0; i < ARRAY_SIZE(ctm->matrix); ++i) { diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c -index c277b198fa3fa..c3df45f901456 100644 +index c277b198f..c3df45f90 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -733,6 +733,7 @@ static void drm_atomic_plane_print_state(struct drm_printer *p, @@ -1899,7 +1979,7 @@ index c277b198fa3fa..c3df45f901456 100644 if (plane->funcs->atomic_print_state) plane->funcs->atomic_print_state(p, state); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c -index 784e63d70a421..25bb0859fda74 100644 +index 784e63d70..25bb0859f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, @@ -1911,7 +1991,7 @@ index 784e63d70a421..25bb0859fda74 100644 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c -index dfec479830e49..f72ef6493340a 100644 +index dfec47983..f72ef6493 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -751,6 +751,55 @@ bool drm_property_replace_blob(struct drm_property_blob **blob, @@ -1971,7 +2051,7 @@ index dfec479830e49..f72ef6493340a 100644 void *data, struct drm_file *file_priv) { diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h -index 912f1e4156853..08d7a7f0188fe 100644 +index 912f1e415..08d7a7f01 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -60,7 +60,7 @@ struct drm_mode_object { @@ -1984,7 +2064,7 @@ index 912f1e4156853..08d7a7f0188fe 100644 * struct drm_object_properties - property tracking for &drm_mode_object */ diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h -index 79d62856defbf..4f87803b3ea12 100644 +index 79d62856d..4f87803b3 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -237,6 +237,13 @@ struct drm_plane_state { @@ -2002,7 +2082,7 @@ index 79d62856defbf..4f87803b3ea12 100644 static inline struct drm_rect diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h -index 65bc9710a4702..082f29156b3e3 100644 +index 65bc9710a..082f29156 100644 --- a/include/drm/drm_property.h +++ b/include/drm/drm_property.h @@ -279,6 +279,12 @@ struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, @@ -2019,7 +2099,7 @@ index 65bc9710a4702..082f29156b3e3 100644 struct drm_property_blob **replace, size_t length, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h -index ea1b639bcb288..cea5653e4020b 100644 +index ea1b639bc..cea5653e4 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -846,6 +846,14 @@ struct drm_color_ctm { diff --git a/SOURCES/0001-hid-asus-nero-patches-rogue.patch b/SOURCES/0001-hid-asus-nero-patches-rogue.patch deleted file mode 100644 index 056cd95..0000000 --- a/SOURCES/0001-hid-asus-nero-patches-rogue.patch +++ /dev/null @@ -1,940 +0,0 @@ -diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c -index fd61dba88..3220d96fc 100644 ---- a/drivers/hid/hid-asus.c -+++ b/drivers/hid/hid-asus.c -@@ -26,7 +26,9 @@ - #include <linux/dmi.h> - #include <linux/hid.h> - #include <linux/module.h> -+#include <linux/sysfs.h> - #include <linux/platform_data/x86/asus-wmi.h> -+#include <linux/platform_device.h> - #include <linux/input/mt.h> - #include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */ - #include <linux/power_supply.h> -@@ -94,6 +96,435 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); - - #define TRKID_SGN ((TRKID_MAX + 1) >> 1) - -+/* -+ * USB buffers to be used in a control transfer to make the joystick change buttons mode and scancodes -+ * 0 is default (game_mode with back buttons sending F17 and F18 instead of F15 for both as when unconfigured) -+ * 1 is mouse mode: back buttons still are F17 and F18 -+ * 2 is macro mode -+ */ -+static const u8 rc71l_mode_switch_commands[][23][64] = { -+ { -+ { -+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+ }, -+ { -+ { -+ 0x5A, 0xD1, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x99, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x02, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x02, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x02, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x96, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x0D, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+ }, -+ { -+ { -+ 0x5A, 0xD1, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x01, 0x2C, 0x01, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x8C, 0x88, 0x76, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x02, 0x2C, 0x01, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x23, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x0D, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x03, 0x2C, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x04, 0x2C, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x05, 0x2C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x05, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x31, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x06, 0x2C, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x07, 0x2C, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x08, 0x2C, 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x02, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x02, 0x09, 0x2C, 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x0F, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x06, 0x02, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x04, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ }, -+ { -+ 0x5A, 0xD1, 0x05, 0x04, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -+ } -+ } -+}; -+ - struct asus_kbd_leds { - struct led_classdev cdev; - struct hid_device *hdev; -@@ -103,6 +534,25 @@ struct asus_kbd_leds { - bool removed; - }; - -+enum rc71l_controller_mode { -+ rc71l_gamepad_mode, -+ rc71l_mouse_mode, -+ rc71l_macro_mode, -+}; -+ -+struct asus_rc71l { -+ unsigned int usb_pipe; -+ -+ struct platform_device *mcu_dev; -+ -+ struct mutex mutex; /* Mutex that protects everything below it */ -+ -+ enum rc71l_controller_mode mode; -+ -+ u8 usb_in_buf[32]; -+ u8 usb_out_buf[64]; /* A temporary buffer to hold data that gets sent over USB (must be accessed upon locking the appropriate mutex) */ -+}; -+ - struct asus_touchpad_info { - int max_x; - int max_y; -@@ -127,6 +577,7 @@ struct asus_drvdata { - int battery_stat; - bool battery_in_query; - unsigned long battery_next_query; -+ struct asus_rc71l *rc71l_data; - }; - - static int asus_report_battery(struct asus_drvdata *, u8 *, int); -@@ -189,6 +640,245 @@ static const struct asus_touchpad_info medion_e1239t_tp = { - .report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */, - }; - -+/** -+ * This function reads data over the USB device on the ROG Ally. -+ * Unlike outgoing traffic the inbound always performs 32-bytes transfers. -+ * -+ * PRE: -+ * - rc71l internal mutex MUST be locked -+ */ -+static int rc71l_usb_read(struct hid_device * hdev) { -+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev); -+ if (drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent); -+ struct usb_device *dev = interface_to_usbdev(intf); -+ -+ const int retval = usb_control_msg_recv(dev, 0x80, 0x01, 0xa1, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_in_buf[0], 32, 250, GFP_KERNEL); -+ -+ if (retval < 0) { -+ hid_err(hdev, "Ally read failed performing control read, error %d\n", retval); -+ goto rc71l_usb_read_err; -+ } -+ -+ const char* b = (const u8*)&rc71l_drvdata->usb_in_buf[0]; -+ hid_info(hdev, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", -+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], -+ b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], -+ b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], -+ b[30], b[31] -+ ); -+ -+rc71l_usb_read_err: -+ return retval; -+} -+ -+/** -+ * This function writes a command over the USB device on the ROG Ally. -+ * The ROG Ally accepts 64-bytes long messages as commands: as such at most 64-bytes will be sent -+ * and unused bytes will be zeroed out. -+ * -+ * PRE: -+ * - rc71l internal mutex MUST be locked -+ */ -+static int rc71l_usb_write(struct hid_device * hdev, const void* buf, size_t buf_sz) { -+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev); -+ -+ if (drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent); -+ struct usb_device *dev = interface_to_usbdev(intf); -+ -+ if (buf_sz > 64) { -+ hid_err(hdev, "Bug in the kernel: cannot write more than 64-bytes\n"); -+ -+ return -EINVAL; -+ } -+ -+ // make sure bytes in excess will be zeroes and copy the user-provided buffer -+ memset((void*)&rc71l_drvdata->usb_out_buf[0], 0, 64); -+ memcpy((void*)&rc71l_drvdata->usb_out_buf[0], buf, buf_sz); -+ -+ /* send the data out the bulk port */ -+ const int retval = usb_control_msg(dev, rc71l_drvdata->usb_pipe, 0x09, 0x21, 0x035A, 0x0002, (void*)&rc71l_drvdata->usb_out_buf[0], 64, 250); -+ if (retval < 0) { -+ hid_err(hdev, -+ "Failed submitting control write error %d\n", retval); -+ -+ goto rc71l_usb_write_err; -+ } -+ -+rc71l_usb_write_err: -+ return retval < 0 ? retval : 0; -+} -+ -+static int rc71l_mode_change(struct hid_device * hdev, enum rc71l_controller_mode new_mode) { -+ struct asus_drvdata *drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev); -+ if (drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ int ret = 0; -+ -+ size_t packets_group = 0; -+ switch (new_mode) { -+ case rc71l_gamepad_mode: -+ packets_group = 0; -+ break; -+ -+ case rc71l_mouse_mode: -+ packets_group = 1; -+ break; -+ -+ case rc71l_macro_mode: -+ packets_group = 2; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ for (int i = 0; (i < 23) && (ret == 0); ++i) { -+ ret = rc71l_usb_write(hdev, (const void*)&rc71l_mode_switch_commands[packets_group][i][0], 64); -+ if (ret > 0) { -+ hid_err(hdev, "Ally controller mode switch %d/23 error %d\n", i, ret); -+ goto rc71l_mode_change_err; -+ } -+ } -+ -+ // controller mode has been switched successfully: change that in driver data -+ if (ret == 0) { -+ hid_info(hdev, "ROG Ally [RC71L] controller mode switch succeeded\n"); -+ rc71l_drvdata->mode = new_mode; -+ } -+ -+rc71l_mode_change_err: -+ return ret; -+} -+ -+static ssize_t __maybe_unused mode_show(struct device *raw_dev, struct device_attribute *attr, char *buf) { -+ struct platform_device *const pdev = to_platform_device(raw_dev); -+ struct hid_device *const hdev = platform_get_drvdata(pdev); -+ if (hdev == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev); -+ if (drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ mutex_lock(&rc71l_drvdata->mutex); -+ int current_mode = 0; -+ switch (rc71l_drvdata->mode) { -+ case rc71l_gamepad_mode: -+ current_mode = 0; -+ break; -+ -+ case rc71l_mouse_mode: -+ current_mode = 1; -+ break; -+ -+ case rc71l_macro_mode: -+ current_mode = 2; -+ break; -+ -+ default: -+ mutex_unlock(&rc71l_drvdata->mutex); -+ return -EINVAL; -+ } -+ mutex_unlock(&rc71l_drvdata->mutex); -+ -+ return sysfs_emit(buf, "%d\n", (int)current_mode); -+} -+ -+static ssize_t __maybe_unused mode_store(struct device *raw_dev, struct device_attribute *attr, const char *buf, size_t count) { -+ struct platform_device *const pdev = to_platform_device(raw_dev); -+ struct hid_device *const hdev = platform_get_drvdata(pdev); -+ if (hdev == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_drvdata *const drvdata = (struct asus_drvdata*)hid_get_drvdata(hdev); -+ if (drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ struct asus_rc71l *const rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata == NULL) { -+ return -EINVAL; -+ } -+ -+ int res = -EINVAL; -+ int val = -EINVAL; -+ res = kstrtoint(buf, 0, &val); -+ if (res) -+ return res; -+ -+ switch (val) { -+ case 0: -+ mutex_lock(&rc71l_drvdata->mutex); -+ res = rc71l_mode_change(hdev, rc71l_gamepad_mode); -+ mutex_unlock(&rc71l_drvdata->mutex); -+ break; -+ -+ case 1: -+ mutex_lock(&rc71l_drvdata->mutex); -+ res = rc71l_mode_change(hdev, rc71l_mouse_mode); -+ mutex_unlock(&rc71l_drvdata->mutex); -+ break; -+ -+ case 2: -+ mutex_lock(&rc71l_drvdata->mutex); -+ res = rc71l_mode_change(hdev, rc71l_macro_mode); -+ mutex_unlock(&rc71l_drvdata->mutex); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ hid_err(hdev, "Ally controller mode switch to %d mode op result: %d\n", val, res); -+ -+ return count; -+} -+ -+DEVICE_ATTR_RW(mode); -+ -+static struct attribute *rc71l_input_attrs[] = { -+ &dev_attr_mode.attr, -+ NULL -+}; -+ -+static const struct attribute_group mcu_attr_group = { -+ .name = "input", -+ .attrs = rc71l_input_attrs, -+}; -+ - static void asus_report_contact_down(struct asus_drvdata *drvdat, - int toolType, u8 *data) - { -@@ -386,7 +1076,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size - unsigned char *dmabuf; - int ret; - -- dmabuf = kmemdup(buf, buf_size, GFP_KERNEL); -+ dmabuf = kmemdup((const void*)buf, buf_size, GFP_KERNEL); - if (!dmabuf) - return -ENOMEM; - -@@ -1000,16 +1694,108 @@ static int asus_start_multitouch(struct hid_device *hdev) - return 0; - } - -+#ifdef CONFIG_PM - static int __maybe_unused asus_reset_resume(struct hid_device *hdev) - { -+ int ret = 0; -+ - struct asus_drvdata *drvdata = hid_get_drvdata(hdev); -+ if (drvdata != NULL) { -+ return -EINVAL; -+ } - - if (drvdata->tp) - return asus_start_multitouch(hdev); - -- return 0; -+ return ret; - } - -+static int __maybe_unused asus_resume(struct hid_device *hdev) -+{ -+ int ret = 0; -+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); -+/* -+ // Controller mode is kept on device sleep -+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) -+ { -+ // Apply the joystick mode switch -+ ret = rog_ally_controller_mode_change(hdev, game_mode); -+ -+ hid_err(hdev, "Asus wake, restore controller %d\n", ret); -+ } -+*/ -+ -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata != NULL) { -+ mutex_lock(&rc71l_drvdata->mutex); -+ ret = rc71l_mode_change(hdev, rc71l_drvdata->mode); -+ mutex_unlock(&rc71l_drvdata->mutex); -+ -+ if (ret < 0) { -+ hid_err(hdev, "ROG Ally [RC71L] failed to reset controller mode: %d\n", ret); -+ goto asus_resume_err; -+ } -+ } -+ -+ -+ /* -+ * On some devices such as the Asus RC71L leds are reset to default after sleep and sysfs attribute will report -+ * something that won't be true: resetting the user-provided value is necessary to maintain coherency and avoid -+ * flashing full brightness leds in face of the user. -+ */ -+ if (drvdata->kbd_backlight) { -+ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, drvdata->kbd_backlight->cdev.brightness }; -+ ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); -+ if (ret < 0) { -+ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); -+ goto asus_resume_err; -+ } -+ -+ hid_err(hdev, "Asus ROG Ally asus_reset_resume, leds reset: %d at brightness %d\n", ret, (int)drvdata->kbd_backlight->cdev.brightness); -+ } -+ -+ asus_resume_err: -+ return ret; -+} -+ -+static int __maybe_unused asus_suspend(struct hid_device *hdev, struct pm_message) -+ { -+ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); -+ -+ if (drvdata == NULL) { -+ return 0; -+ } -+ -+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent); -+ struct usb_device *dev = interface_to_usbdev(intf); -+ -+ int ret = 0; -+ -+ if (dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) { -+ // Send the USB ABORT_PIPE command -+ int result = usb_control_msg( -+ dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE, -+ USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT, -+ USB_ENDPOINT_HALT, 0x02, NULL, 0, 1000); -+ -+ if (result < 0) { -+ printk("USB ABORT_PIPE failed: %d\n", result); -+ } else { -+ printk("USB ABORT_PIPE succeeded\n"); -+ } -+ } -+ -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata != NULL) { -+ mutex_lock(&rc71l_drvdata->mutex); -+ // TODO: send ABORT_PIPE here -+ mutex_unlock(&rc71l_drvdata->mutex); -+ } -+ -+ return ret; -+} -+#endif -+ - static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) - { - int ret; -@@ -1021,6 +1807,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) - return -ENOMEM; - } - -+ drvdata->rc71l_data = NULL; -+ - hid_set_drvdata(hdev, drvdata); - - drvdata->quirks = id->driver_data; -@@ -1109,6 +1897,51 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) - goto err_stop_hw; - } - -+ if ((dmi_match(DMI_PRODUCT_NAME, "ROG Ally RC71L_RC71L")) && (hdev->rsize > 9) && (hdev->rdesc[7] == 0x85) && (hdev->rdesc[8] == 0x5a)) -+ { -+ drvdata->rc71l_data = devm_kzalloc(&hdev->dev, sizeof(*drvdata->rc71l_data), GFP_KERNEL); -+ if (drvdata->rc71l_data == NULL) { -+ hid_err(hdev, "Can't alloc Asus ROG Ally [RC71L] descriptor\n"); -+ ret = -ENOMEM; -+ goto err_stop_hw; -+ } -+ -+ mutex_init(&drvdata->rc71l_data->mutex); -+ -+ struct usb_interface *intf = to_usb_interface(hdev->dev.parent); -+ struct usb_device *dev = interface_to_usbdev(intf); -+ -+ // default controller mode -+ drvdata->rc71l_data->mode = rc71l_gamepad_mode; -+ -+ // usb_device and endpoint -+ drvdata->rc71l_data->usb_pipe = usb_sndctrlpipe(dev, 0); -+ -+ // apply the default controller mode -+ mutex_lock(&drvdata->rc71l_data->mutex); -+ ret = rc71l_mode_change(hdev, drvdata->rc71l_data->mode); -+ mutex_unlock(&drvdata->rc71l_data->mutex); -+ -+ if (ret < 0) { -+ hid_err(hdev, "Asus ROG Ally [RC71L] error setting the default controller mode: %d\n", ret); -+ goto err_stop_hw; -+ } -+ -+ drvdata->rc71l_data->mcu_dev = platform_device_register_simple("asus-mcu", 0, NULL, 0); -+ if (IS_ERR(drvdata->rc71l_data->mcu_dev)) { -+ hid_err(hdev, "Error registering MCU platform device: %ld\n", PTR_ERR(drvdata->rc71l_data->mcu_dev)); -+ goto err_stop_hw; -+ } -+ -+ platform_set_drvdata(drvdata->rc71l_data->mcu_dev, hdev); -+ -+ ret = devm_device_add_group(&drvdata->rc71l_data->mcu_dev->dev, &mcu_attr_group); -+ if (ret != 0) { -+ platform_device_unregister(drvdata->rc71l_data->mcu_dev); -+ goto err_stop_hw; -+ } -+ } -+ - if (drvdata->tp) { - drvdata->input->name = "Asus TouchPad"; - } else { -@@ -1140,6 +1973,16 @@ static void asus_remove(struct hid_device *hdev) - cancel_work_sync(&drvdata->kbd_backlight->work); - } - -+ struct asus_rc71l *rc71l_drvdata = drvdata->rc71l_data; -+ if (rc71l_drvdata != NULL) { -+ platform_device_unregister(rc71l_drvdata->mcu_dev); -+ -+ mutex_lock(&rc71l_drvdata->mutex); -+ platform_device_unregister(rc71l_drvdata->mcu_dev); -+ // TODO: perform cleanup operations -+ mutex_unlock(&rc71l_drvdata->mutex); -+ } -+ - hid_hw_stop(hdev); - } - -@@ -1294,6 +2140,8 @@ static struct hid_driver asus_driver = { - .input_configured = asus_input_configured, - #ifdef CONFIG_PM - .reset_resume = asus_reset_resume, -+ .resume = asus_resume, -+ .suspend = asus_suspend, - #endif - .event = asus_event, - .raw_event = asus_raw_event - --- -2.43.0 - diff --git a/SOURCES/OpenRGB.patch b/SOURCES/OpenRGB.patch index 5a140ad..0ca0401 100644 --- a/SOURCES/OpenRGB.patch +++ b/SOURCES/OpenRGB.patch @@ -1,8 +1,21 @@ +From 309712fae7491a876359ddda6e4cf8944f454731 Mon Sep 17 00:00:00 2001 +From: GloriousEggroll <gloriouseggroll@gmail.com> +Date: Wed, 13 Sep 2023 17:59:59 -0600 +Subject: [PATCH] OpenRGB + +--- + drivers/i2c/busses/Kconfig | 9 + + drivers/i2c/busses/Makefile | 1 + + drivers/i2c/busses/i2c-nct6775.c | 647 +++++++++++++++++++++++++++++++ + drivers/i2c/busses/i2c-piix4.c | 4 +- + 4 files changed, 659 insertions(+), 2 deletions(-) + create mode 100644 drivers/i2c/busses/i2c-nct6775.c + diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 2ddca08f8a76..72647850f08e 100644 +index 9cfe8fc50..efc3b0c0b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig -@@ -217,6 +217,15 @@ config I2C_CHT_WC +@@ -229,6 +229,15 @@ config I2C_CHT_WC combined with a FUSB302 Type-C port-controller as such it is advised to also select CONFIG_TYPEC_FUSB302=m. @@ -19,10 +32,10 @@ index 2ddca08f8a76..72647850f08e 100644 tristate "Nvidia nForce2, nForce3 and nForce4" depends on PCI diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index 25d60889713c..3c2a9b237ac6 100644 +index af56fe2c7..76be74584 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile -@@ -17,6 +17,7 @@ obj-$(CONFIG_I2C_CHT_WC) += i2c-cht-wc.o +@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_CHT_WC) += i2c-cht-wc.o obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_ISCH) += i2c-isch.o obj-$(CONFIG_I2C_ISMT) += i2c-ismt.o @@ -32,7 +45,7 @@ index 25d60889713c..3c2a9b237ac6 100644 obj-$(CONFIG_I2C_NVIDIA_GPU) += i2c-nvidia-gpu.o diff --git a/drivers/i2c/busses/i2c-nct6775.c b/drivers/i2c/busses/i2c-nct6775.c new file mode 100644 -index 000000000000..0462f0952043 +index 000000000..0462f0952 --- /dev/null +++ b/drivers/i2c/busses/i2c-nct6775.c @@ -0,0 +1,647 @@ @@ -684,10 +697,10 @@ index 000000000000..0462f0952043 +module_init(i2c_nct6775_init); +module_exit(i2c_nct6775_exit); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c -index 30ded6422e7b..e25ce84c26af 100644 +index 809fbd014..d54b35b14 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c -@@ -467,11 +467,11 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter) +@@ -568,11 +568,11 @@ static int piix4_transaction(struct i2c_adapter *piix4_adapter) if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */ usleep_range(2000, 2100); else @@ -701,15 +714,6 @@ index 30ded6422e7b..e25ce84c26af 100644 /* If the SMBus is still busy, we give up */ if (timeout == MAX_TIMEOUT) { -@@ -981,6 +981,11 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) - retval = piix4_setup_sb800(dev, id, 1); - } - -+ if (dev->vendor == PCI_VENDOR_ID_AMD && -+ dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) { -+ retval = piix4_setup_sb800(dev, id, 1); -+ } -+ - if (retval > 0) { - /* Try to add the aux adapter if it exists, - * piix4_add_adapter will clean up if this fails */ +-- +2.41.0 + diff --git a/SOURCES/amdgpu-si-cik-default.patch b/SOURCES/amdgpu-si-cik-default.patch index b2df0dc..d2d3178 100644 --- a/SOURCES/amdgpu-si-cik-default.patch +++ b/SOURCES/amdgpu-si-cik-default.patch @@ -16,7 +16,7 @@ index 81edf66dbea8..5021d03089ff 100644 @@ -582,13 +582,8 @@ module_param_named(timeout_period, amdgpu_watchdog_timer.period, uint, 0644); */ #ifdef CONFIG_DRM_AMDGPU_SI - + -#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE) -int amdgpu_si_support = 0; -MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))"); @@ -24,13 +24,13 @@ index 81edf66dbea8..5021d03089ff 100644 int amdgpu_si_support = 1; MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)"); -#endif - + module_param_named(si_support, amdgpu_si_support, int, 0444); #endif @@ -601,13 +596,8 @@ module_param_named(si_support, amdgpu_si_support, int, 0444); */ #ifdef CONFIG_DRM_AMDGPU_CIK - + -#if IS_ENABLED(CONFIG_DRM_RADEON) || IS_ENABLED(CONFIG_DRM_RADEON_MODULE) -int amdgpu_cik_support = 0; -MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))"); @@ -38,7 +38,7 @@ index 81edf66dbea8..5021d03089ff 100644 int amdgpu_cik_support = 1; MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); -#endif - + module_param_named(cik_support, amdgpu_cik_support, int, 0444); #endif diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c @@ -48,7 +48,7 @@ index 7bf08164140e..865f186f48c4 100644 @@ -239,12 +239,22 @@ module_param_named(uvd, radeon_uvd, int, 0444); MODULE_PARM_DESC(vce, "vce enable/disable vce support (1 = enable, 0 = disable)"); module_param_named(vce, radeon_vce, int, 0444); - + +#ifdef CONFIG_DRM_AMDGPU_SI +int radeon_si_support = 0; +MODULE_PARM_DESC(si_support, "SI support (1 = enabled, 0 = disabled (default))"); @@ -57,7 +57,7 @@ index 7bf08164140e..865f186f48c4 100644 MODULE_PARM_DESC(si_support, "SI support (1 = enabled (default), 0 = disabled)"); +#endif module_param_named(si_support, radeon_si_support, int, 0444); - + +#ifdef CONFIG_DRM_AMDGPU_CIK +int radeon_cik_support = 0; +MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled, 0 = disabled (default))"); @@ -66,5 +66,5 @@ index 7bf08164140e..865f186f48c4 100644 MODULE_PARM_DESC(cik_support, "CIK support (1 = enabled (default), 0 = disabled)"); +#endif module_param_named(cik_support, radeon_cik_support, int, 0444); - + static struct pci_device_id pciidlist[] = { diff --git a/SOURCES/asus-linux.patch b/SOURCES/asus-linux.patch index 5e084db..a2bcfcc 100644 --- a/SOURCES/asus-linux.patch +++ b/SOURCES/asus-linux.patch @@ -84,7 +84,7 @@ index c83328971728..de0802859849 100644 + cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, reset_gpio, GPIOD_OUT_HIGH); + hw_cfg->valid = true; - + return 0; @@ -92,6 +135,20 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { { "CLSA0100", NULL, lenovo_legion_no_acpi }, @@ -106,8 +106,8 @@ index c83328971728..de0802859849 100644 + { "CSC3551", "10431F1F", asus_rog_2023_no_acpi }, // H7604JV spi, rst=0 {} }; - --- + +-- 2.41.0 From b35a4c957b3f0e5b4c7c73dec4fe3a5b9dbc4873 Mon Sep 17 00:00:00 2001 @@ -157,26 +157,26 @@ index f54178d6f780..0b13be703856 100644 @@ -127,6 +128,10 @@ module_param(fnlock_default, bool, 0444); #define NVIDIA_TEMP_MIN 75 #define NVIDIA_TEMP_MAX 87 - + +#define ASUS_SCREENPAD_BRIGHT_MIN 20 +#define ASUS_SCREENPAD_BRIGHT_MAX 255 +#define ASUS_SCREENPAD_BRIGHT_DEFAULT 60 + static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; - + static int throttle_thermal_policy_write(struct asus_wmi *); @@ -212,6 +217,7 @@ struct asus_wmi { - + struct input_dev *inputdev; struct backlight_device *backlight_device; + struct backlight_device *screenpad_backlight_device; struct platform_device *platform_device; - + struct led_classdev wlan_led; @@ -3776,6 +3782,124 @@ static int is_display_toggle(int code) return 0; } - + +/* Screenpad backlight *******************************************************/ + +static int read_screenpad_backlight_power(struct asus_wmi *asus) @@ -296,12 +296,12 @@ index f54178d6f780..0b13be703856 100644 +} + /* Fn-lock ********************************************************************/ - + static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus) @@ -4431,6 +4555,12 @@ static int asus_wmi_add(struct platform_device *pdev) } else if (asus->driver->quirks->wmi_backlight_set_devstate) err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 2, NULL); - + + if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_SCREENPAD_LIGHT)) { + err = asus_screenpad_init(asus); + if (err && err != -ENODEV) @@ -338,7 +338,7 @@ index a478ebfd34df..5fbdd0eafa02 100644 int panel_power; + int screenpad_brightness; int wlan_ctrl_by_user; - + const char *name; diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h index 16e99a1c37fc..63e630276499 100644 @@ -354,8 +354,8 @@ index 16e99a1c37fc..63e630276499 100644 +#define ASUS_WMI_DEVID_SCREENPAD_LIGHT 0x00050032 #define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018 #define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075 - --- + +-- 2.41.0 From 7760e10674dbb9127450629308c6ee1c35d5fc19 Mon Sep 17 00:00:00 2001 @@ -386,6 +386,5 @@ index 58006c8bcfb9..a690baa202c5 100644 SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), --- +-- 2.41.0 - diff --git a/SOURCES/hid-asus-reset-the-backlight-brightness-level-on-resume.patch b/SOURCES/hid-asus-reset-the-backlight-brightness-level-on-resume.patch new file mode 100644 index 0000000..24cff73 --- /dev/null +++ b/SOURCES/hid-asus-reset-the-backlight-brightness-level-on-resume.patch @@ -0,0 +1,275 @@ +From patchwork Fri Nov 17 01:15:55 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Luke Jones <luke@ljones.dev> +X-Patchwork-Id: 13458327 +X-Patchwork-Delegate: jikos@jikos.cz +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev + header.b="joJ1IrQk"; + dkim=pass (2048-bit key) header.d=messagingengine.com + header.i=@messagingengine.com header.b="OgcXPjZQ" +Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com + [66.111.4.29]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23A8D1AD; + Thu, 16 Nov 2023 17:16:21 -0800 (PST) +Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) + by mailout.nyi.internal (Postfix) with ESMTP id 80FF05C01D5; + Thu, 16 Nov 2023 20:16:20 -0500 (EST) +Received: from mailfrontend1 ([10.202.2.162]) + by compute1.internal (MEProxy); Thu, 16 Nov 2023 20:16:20 -0500 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ljones.dev; h=cc + :cc:content-transfer-encoding:content-type:date:date:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to; s=fm2; t=1700183780; x= + 1700270180; bh=6VCvJjojGG/O8+rbwWkHTqMF8m/NO3fQFVfb6jMvLVc=; b=j + oJ1IrQkctNq6Z9EoVV8wV+1PpDSuUJj7CRNNwjZ28LS6BcoHLF91fsc7JggUL00w + zLKnMg5Rkxfhl5vaRFNP7LuQ1JxTbo8jenkt8KE3oMhhm5j0E1ciyHEC5tubM8C4 + hJHKFYK56dhKw4H4bv05/4K2t25zgME1BVHginuNJToupYX1Y+vZ+H1byx5CFVDR + VuhYNnoIOlUlhiMFIs4qq0ZXcEXvq0JRtE06SlwQsjlKKibILKaPsg0E4j+HI1cO + BFGOcEXD4IJgzZ7L7etIXomAWGPlCtjSyfGyFhVVT2Tkr8MRnH971E1BA+rtownx + FlcLqdYHevxGBPVF1ow/A== +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= + messagingengine.com; h=cc:cc:content-transfer-encoding + :content-type:date:date:feedback-id:feedback-id:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy + :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1700183780; x= + 1700270180; bh=6VCvJjojGG/O8+rbwWkHTqMF8m/NO3fQFVfb6jMvLVc=; b=O + gcXPjZQq/MUN7cHYWBpzZy4vSH6jAzg861vtzKMzj0M0TZY1uhebF4DcK2+slxV8 + OjJOzuO8xbezJuq9oINt4k3aa/wZbHTgQMKCZp/Y/9og/NSEgAm1gcW9SXxnXQc2 + X0hgo9oWOnB71CSyZFPrRTDFMJdysZxMYX6lk3IuJxtCsDcwrRm7Ibl187Y/5b+a + eKPSR2WsoLXTatWnpyFUGUFlkH4oE8JcexVqoubex7EkvSf/RD9ruZA6lthmUg4q + 0gLFGO9wO+jKd1TdLu1KGtDpHD9nfvuZJNiY106nQNYbAslkZoumgipZX1q8DLNd + Cvfcc8ETFuHTjTCLawXww== +X-ME-Sender: <xms:5L5WZZThhjJXvCrJS9aa2YR7e_zq3QWba63-klSi4C2YMx6qpWp6_g> + <xme:5L5WZSwgf0bMp5s0edZF37MoW2ALjC97EVMvNvaien2HwwxTsA3MhyjGA4qbR5El7 + ar053vdhuRwYunce-k> +X-ME-Received: + <xmr:5L5WZe2S-AI72DhYjD5G0yy9Vp9IAYQSu0rUOZhjsY90MGlIqrYLLLDQIG15> +X-ME-Proxy-Cause: + gggruggvucftvghtrhhoucdtuddrgedvkedrudefledgfeduucetufdoteggodetrfdotf + fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen + uceurghilhhouhhtmecufedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtke + ertdertddtnecuhfhrohhmpedfnfhukhgvucffrdculfhonhgvshdfuceolhhukhgvsehl + jhhonhgvshdruggvvheqnecuggftrfgrthhtvghrnhepgfetfedugfetudeuheetjefhue + fggfelleetvdevtefhueeujeefvdegleevhefgnecuvehluhhsthgvrhfuihiivgeptden + ucfrrghrrghmpehmrghilhhfrhhomheplhhukhgvsehljhhonhgvshdruggvvh +X-ME-Proxy: <xmx:5L5WZRDpNtVMB2JEUjRakHCQo8yBOZgOGCtwVg4O87sSCpAkGY8MwA> + <xmx:5L5WZShgyRTLLhMQ1FbTqFRCK7q4rO8y01_1ej_Bmdi_SX62i466-w> + <xmx:5L5WZVp96JuOjG0DAFGMPInav3v6PxYWQhQDX4sjTIP7Rd6b5uc_vg> + <xmx:5L5WZVtKQTu_ZXbq6rYiW4Hi26Tz5NE9tt0SL8nmcliUeQ2vbsBPOg> +Feedback-ID: i5ec1447f:Fastmail +Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, + 16 Nov 2023 20:16:17 -0500 (EST) +From: "Luke D. Jones" <luke@ljones.dev> +To: jikos@kernel.org +Cc: benjamin.tissoires@redhat.com, + linux-input@vger.kernel.org, + linux-kernel@vger.kernel.org, + benato.denis96@gmail.com +Subject: [PATCH 1/2] hid-asus: add const to read-only outgoing usb buffer +Date: Fri, 17 Nov 2023 14:15:55 +1300 +Message-ID: <20231117011556.13067-2-luke@ljones.dev> +X-Mailer: git-send-email 2.41.0 +In-Reply-To: <20231117011556.13067-1-luke@ljones.dev> +References: <20231117011556.13067-1-luke@ljones.dev> +Precedence: bulk +X-Mailing-List: linux-input@vger.kernel.org +List-Id: <linux-input.vger.kernel.org> +List-Subscribe: <mailto:linux-input+subscribe@vger.kernel.org> +List-Unsubscribe: <mailto:linux-input+unsubscribe@vger.kernel.org> +MIME-Version: 1.0 + +From: Denis Benato <benato.denis96@gmail.com> + +In the function asus_kbd_set_report the parameter buf is read-only +as it gets copied in a memory portion suitable for USB transfer, +but the parameter is not marked as const: add the missing const and mark +const immutable buffers passed to that function. + +Signed-off-by: Denis Benato <benato.denis96@gmail.com> +--- + drivers/hid/hid-asus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index fd61dba88233..b70673a929a1 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev, + return 0; + } + +-static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) ++static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) + { + unsigned char *dmabuf; + int ret; +@@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size + + static int asus_kbd_init(struct hid_device *hdev) + { +- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + int ret; + +@@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev) + static int asus_kbd_get_functions(struct hid_device *hdev, + unsigned char *kbd_func) + { +- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; + u8 *readbuf; + int ret; + +@@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, + + static int rog_nkey_led_init(struct hid_device *hdev) + { +- u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; ++ const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; + u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20, + 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; + u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, + +From patchwork Fri Nov 17 01:15:56 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Luke Jones <luke@ljones.dev> +X-Patchwork-Id: 13458328 +X-Patchwork-Delegate: jikos@jikos.cz +Authentication-Results: smtp.subspace.kernel.org; + dkim=pass (2048-bit key) header.d=ljones.dev header.i=@ljones.dev + header.b="CmfGtmGu"; + dkim=pass (2048-bit key) header.d=messagingengine.com + header.i=@messagingengine.com header.b="jzb6JGxZ" +Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com + [66.111.4.29]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2FDA9182; + Thu, 16 Nov 2023 17:16:24 -0800 (PST) +Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) + by mailout.nyi.internal (Postfix) with ESMTP id 9EAC45C01D0; + Thu, 16 Nov 2023 20:16:23 -0500 (EST) +Received: from mailfrontend1 ([10.202.2.162]) + by compute4.internal (MEProxy); Thu, 16 Nov 2023 20:16:23 -0500 +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ljones.dev; h=cc + :cc:content-transfer-encoding:content-type:date:date:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to; s=fm2; t=1700183783; x= + 1700270183; bh=eW7/wu+ICidmfZHSNxKv48b4TD+SrR9ios0hX/9qiic=; b=C + mfGtmGuSaYypQGBqeXOqsgU84svGsmxsKEI6B1P7Up6LKAMVV4memvlhpkkpvSmu + NbUpUijlEN5j+nHGZAc41KnIN2lFjlWVKkWxnfQG+LpVEhlyMHbv9/FJbxF9XvTm + GK8PcciRWt5dSntKZw+Yn8GumCwPDGy3Tzwx3M6PFwbo+SzzsKox1mTATb0BVPmz + y9yHl/CH8n6Vw1/IiILvCjT5D7Pg9R6t6n25ks6pa8lhTpGPdt+u0j2gAj+I9tKe + sGnZ36pZN0Fxe7gfgC8vnjhCKtSAmzjwHJZ/106YHvNB9KVk78hbYw3VsqmdhcBi + TPdREbF0UnXZc0T/+fAPA== +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= + messagingengine.com; h=cc:cc:content-transfer-encoding + :content-type:date:date:feedback-id:feedback-id:from:from + :in-reply-to:in-reply-to:message-id:mime-version:references + :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy + :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1700183783; x= + 1700270183; bh=eW7/wu+ICidmfZHSNxKv48b4TD+SrR9ios0hX/9qiic=; b=j + zb6JGxZ5/h3mYwvyarhtE20qVT9ZQZcRtxt/hLoF71iKmwdBcQDGwx7uza6O5KXN + gyp9FKKDeyA8B4U04jhXWIcgy4M6PP5qTD+U4YMvy8vIhA3tBa/sS1DOYHIHqFzN + QSh/bPDxrY7ztw6xouoFRm1z1pBLLHOsJCB3akgFd53xPYVx/U2f4F3qvh0rSfli + rEIh/FkqbBMGe0NLClXiKLKGAQUm1EX4wnur8HVgwuv7zc+EGZhqD03OTQSrBcIO + PYjwqjDtXen/ynFbWP03uBPKJ1cevJIRt2MWrndItRwMeuZeD7Ru/IRFxGxPOJjb + KSWodEkqKycqzJCQUnbaw== +X-ME-Sender: <xms:575WZdqmRNoWh0wdaiEx75GCMCyj_7B51QYsgd73h0-TQbHDhXy2zw> + <xme:575WZfoCEcLPijY4Y9_zZT56J9vXWcbixQBf77SxmVTTCaP6ltHIzvUP6Qv16cuJc + aMYTkQFJ4J4cK-SxBg> +X-ME-Received: + <xmr:575WZaM4w2tfNzCs_O9IADh1kf8PLApFT54gO9RLalFlkVsF3Hy-FiCGHl5M> +X-ME-Proxy-Cause: + gggruggvucftvghtrhhoucdtuddrgedvkedrudefledgfeduucetufdoteggodetrfdotf + fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen + uceurghilhhouhhtmecufedttdenucenucfjughrpefhvfevufffkffojghfggfgsedtke + ertdertddtnecuhfhrohhmpedfnfhukhgvucffrdculfhonhgvshdfuceolhhukhgvsehl + jhhonhgvshdruggvvheqnecuggftrfgrthhtvghrnhepgfetfedugfetudeuheetjefhue + fggfelleetvdevtefhueeujeefvdegleevhefgnecuvehluhhsthgvrhfuihiivgeptden + ucfrrghrrghmpehmrghilhhfrhhomheplhhukhgvsehljhhonhgvshdruggvvh +X-ME-Proxy: <xmx:575WZY77KBxh-bL85znFipiE-ggUKTJ2tDIDTvTm9YF0kJarn0AkQA> + <xmx:575WZc5zoBYeJvYPSo1lIUmVXBPbdx227RtLugZedyX_ACQs4jPdBQ> + <xmx:575WZQj_KrFlWDt48A8oN1-mT__TYIKuv7g6oiImr1BNemELhZUkxg> + <xmx:575WZcHsLP6IeIta4DTX1y66Yx02mgxpKuYqDaML9NNskFO4QUZEfQ> +Feedback-ID: i5ec1447f:Fastmail +Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, + 16 Nov 2023 20:16:20 -0500 (EST) +From: "Luke D. Jones" <luke@ljones.dev> +To: jikos@kernel.org +Cc: benjamin.tissoires@redhat.com, + linux-input@vger.kernel.org, + linux-kernel@vger.kernel.org, + benato.denis96@gmail.com +Subject: [PATCH 2/2] hid-asus: reset the backlight brightness level on resume +Date: Fri, 17 Nov 2023 14:15:56 +1300 +Message-ID: <20231117011556.13067-3-luke@ljones.dev> +X-Mailer: git-send-email 2.41.0 +In-Reply-To: <20231117011556.13067-1-luke@ljones.dev> +References: <20231117011556.13067-1-luke@ljones.dev> +Precedence: bulk +X-Mailing-List: linux-input@vger.kernel.org +List-Id: <linux-input.vger.kernel.org> +List-Subscribe: <mailto:linux-input+subscribe@vger.kernel.org> +List-Unsubscribe: <mailto:linux-input+unsubscribe@vger.kernel.org> +MIME-Version: 1.0 + +From: Denis Benato <benato.denis96@gmail.com> + +Some devices managed by this driver automatically set brightness to 0 +before entering a suspended state and reset it back to a default +brightness level after the resume: +this has the effect of having the kernel report wrong brightness +status after a sleep, and on some devices (like the Asus RC71L) that +brightness is the intensity of LEDs directly facing the user. + +Fix the above issue by setting back brightness to the level it had +before entering a sleep state. + +Signed-off-by: Denis Benato <benato.denis96@gmail.com> +--- + drivers/hid/hid-asus.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c +index b70673a929a1..78cdfb8b9a7a 100644 +--- a/drivers/hid/hid-asus.c ++++ b/drivers/hid/hid-asus.c +@@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev) + return 0; + } + ++static int __maybe_unused asus_resume(struct hid_device *hdev) { ++ struct asus_drvdata *drvdata = hid_get_drvdata(hdev); ++ int ret = 0; ++ ++ if (drvdata->kbd_backlight) { ++ const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, ++ drvdata->kbd_backlight->cdev.brightness }; ++ ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); ++ if (ret < 0) { ++ hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); ++ goto asus_resume_err; ++ } ++ } ++ ++asus_resume_err: ++ return ret; ++} ++ + static int __maybe_unused asus_reset_resume(struct hid_device *hdev) + { + struct asus_drvdata *drvdata = hid_get_drvdata(hdev); +@@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = { + .input_configured = asus_input_configured, + #ifdef CONFIG_PM + .reset_resume = asus_reset_resume, ++ .resume = asus_resume, + #endif + .event = asus_event, + .raw_event = asus_raw_event diff --git a/SOURCES/kernel-aarch64-16k-debug-fedora.config b/SOURCES/kernel-aarch64-16k-debug-fedora.config index f0d8660..706157b 100644 --- a/SOURCES/kernel-aarch64-16k-debug-fedora.config +++ b/SOURCES/kernel-aarch64-16k-debug-fedora.config @@ -9800,3 +9800,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-16k-fedora.config b/SOURCES/kernel-aarch64-16k-fedora.config index 26b3744..3081b71 100644 --- a/SOURCES/kernel-aarch64-16k-fedora.config +++ b/SOURCES/kernel-aarch64-16k-fedora.config @@ -9771,3 +9771,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-64k-debug-rhel.config b/SOURCES/kernel-aarch64-64k-debug-rhel.config index 90273ac..f3bfb78 100644 --- a/SOURCES/kernel-aarch64-64k-debug-rhel.config +++ b/SOURCES/kernel-aarch64-64k-debug-rhel.config @@ -7945,3 +7945,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-64k-rhel.config b/SOURCES/kernel-aarch64-64k-rhel.config index 52d7803..7a5e7f9 100644 --- a/SOURCES/kernel-aarch64-64k-rhel.config +++ b/SOURCES/kernel-aarch64-64k-rhel.config @@ -7920,3 +7920,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-debug-fedora.config b/SOURCES/kernel-aarch64-debug-fedora.config index 7615479..12be823 100644 --- a/SOURCES/kernel-aarch64-debug-fedora.config +++ b/SOURCES/kernel-aarch64-debug-fedora.config @@ -9800,3 +9800,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-debug-rhel.config b/SOURCES/kernel-aarch64-debug-rhel.config index 9b874db..09b5480 100644 --- a/SOURCES/kernel-aarch64-debug-rhel.config +++ b/SOURCES/kernel-aarch64-debug-rhel.config @@ -7941,3 +7941,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-fedora.config b/SOURCES/kernel-aarch64-fedora.config index c5fd773..0558608 100644 --- a/SOURCES/kernel-aarch64-fedora.config +++ b/SOURCES/kernel-aarch64-fedora.config @@ -9771,3 +9771,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-rhel.config b/SOURCES/kernel-aarch64-rhel.config index 6645911..b19a213 100644 --- a/SOURCES/kernel-aarch64-rhel.config +++ b/SOURCES/kernel-aarch64-rhel.config @@ -7916,3 +7916,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-rt-debug-rhel.config b/SOURCES/kernel-aarch64-rt-debug-rhel.config index fb5a0f3..7bbd15e 100644 --- a/SOURCES/kernel-aarch64-rt-debug-rhel.config +++ b/SOURCES/kernel-aarch64-rt-debug-rhel.config @@ -8002,3 +8002,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-aarch64-rt-rhel.config b/SOURCES/kernel-aarch64-rt-rhel.config index 618b209..a644a4c 100644 --- a/SOURCES/kernel-aarch64-rt-rhel.config +++ b/SOURCES/kernel-aarch64-rt-rhel.config @@ -7977,3 +7977,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-ppc64le-debug-fedora.config b/SOURCES/kernel-ppc64le-debug-fedora.config index 651a070..89f1244 100644 --- a/SOURCES/kernel-ppc64le-debug-fedora.config +++ b/SOURCES/kernel-ppc64le-debug-fedora.config @@ -8250,3 +8250,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-ppc64le-debug-rhel.config b/SOURCES/kernel-ppc64le-debug-rhel.config index 878cd33..ebeaed0 100644 --- a/SOURCES/kernel-ppc64le-debug-rhel.config +++ b/SOURCES/kernel-ppc64le-debug-rhel.config @@ -7420,3 +7420,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-ppc64le-fedora.config b/SOURCES/kernel-ppc64le-fedora.config index cf58241..e5c076b 100644 --- a/SOURCES/kernel-ppc64le-fedora.config +++ b/SOURCES/kernel-ppc64le-fedora.config @@ -8219,3 +8219,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-ppc64le-rhel.config b/SOURCES/kernel-ppc64le-rhel.config index 95d5ee5..d79f055 100644 --- a/SOURCES/kernel-ppc64le-rhel.config +++ b/SOURCES/kernel-ppc64le-rhel.config @@ -7397,3 +7397,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-s390x-debug-fedora.config b/SOURCES/kernel-s390x-debug-fedora.config index 63c8715..4005a65 100644 --- a/SOURCES/kernel-s390x-debug-fedora.config +++ b/SOURCES/kernel-s390x-debug-fedora.config @@ -8187,3 +8187,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-s390x-debug-rhel.config b/SOURCES/kernel-s390x-debug-rhel.config index c076c30..e7352e8 100644 --- a/SOURCES/kernel-s390x-debug-rhel.config +++ b/SOURCES/kernel-s390x-debug-rhel.config @@ -7406,3 +7406,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-s390x-fedora.config b/SOURCES/kernel-s390x-fedora.config index 7bd03d7..1ccf24d 100644 --- a/SOURCES/kernel-s390x-fedora.config +++ b/SOURCES/kernel-s390x-fedora.config @@ -8156,3 +8156,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-s390x-rhel.config b/SOURCES/kernel-s390x-rhel.config index 1740360..9ecadbf 100644 --- a/SOURCES/kernel-s390x-rhel.config +++ b/SOURCES/kernel-s390x-rhel.config @@ -7383,3 +7383,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-s390x-zfcpdump-rhel.config b/SOURCES/kernel-s390x-zfcpdump-rhel.config index 9063e22..8aba057 100644 --- a/SOURCES/kernel-s390x-zfcpdump-rhel.config +++ b/SOURCES/kernel-s390x-zfcpdump-rhel.config @@ -7406,3 +7406,4 @@ CONFIG_HID_ITHC=m CONFIG_SURFACE_BOOK1_DGPU_SWITCH=m CONFIG_IPC_CLASSES=y CONFIG_LEDS_TPS68470=m +# CONFIG_DRM_AMD_COLOR_STEAMDECK is not set diff --git a/SOURCES/kernel-x86_64-debug-fedora.config b/SOURCES/kernel-x86_64-debug-fedora.config index cf392af..5112096 100644 --- a/SOURCES/kernel-x86_64-debug-fedora.config +++ b/SOURCES/kernel-x86_64-debug-fedora.config @@ -8859,3 +8859,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/kernel-x86_64-debug-rhel.config b/SOURCES/kernel-x86_64-debug-rhel.config index 6bcbd0d..f010799 100644 --- a/SOURCES/kernel-x86_64-debug-rhel.config +++ b/SOURCES/kernel-x86_64-debug-rhel.config @@ -7808,3 +7808,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/kernel-x86_64-fedora.config b/SOURCES/kernel-x86_64-fedora.config index 6d9d376..4426da3 100644 --- a/SOURCES/kernel-x86_64-fedora.config +++ b/SOURCES/kernel-x86_64-fedora.config @@ -8829,3 +8829,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/kernel-x86_64-rhel.config b/SOURCES/kernel-x86_64-rhel.config index 95ebb31..d26a4d9 100644 --- a/SOURCES/kernel-x86_64-rhel.config +++ b/SOURCES/kernel-x86_64-rhel.config @@ -7784,3 +7784,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/kernel-x86_64-rt-debug-rhel.config b/SOURCES/kernel-x86_64-rt-debug-rhel.config index 6ad9338..0400c37 100644 --- a/SOURCES/kernel-x86_64-rt-debug-rhel.config +++ b/SOURCES/kernel-x86_64-rt-debug-rhel.config @@ -7870,3 +7870,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/kernel-x86_64-rt-rhel.config b/SOURCES/kernel-x86_64-rt-rhel.config index a83132e..2aa0176 100644 --- a/SOURCES/kernel-x86_64-rt-rhel.config +++ b/SOURCES/kernel-x86_64-rt-rhel.config @@ -7846,3 +7846,4 @@ CONFIG_SND_SOC_SOF_AMD_ACP63=m # CONFIG_SND_AMD_ASOC_REMBRANDT is not set # CONFIG_SND_SOC_AMD_LEGACY_MACH is not set CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_DRM_AMD_COLOR_STEAMDECK=y diff --git a/SOURCES/patch-6.6-redhat.patch b/SOURCES/patch-6.6-redhat.patch index 229bd54..1acbbd7 100644 --- a/SOURCES/patch-6.6-redhat.patch +++ b/SOURCES/patch-6.6-redhat.patch @@ -38,7 +38,7 @@ 37 files changed, 681 insertions(+), 181 deletions(-) diff --git a/Makefile b/Makefile -index cbe63ba9126e..07635f242c3d 100644 +index ee4e504a3e78..c4128bb7691b 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \ @@ -232,10 +232,10 @@ index 1687483ff319..390b67f19181 100644 return ctx.rc; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 691d4b7686ee..433ff7d8a844 100644 +index 1d249d0f61ae..f064f4c6405a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c -@@ -1752,6 +1752,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) +@@ -1757,6 +1757,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) if (!acpi_match_device_ids(device, ignore_serial_bus_ids)) return false; @@ -924,7 +924,7 @@ index 258d5fe3d395..f7298e3dc8f3 100644 if (data->f01_container->dev.driver) { /* Driver already bound, so enable ATTN now. */ diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c -index c146378c7d03..f9e8d35eaccc 100644 +index 3a67e636287a..eb5e796277d6 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -8,6 +8,7 @@ @@ -1034,7 +1034,7 @@ index 228fb2d11c70..696cfa7025de 100644 } #else diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index 6effa13039f3..fbfbd542b858 100644 +index e17509f0b3fa..f3b41bec28c2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -118,6 +118,14 @@ static const char *sd_cache_types[] = { @@ -1052,7 +1052,7 @@ index 6effa13039f3..fbfbd542b858 100644 static void sd_set_flush_flag(struct scsi_disk *sdkp) { bool wc = false, fua = false; -@@ -4045,6 +4053,8 @@ static int __init init_sd(void) +@@ -4052,6 +4060,8 @@ static int __init init_sd(void) goto err_out_class; } diff --git a/SOURCES/v2-0001-platform-x86-asus-wmi-disable-USB0-hub-on-ROG-All.patch b/SOURCES/platform-x86-asus-wmi-disable-USB0-hub-on-ROG-Ally-before-suspend.patch index 3c89787..aec1ecc 100644 --- a/SOURCES/v2-0001-platform-x86-asus-wmi-disable-USB0-hub-on-ROG-All.patch +++ b/SOURCES/platform-x86-asus-wmi-disable-USB0-hub-on-ROG-Ally-before-suspend.patch @@ -1,11 +1,15 @@ -From 0a399a37fbe6f6b2b9062e1c076df28608b628c9 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" <luke@ljones.dev> -Date: Fri, 24 Nov 2023 21:13:11 +1300 -Subject: [PATCH v2] platform/x86: asus-wmi: disable USB0 hub on ROG Ally +To: hdegoede@redhat.com +Cc: ilpo.jarvinen@linux.intel.com, + corentin.chary@gmail.com, + platform-driver-x86@vger.kernel.org, + linux-kernel@vger.kernel.org, + "Luke D. Jones" <luke@ljones.dev> +Subject: [PATCH v2 1/1] platform/x86: asus-wmi: disable USB0 hub on ROG Ally before suspend ASUS have worked around an issue in XInput where it doesn't support USB -selective suspend, whcih causes suspend issues in Windows. They worked +selective suspend, which causes suspend issues in Windows. They worked around this by adjusting the MCU firmware to disable the USB0 hub when the screen is switched off during the Microsoft DSM suspend path in ACPI. @@ -15,15 +19,24 @@ this in a prepare() and add a small msleep() to ensure it is done. This must be done before the screen is switched off to prevent a variety of possible races. +Further to this the MCU powersave option must also be disabled as it can +cause a number of issues such as: +- unreliable resume connection of N-Key +- complete loss of N-Key if the power is plugged in while suspended +Disabling the powersave option prevents this. + Without this the MCU is unable to initialise itself correctly on resume. Signed-off-by: Luke D. Jones <luke@ljones.dev> +Tested-by: Philip Mueller <philm@manjaro.org> +Reviewed-by: Hans de Goede <hdegoede@redhat.com> --- - drivers/platform/x86/asus-wmi.c | 40 +++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) + drivers/platform/x86/asus-wmi.c | 50 ++++++++++++++++++++++ + include/linux/platform_data/x86/asus-wmi.h | 3 ++ + 2 files changed, 53 insertions(+) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index 6a79f16233ab..563c9ab31bc7 100644 +index 6a79f16233ab..4ba33dfebfd4 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -16,6 +16,7 @@ @@ -34,36 +47,38 @@ index 6a79f16233ab..563c9ab31bc7 100644 #include <linux/dmi.h> #include <linux/fb.h> #include <linux/hwmon.h> -@@ -132,6 +133,9 @@ module_param(fnlock_default, bool, 0444); +@@ -132,6 +133,11 @@ module_param(fnlock_default, bool, 0444); #define ASUS_SCREENPAD_BRIGHT_MAX 255 #define ASUS_SCREENPAD_BRIGHT_DEFAULT 60 +/* Controls the power state of the USB0 hub on ROG Ally which input is on */ +#define ASUS_USB0_PWR_EC0_CSEE "\\_SB.PCI0.SBRG.EC0.CSEE" ++/* 300ms so far seems to produce a reliable result on AC and battery */ ++#define ASUS_USB0_PWR_EC0_CSEE_WAIT 300 + static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; static int throttle_thermal_policy_write(struct asus_wmi *); -@@ -300,6 +304,9 @@ struct asus_wmi { +@@ -300,6 +306,9 @@ struct asus_wmi { bool fnlock_locked; -+ /* The ROG Ally device requires the USB hub to be disabled before suspend */ -+ bool pre_suspend_ec0_csee_disable; ++ /* The ROG Ally device requires the MCU USB device be disconnected before suspend */ ++ bool ally_mcu_usb_switch; + struct asus_wmi_debug debug; struct asus_wmi_driver *driver; -@@ -4488,6 +4495,8 @@ static int asus_wmi_add(struct platform_device *pdev) +@@ -4488,6 +4497,8 @@ static int asus_wmi_add(struct platform_device *pdev) asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET); asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE); -+ asus->pre_suspend_ec0_csee_disable = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) ++ asus->ally_mcu_usb_switch = acpi_has_method(NULL, ASUS_USB0_PWR_EC0_CSEE) + && dmi_match(DMI_BOARD_NAME, "RC71L"); err = fan_boost_mode_check_present(asus); if (err) -@@ -4654,6 +4663,35 @@ static int asus_hotk_resume(struct device *device) +@@ -4654,6 +4665,43 @@ static int asus_hotk_resume(struct device *device) asus_wmi_fnlock_update(asus); asus_wmi_tablet_mode_get_state(asus); @@ -75,31 +90,39 @@ index 6a79f16233ab..563c9ab31bc7 100644 +{ + struct asus_wmi *asus = dev_get_drvdata(device); + -+ if (asus->pre_suspend_ec0_csee_disable) { -+ /* sleep required to ensure USB0 is enabled before drivers notice */ ++ if (asus->ally_mcu_usb_switch) { + if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB8))) -+ pr_warn("ASUS ROG Ally failed to set USB hub power on\n"); ++ dev_err(device, "ROG Ally MCU failed to connect USB dev\n"); ++ else ++ msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); + } -+ + return 0; +} + +static int asus_hotk_prepare(struct device *device) +{ + struct asus_wmi *asus = dev_get_drvdata(device); ++ int result, err; + -+ if (asus->pre_suspend_ec0_csee_disable) { ++ if (asus->ally_mcu_usb_switch) { ++ /* When powersave is enabled it causes many issues with resume of USB hub */ ++ result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_MCU_POWERSAVE); ++ if (result == 1) { ++ dev_warn(device, "MCU powersave enabled, disabling to prevent resume issues"); ++ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_MCU_POWERSAVE, 0, &result); ++ if (err || result != 1) ++ dev_err(device, "Failed to set MCU powersave mode: %d\n", err); ++ } + /* sleep required to ensure USB0 is disabled before sleep continues */ + if (ACPI_FAILURE(acpi_execute_simple_method(NULL, ASUS_USB0_PWR_EC0_CSEE, 0xB7))) -+ pr_warn("ASUS ROG Ally failed to set USB hub power off\n"); ++ dev_err(device, "ROG Ally MCU failed to disconnect USB dev\n"); + else -+ msleep(100); ++ msleep(ASUS_USB0_PWR_EC0_CSEE_WAIT); + } -+ return 0; } -@@ -4701,6 +4739,8 @@ static const struct dev_pm_ops asus_pm_ops = { +@@ -4701,6 +4749,8 @@ static const struct dev_pm_ops asus_pm_ops = { .thaw = asus_hotk_thaw, .restore = asus_hotk_restore, .resume = asus_hotk_resume, @@ -108,6 +131,17 @@ index 6a79f16233ab..563c9ab31bc7 100644 }; /* Registration ***************************************************************/ --- -2.43.0 - +diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h +index 63e630276499..ab1c7deff118 100644 +--- a/include/linux/platform_data/x86/asus-wmi.h ++++ b/include/linux/platform_data/x86/asus-wmi.h +@@ -114,6 +114,9 @@ + /* Charging mode - 1=Barrel, 2=USB */ + #define ASUS_WMI_DEVID_CHARGE_MODE 0x0012006C + ++/* MCU powersave mode */ ++#define ASUS_WMI_DEVID_MCU_POWERSAVE 0x001200E2 ++ + /* epu is connected? 1 == true */ + #define ASUS_WMI_DEVID_EGPU_CONNECTED 0x00090018 + /* egpu on/off */ diff --git a/SOURCES/steamdeck-oled-hw-quirks.patch b/SOURCES/steamdeck-oled-hw-quirks.patch index a2b1228..e233674 100644 --- a/SOURCES/steamdeck-oled-hw-quirks.patch +++ b/SOURCES/steamdeck-oled-hw-quirks.patch @@ -71,33 +71,6 @@ index e8b2fc4002a52..3c69d860e1c9d 100644 -- GitLab -From a32cc4f110bcd8d4595ff0812a72a521e99006ac Mon Sep 17 00:00:00 2001 -From: Keith Mikoleit <keithm@valvesoftware.com> -Date: Fri, 22 Sep 2023 17:30:44 -0700 -Subject: [PATCH] drm/amd/display: change default edp brightness check to min 1 - nit - ---- - .../amd/display/dc/link/protocols/link_edp_panel_control.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c -index 2039a345f23a1..e4626f2072f0f 100644 ---- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c -+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c -@@ -266,8 +266,8 @@ bool set_default_brightness_aux(struct dc_link *link) - if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { - if (!read_default_bl_aux(link, &default_backlight)) - default_backlight = 150000; -- // if < 5 nits or > 5000, it might be wrong readback -- if (default_backlight < 5000 || default_backlight > 5000000) -+ // if < 1 nits or > 5000, it might be wrong readback -+ if (default_backlight < 1000 || default_backlight > 5000000) - default_backlight = 150000; // - - return edp_set_backlight_level_nits(link, true, --- -GitLab From b59fed802470f07fafe72f6a2bdda2163da5ba33 Mon Sep 17 00:00:00 2001 From: Swapnil Patel <Swapnil.Patel@amd.com> Date: Tue, 26 Sep 2023 16:24:25 -0400 @@ -155,7 +128,7 @@ index b8633df418d43..77a1bedaee98c 100644 @@ -416,8 +416,6 @@ struct drm_property *regamma_tf_property; }; - + -#define AMDGPU_MAX_BL_LEVEL 0xFF - struct amdgpu_backlight_privdata { @@ -235,16 +208,16 @@ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm index e1a77a0d66336..8e61c86819fe2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -4032,7 +4032,7 @@ +@@ -4017,7 +4017,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) return 0; } - + -#define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12 +#define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 0 #define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255 #define AUX_BL_DEFAULT_TRANSITION_TIME_MS 50 - -@@ -4050,11 +4050,27 @@ + +@@ -4035,11 +4035,27 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm, amdgpu_acpi_get_backlight_caps(&caps); if (caps.caps_valid) { dm->backlight_caps[bl_idx].caps_valid = true; @@ -272,27 +245,27 @@ index e1a77a0d66336..8e61c86819fe2 100644 dm->backlight_caps[bl_idx].min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; dm->backlight_caps[bl_idx].max_input_signal = -@@ -4064,6 +4080,9 @@ +@@ -4049,6 +4065,9 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm, if (dm->backlight_caps[bl_idx].aux_support) return; - + + printk(KERN_NOTICE"VLV Kernel built without ACPI. using backlight range defaults: %d %d\n", + AMDGPU_DM_DEFAULT_MIN_BACKLIGHT, AMDGPU_DM_DEFAULT_MAX_BACKLIGHT); + dm->backlight_caps[bl_idx].min_input_signal = AMDGPU_DM_DEFAULT_MIN_BACKLIGHT; dm->backlight_caps[bl_idx].max_input_signal = AMDGPU_DM_DEFAULT_MAX_BACKLIGHT; #endif -@@ -4095,7 +4114,7 @@ +@@ -4080,7 +4099,7 @@ static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *c if (!get_brightness_range(caps, &min, &max)) return brightness; - + - // Rescale 0..255 to min..max + // Rescale 0..AMDGPU_MAX_BL_LEVEL to min..max return min + DIV_ROUND_CLOSEST((max - min) * brightness, AMDGPU_MAX_BL_LEVEL); } -@@ -4110,7 +4129,7 @@ - +@@ -4095,7 +4114,7 @@ static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *cap + if (brightness < min) return 0; - // Rescale min..max to 0..255 @@ -303,6 +276,7 @@ index e1a77a0d66336..8e61c86819fe2 100644 -- GitLab + From ab7d646eacf9f1c745d284e293211569a4428573 Mon Sep 17 00:00:00 2001 From: "Pierre-Loup A. Griffais" <pgriffais@valvesoftware.com> Date: Wed, 8 Nov 2023 19:45:52 -0800 @@ -393,3 +367,219 @@ index b76ff08506181..95f33dadb2be2 100644 -- GitLab +From 32d8309584145f531b46e8c1a72c86494e72160d Mon Sep 17 00:00:00 2001 +From: Joshua Ashton <joshua@froggi.es> +Date: Wed, 6 Sep 2023 22:00:26 +0100 +Subject: [PATCH] drm/amd/display: Don't consider vblank passed if currently in + vertical front porch time + +Changing refresh rates on OLED displays works differently to typical +LCD panels in that instead of changing the clock, the vertical porch +is extended significantly for lower rates. + +This can mean that the vertical porch can be incredibly large for +non-base refresh rates eg. 60Hz on a 90Hz display. + +This isn't an issue for X11/typical compositors as their present slop +is 1/2th of the refresh interval so the issue never manifests. + +However in Gamescope, the present slop very small and tuned to be +optimal in real-time to try and reduce display latency significantly. +This results in us queueing up the atomic commit inside the vertical +porch region which, due to legacy X11/sync control reasons, means that +AMDGPU must target the next vblank. + +This patch changes that behaviour to make FRR displays match what occurs +on VRR/Freesync displays where the vertical porch time is not included +in determining what vblank to target and solves the issue. + +This means that smarter compositors can get large input latency +reductions when using OLED displays at lower than base refresh rates. + +For upstreaming this patch, it will need to be considered what the best +solution is to enable this behaviour from the userspace side. +Obviously the X11/legacy stuff probably cannot change here -- so we +either need to enable this new behaviour globally for all DRM atomic +clients (ie. basically Wayland compositors) or have a +new DRM_MODE_ATOMIC flag. + +Signed-off-by: Joshua Ashton <joshua@froggi.es> +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index b87797bc5874..28e6fa8d7860 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -434,7 +434,7 @@ static void dm_pflip_high_irq(void *interrupt_params) + + WARN_ON(!e); + +- vrr_active = amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc); ++ vrr_active = true;//amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc); + + /* Fixed refresh rate, or VRR scanout position outside front-porch? */ + if (!vrr_active || +@@ -531,11 +531,11 @@ static void dm_vupdate_high_irq(void *interrupt_params) + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ +- if (vrr_active) { ++ if (true) { + amdgpu_dm_crtc_handle_vblank(acrtc); + + /* BTR processing for pre-DCE12 ASICs */ +- if (acrtc->dm_irq_params.stream && ++ if (vrr_active && acrtc->dm_irq_params.stream && + adev->family < AMDGPU_FAMILY_AI) { + spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); + mod_freesync_handle_v_update( +@@ -8098,7 +8098,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + int planes_count = 0, vpos, hpos; + unsigned long flags; + u32 target_vblank, last_flip_vblank; +- bool vrr_active = amdgpu_dm_crtc_vrr_active(acrtc_state); ++ bool vrr_active = true;//amdgpu_dm_crtc_vrr_active(acrtc_state); + bool cursor_update = false; + bool pflip_present = false; + bool dirty_rects_changed = false; +-- +GitLab + +From 2bfd05863fff384619dea44bafa98ba0e6a5cdf4 Mon Sep 17 00:00:00 2001 +From: Joshua Ashton <joshua@froggi.es> +Date: Sun, 3 Dec 2023 11:35:06 +0000 +Subject: [PATCH] drm/amd/display: Revert some of the vrr always on hack + +Fixes frame timings on some non)-VRR external displays going all whacky. + +This makes us not use the late vblank irq handler (backporch line 0) and instead send the vblank event immediately on page flip when we know where the vblank is going to be. + +Should also improve latency/stutter on internal display potentially too. +--- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +index 715f442a0e3b..06dcd463f841 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -434,7 +434,7 @@ static void dm_pflip_high_irq(void *interrupt_params) + + WARN_ON(!e); + +- vrr_active = true;//amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc); ++ vrr_active = amdgpu_dm_crtc_vrr_active_irq(amdgpu_crtc); + + /* Fixed refresh rate, or VRR scanout position outside front-porch? */ + if (!vrr_active || +@@ -531,11 +531,11 @@ static void dm_vupdate_high_irq(void *interrupt_params) + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ +- if (true) { ++ if (vrr_active) { + amdgpu_dm_crtc_handle_vblank(acrtc); + + /* BTR processing for pre-DCE12 ASICs */ +- if (vrr_active && acrtc->dm_irq_params.stream && ++ if (acrtc->dm_irq_params.stream && + adev->family < AMDGPU_FAMILY_AI) { + spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); + mod_freesync_handle_v_update( +-- +GitLab + +From d426d1ad3f92605c95bdf58bbc19129a128f5590 Mon Sep 17 00:00:00 2001 +From: Friedrich Vock <friedrich.vock@gmx.de> +Date: Fri, 1 Dec 2023 15:15:58 +0100 +Subject: [PATCH] drm/amdgpu: Enable tunneling on high-priority compute queues + +This improves latency if the GPU is already busy with other work. +This is useful for VR compositors that submit highly latency-sensitive +compositing work on high-priority compute queues while the GPU is busy +rendering the next frame. + +Userspace merge request: +https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26462 + +Signed-off-by: Friedrich Vock <friedrich.vock@gmx.de> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 10 ++++++---- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 3 ++- + drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 3 ++- + 4 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index df59a6919d878..04686b816fa11 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -768,6 +768,7 @@ struct amdgpu_mqd_prop { + uint64_t eop_gpu_addr; + uint32_t hqd_pipe_priority; + uint32_t hqd_queue_priority; ++ bool allow_tunneling; + bool hqd_active; + }; + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +index 72085a3ef53c0..5d1a6e95b02e8 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +@@ -637,6 +637,10 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring, + struct amdgpu_mqd_prop *prop) + { + struct amdgpu_device *adev = ring->adev; ++ bool is_high_prio_compute = ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE && ++ amdgpu_gfx_is_high_priority_compute_queue(adev, ring); ++ bool is_high_prio_gfx = ring->funcs->type == AMDGPU_RING_TYPE_GFX && ++ amdgpu_gfx_is_high_priority_graphics_queue(adev, ring); + + memset(prop, 0, sizeof(*prop)); + +@@ -654,10 +658,8 @@ static void amdgpu_ring_to_mqd_prop(struct amdgpu_ring *ring, + */ + prop->hqd_active = ring->funcs->type == AMDGPU_RING_TYPE_KIQ; + +- if ((ring->funcs->type == AMDGPU_RING_TYPE_COMPUTE && +- amdgpu_gfx_is_high_priority_compute_queue(adev, ring)) || +- (ring->funcs->type == AMDGPU_RING_TYPE_GFX && +- amdgpu_gfx_is_high_priority_graphics_queue(adev, ring))) { ++ prop->allow_tunneling = is_high_prio_compute; ++ if (is_high_prio_compute || is_high_prio_gfx) { + prop->hqd_pipe_priority = AMDGPU_GFX_PIPE_PRIO_HIGH; + prop->hqd_queue_priority = AMDGPU_GFX_QUEUE_PRIORITY_MAXIMUM; + } +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +index 8256f80d468dd..fc58924e8a5e0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -6572,7 +6572,8 @@ static int gfx_v10_0_compute_mqd_init(struct amdgpu_device *adev, void *m, + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1); + #endif + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); +- tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); ++ tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, ++ prop->allow_tunneling); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); + mqd->cp_hqd_pq_control = tmp; +diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +index da21bf868080e..6d4dbb3f0e381 100644 +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +@@ -3795,7 +3795,8 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m, + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE, + (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); +- tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); ++ tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, ++ prop->allow_tunneling); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); + mqd->cp_hqd_pq_control = tmp; +-- +GitLab + diff --git a/SOURCES/steamdeck-oled-wifi.patch b/SOURCES/steamdeck-oled-wifi.patch index 39ae50a..a25f07d 100644 --- a/SOURCES/steamdeck-oled-wifi.patch +++ b/SOURCES/steamdeck-oled-wifi.patch @@ -1,145 +1,99 @@ -From 127870bd4c46edfc7bbc58476d7e02cf9a25ea05 Mon Sep 17 00:00:00 2001 -From: Thomas Crider <gloriouseggroll@gmail.com> -Date: Sat, 2 Dec 2023 03:04:44 -0500 -Subject: [PATCH] steamdeck-wifi-unified +From 01fd63d2e9b32cd917c9036dfb703b5c4bbd872d Mon Sep 17 00:00:00 2001 +From: "neil.shi" <neil.shi@quectel.com> +Date: Tue, 23 May 2023 16:58:08 +0800 +Subject: [PATCH] wifi: ath11k: [DBS PATCH 1/6]: Indicate NAN support to + firmware +Signed-off-by: neil.shi <neil.shi@quectel.com> --- - drivers/net/wireless/ath/ath11k/Makefile | 4 +- - drivers/net/wireless/ath/ath11k/ce.c | 6 +- - drivers/net/wireless/ath/ath11k/core.c | 159 +++++ - drivers/net/wireless/ath/ath11k/core.h | 60 ++ - drivers/net/wireless/ath/ath11k/debugfs.c | 79 +++ - drivers/net/wireless/ath/ath11k/dp.c | 12 +- - drivers/net/wireless/ath/ath11k/dp_rx.c | 2 +- - drivers/net/wireless/ath/ath11k/hal.c | 9 +- - drivers/net/wireless/ath/ath11k/hif.h | 8 + - drivers/net/wireless/ath/ath11k/hw.c | 13 + - drivers/net/wireless/ath/ath11k/hw.h | 8 + - drivers/net/wireless/ath/ath11k/mac.c | 709 +++++++++++++++++++-- - drivers/net/wireless/ath/ath11k/mac.h | 7 +- - drivers/net/wireless/ath/ath11k/mhi.c | 18 +- - drivers/net/wireless/ath/ath11k/mhi.h | 1 + - drivers/net/wireless/ath/ath11k/pci.c | 181 +++++- - drivers/net/wireless/ath/ath11k/pci.h | 63 ++ - drivers/net/wireless/ath/ath11k/pcic.c | 22 +- - drivers/net/wireless/ath/ath11k/qmi.c | 65 +- - drivers/net/wireless/ath/ath11k/qmi.h | 1 + - drivers/net/wireless/ath/ath11k/reg.c | 189 ++++-- - drivers/net/wireless/ath/ath11k/reg.h | 7 +- - drivers/net/wireless/ath/ath11k/testmode.h | 18 +- - drivers/net/wireless/ath/ath11k/unitest.c | 96 +++ - drivers/net/wireless/ath/ath11k/unitest.h | 44 ++ - drivers/net/wireless/ath/ath11k/wmi.c | 307 +++++++-- - drivers/net/wireless/ath/ath11k/wmi.h | 182 ++++++ - include/net/cfg80211.h | 5 + - include/net/regulatory.h | 1 + - include/uapi/linux/nl80211.h | 11 +- - kernel/dma/direct.c | 1 + - net/wireless/nl80211.c | 18 + - net/wireless/reg.c | 17 + - 33 files changed, 2131 insertions(+), 192 deletions(-) - create mode 100644 drivers/net/wireless/ath/ath11k/unitest.c - create mode 100644 drivers/net/wireless/ath/ath11k/unitest.h + drivers/net/wireless/ath/ath11k/hw.c | 1 + + drivers/net/wireless/ath/ath11k/wmi.c | 1 + + drivers/net/wireless/ath/ath11k/wmi.h | 19 +++++++++++++++++++ + 3 files changed, 21 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c +index dbcc0c4035b62..6309efe4b7c1f 100644 +--- a/drivers/net/wireless/ath/ath11k/hw.c ++++ b/drivers/net/wireless/ath/ath11k/hw.c +@@ -100,6 +100,7 @@ static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab, + config->num_wow_filters = 0x16; + config->num_keep_alive_pattern = 0; + config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; ++ config->host_service_flags |= WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT; + } + + static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 3e0a47f4a3ebd..64648e0d9484d 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -4069,6 +4132,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, + wmi_cfg->sched_params = tg_cfg->sched_params; + wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; + wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; ++ wmi_cfg->host_service_flags = tg_cfg->host_service_flags; + wmi_cfg->host_service_flags &= + ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); + wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 8f2c07d70a4a2..042c7b0d16631 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -2330,6 +2330,7 @@ struct wmi_init_cmd { + #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) + #define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9) + #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) ++#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT BIT(0) + + #define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 + +@@ -5700,6 +5710,15 @@ struct target_resource_config { + u8 is_reg_cc_ext_event_supported; + u32 ema_max_vap_cnt; + u32 ema_max_profile_period; ++ u32 max_nlo_ssids; ++ u32 num_packet_filters; ++ u32 num_max_sta_vdevs; ++ u32 max_bssid_indicator; ++ u32 ul_resp_config; ++ u32 msdu_flow_override_config0; ++ u32 msdu_flow_override_config1; ++ u32 flags2; ++ u32 host_service_flags; + }; -diff --git a/drivers/net/wireless/ath/ath11k/Makefile b/drivers/net/wireless/ath/ath11k/Makefile -index cc47e0114..f591a12a8 100644 ---- a/drivers/net/wireless/ath/ath11k/Makefile -+++ b/drivers/net/wireless/ath/ath11k/Makefile -@@ -17,7 +17,9 @@ ath11k-y += core.o \ - peer.o \ - dbring.o \ - hw.o \ -- pcic.o -+ pcic.o \ -+ wow.o \ -+ unitest.o + enum wmi_debug_log_param { +-- +GitLab + +From bc6d3226e567630188a41a78a12514c74babdea9 Mon Sep 17 00:00:00 2001 +From: "neil.shi" <neil.shi@quectel.com> +Date: Tue, 23 May 2023 17:01:06 +0800 +Subject: [PATCH] wifi: ath11k: [DBS PATCH 2/6] wifi: ath11k: add support for + QCA206X + +--- + drivers/net/wireless/ath/ath11k/core.c | 64 ++++++++++++++++++++++++++ + drivers/net/wireless/ath/ath11k/core.h | 1 + + drivers/net/wireless/ath/ath11k/mhi.c | 1 + + drivers/net/wireless/ath/ath11k/pci.c | 17 ++++++- + 4 files changed, 82 insertions(+), 1 deletion(-) - ath11k-$(CONFIG_ATH11K_DEBUGFS) += debugfs.o debugfs_htt_stats.o debugfs_sta.o - ath11k-$(CONFIG_NL80211_TESTMODE) += testmode.o -diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c -index 289d47ae9..4d04c49ee 100644 ---- a/drivers/net/wireless/ath/ath11k/ce.c -+++ b/drivers/net/wireless/ath/ath11k/ce.c -@@ -627,9 +627,9 @@ ath11k_ce_alloc_ring(struct ath11k_base *ab, int nentries, int desc_sz) - * coherent DMA are unsupported - */ - ce_ring->base_addr_owner_space_unaligned = -- dma_alloc_coherent(ab->dev, -- nentries * desc_sz + CE_DESC_RING_ALIGN, -- &base_addr, GFP_KERNEL); -+ ath11k_core_dma_alloc_coherent(ab->dev, -+ nentries * desc_sz + CE_DESC_RING_ALIGN, -+ &base_addr, GFP_KERNEL | GFP_DMA32); - if (!ce_ring->base_addr_owner_space_unaligned) { - kfree(ce_ring); - return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c -index fc7c4564a..2cbfd20bd 100644 +index 893fefadbba96..96ed5b7cd0048 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c -@@ -9,6 +9,7 @@ - #include <linux/remoteproc.h> - #include <linux/firmware.h> - #include <linux/of.h> -+#include <linux/dma-direct.h> - - #include "core.h" - #include "dp_tx.h" -@@ -16,6 +17,7 @@ - #include "debug.h" - #include "hif.h" - #include "wow.h" -+#include "wmi.h" - - unsigned int ath11k_debug_mask; - EXPORT_SYMBOL(ath11k_debug_mask); -@@ -121,6 +123,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tcl_ring_retry = true, - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, -+ .coex_isolation = true, - }, - { - .hw_rev = ATH11K_HW_IPQ6018_HW10, -@@ -204,6 +207,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, - .support_fw_mac_sequence = false, -+ .coex_isolation = false, -+ .support_fw_mac_sequence = false, - }, - { - .name = "qca6390 hw2.0", -@@ -288,6 +293,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tcl_ring_retry = true, - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, -+ .coex_isolation = false, - .support_fw_mac_sequence = true, - }, - { -@@ -371,6 +377,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, - .support_fw_mac_sequence = false, -+ .coex_isolation = false, -+ .support_fw_mac_sequence = false, - }, - { - .name = "wcn6855 hw2.0", -@@ -410,6 +418,78 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { +@@ -394,6 +394,70 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { .fragment_160mhz = false, }, + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP), + .supports_monitor = false, -+ .full_monitor_mode = false, + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, -+ .coldboot_cal_mm = false, -+ .coldboot_cal_ftm = false, ++ .cold_boot_calib = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, + .num_peers = 512, @@ -152,20 +106,11 @@ index fc7c4564a..2cbfd20bd 100644 + .hal_params = &ath11k_hw_hal_params_qca6390, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = false, ++ .wakeup_mhi = true, + .supports_rssi_stats = true, + .fw_wmi_diag_event = true, + .current_cc_support = true, + .dbr_debug_support = false, -+ .coex_isolation = false, -+ .global_reset = true, -+ .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855, -+ .m3_fw_support = true, -+ .fixed_bdf_addr = false, -+ .fixed_mem_region = false, -+ .static_window_map = false, -+ .hybrid_bus_type = false, -+ .fixed_fw_mem = false, -+ .support_off_channel_tx = true, + }, + { + .name = "qca206x hw2.1", @@ -188,6 +133,9 @@ index fc7c4564a..2cbfd20bd 100644 + .target_ce_count = 9, + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, + .svc_to_ce_map_len = 14, ++ .rfkill_pin = 0, ++ .rfkill_cfg = 0, ++ .rfkill_on_level = 0, + .single_pdev_only = true, + .rxdma1_enable = false, + .num_rxmda_per_pdev = 2, @@ -206,143 +154,8 @@ index fc7c4564a..2cbfd20bd 100644 .interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), .supports_monitor = false, -@@ -456,6 +536,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, - .support_fw_mac_sequence = true, -+ .coex_isolation = true, - }, - { - .name = "wcn6855 hw2.1", -@@ -497,6 +578,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP), - .supports_monitor = false, -+ .full_monitor_mode = false, - .supports_shadow_regs = true, - .idle_ps = true, - .supports_sta_ps = true, -@@ -538,6 +620,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tcl_ring_retry = true, - .tx_ring_size = DP_TCL_DATA_RING_SIZE, - .smp2p_wow_exit = false, -+ .coex_isolation = false, - .support_fw_mac_sequence = true, - }, - { -@@ -619,6 +702,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - .tcl_ring_retry = false, - .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750, - .smp2p_wow_exit = true, -+ .coex_isolation = false, - .support_fw_mac_sequence = true, - }, - { -@@ -704,6 +788,40 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { - }, - }; - -+static const struct dma_map_ops *ath11k_core_get_dma_ops(struct device *dev) -+{ -+ if (dev->dma_ops) -+ return dev->dma_ops; -+ return NULL; -+} -+ -+void *ath11k_core_dma_alloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, gfp_t flag) -+{ -+ unsigned long attrs = (flag & __GFP_NOWARN) ? DMA_ATTR_NO_WARN : 0; -+ const struct dma_map_ops *ops = ath11k_core_get_dma_ops(dev); -+ void *cpu_addr; -+ -+ WARN_ON_ONCE(!dev->coherent_dma_mask); -+ -+ /* -+ * DMA allocations can never be turned back into a page pointer, so -+ * requesting compound pages doesn't make sense (and can't even be -+ * supported at all by various backends). -+ */ -+ if (WARN_ON_ONCE(flag & __GFP_COMP)) -+ return NULL; -+ -+ if (!ops) -+ cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs); -+ else if (ops->alloc) -+ cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs); -+ else -+ return NULL; -+ -+ return cpu_addr; -+} -+ - static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab) - { - WARN_ON(!ab->hw_params.single_pdev_only); -@@ -1505,6 +1623,30 @@ static void ath11k_core_pdev_destroy(struct ath11k_base *ab) - ath11k_debugfs_pdev_destroy(ab); - } - -+static int ath11k_core_config_coex_isolation(struct ath11k_base *ab) -+{ -+ struct ath11k *ar = ath11k_ab_to_ar(ab, 0); -+ struct wmi_coex_config_params param; -+ -+ memset(¶m, 0, sizeof(struct wmi_coex_config_params)); -+ param.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; -+ param.config_arg1 = WMI_COEX_ISOLATION_ARG1_DEFAUT; -+ -+ return ath11k_wmi_send_coex_config(ar, ¶m); -+} -+ -+static int ath11k_core_config_btc_mode(struct ath11k_base *ab) -+{ -+ struct ath11k *ar = ath11k_ab_to_ar(ab, 0); -+ struct wmi_coex_config_params param; -+ -+ memset(¶m, 0, sizeof(struct wmi_coex_config_params)); -+ param.config_type = WMI_COEX_CONFIG_BTC_MODE; -+ param.config_arg1 = WMI_COEX_BTC_MODE_ARG1_DEFAULT; -+ -+ return ath11k_wmi_send_coex_config(ar, ¶m); -+} -+ - static int ath11k_core_start(struct ath11k_base *ab) - { - int ret; -@@ -1602,6 +1744,22 @@ static int ath11k_core_start(struct ath11k_base *ab) - goto err_reo_cleanup; - } - -+ if (ab->hw_params.coex_isolation) { -+ ret = ath11k_core_config_coex_isolation(ab); -+ if (ret) { -+ ath11k_err(ab, "failed to set coex isolation: %d\n", -+ ret); -+ goto err_reo_cleanup; -+ } -+ } -+ -+ ret = ath11k_core_config_btc_mode(ab); -+ if (ret) { -+ ath11k_err(ab, "failed to set btc mode: %d\n", -+ ret); -+ goto err_reo_cleanup; -+ } -+ - return 0; - - err_reo_cleanup: -@@ -1751,6 +1909,7 @@ void ath11k_core_halt(struct ath11k *ar) - ath11k_mac_scan_finish(ar); - ath11k_mac_peer_cleanup_all(ar); - cancel_delayed_work_sync(&ar->scan.timeout); -+ cancel_work_sync(&ar->channel_update_work); - cancel_work_sync(&ar->regd_update_work); - cancel_work_sync(&ab->update_11d_work); - diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h -index b04447762..bac6624f3 100644 +index bd06536f82a64..ab120329619c0 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -144,6 +144,7 @@ enum ath11k_hw_rev { @@ -353,1145 +166,83 @@ index b04447762..bac6624f3 100644 }; enum ath11k_firmware_mode { -@@ -311,6 +312,43 @@ struct ath11k_rekey_data { - bool enable_offload; - }; - -+/** -+ * struct chan_power_info - TPE containing power info per channel chunk -+ * @chan_cfreq: channel center freq (MHz) -+ * e.g. -+ * channel 37/20 MHz, it is 6135 -+ * channel 37/40 MHz, it is 6125 -+ * channel 37/80 MHz, it is 6145 -+ * channel 37/160 MHz, it is 6185 -+ * @tx_power: transmit power (dBm) -+ */ -+struct chan_power_info { -+ u16 chan_cfreq; -+ s8 tx_power; -+}; -+ -+/** -+ * struct reg_tpc_power_info - regulatory TPC power info -+ * @is_psd_power: is PSD power or not -+ * @eirp_power: Maximum EIRP power (dBm), valid only if power is PSD -+ * @power_type_6g: type of power (SP/LPI/VLP) -+ * @num_pwr_levels: number of power levels -+ * @reg_max: Array of maximum TX power (dBm) per PSD value -+ * @ap_constraint_power: AP constraint power (dBm) -+ * @tpe: TPE values processed from TPE IE -+ * @chan_power_info: power info to send to firmware -+ */ -+struct ath11k_reg_tpc_power_info { -+ bool is_psd_power; -+ u8 eirp_power; -+ enum wmi_reg_6ghz_ap_type power_type_6g; -+ u8 num_pwr_levels; -+ u8 reg_max[IEEE80211_MAX_NUM_PWR_LEVEL]; -+ u8 ap_constraint_power; -+ s8 tpe[IEEE80211_MAX_NUM_PWR_LEVEL]; -+ struct chan_power_info chan_power_info[IEEE80211_MAX_NUM_PWR_LEVEL]; -+}; -+ - struct ath11k_vif { - u32 vdev_id; - enum wmi_vdev_type vdev_type; -@@ -369,6 +407,7 @@ struct ath11k_vif { - #ifdef CONFIG_ATH11K_DEBUGFS - struct dentry *debugfs_twt; - #endif /* CONFIG_ATH11K_DEBUGFS */ -+ struct ath11k_reg_tpc_power_info reg_tpc_info; - }; - - struct ath11k_vif_iter { -@@ -697,6 +736,10 @@ struct ath11k { - struct completion bss_survey_done; - - struct work_struct regd_update_work; -+ struct work_struct channel_update_work; -+ struct list_head channel_update_queue; -+ /* protects channel_update_queue data */ -+ spinlock_t channel_update_lock; - - struct work_struct wmi_mgmt_tx_work; - struct sk_buff_head wmi_mgmt_tx_queue; -@@ -737,6 +780,7 @@ struct ath11k { - /* protected by conf_mutex */ - bool ps_state_enable; - bool ps_timekeeper_enable; -+ s8 max_allowed_tx_power; - }; - - struct ath11k_band_cap { -@@ -840,6 +884,16 @@ struct ath11k_msi_config { - u16 hw_rev; - }; - -+struct fw_remote_mem { -+ size_t size; -+ void *vaddr; -+}; -+ -+struct fw_remote_crash_data { -+ u8 *remote_buf; -+ size_t remote_buf_len; -+}; -+ - /* Master structure to hold the hw data which may be used in core module */ - struct ath11k_base { - enum ath11k_hw_rev hw_rev; -@@ -923,6 +977,7 @@ struct ath11k_base { - * This may or may not be used during the runtime - */ - struct ieee80211_regdomain *new_regd[MAX_RADIOS]; -+ struct cur_regulatory_info *reg_info_store; - - /* Current DFS Regulatory */ - enum ath11k_dfs_region dfs_region; -@@ -992,6 +1047,9 @@ struct ath11k_base { - } testmode; - #endif - -+ struct fw_remote_mem remote_mem[ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; -+ struct fw_remote_crash_data remote_crash_data; -+ - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); - }; -@@ -1251,4 +1309,6 @@ static inline const char *ath11k_bus_str(enum ath11k_bus bus) - return "unknown"; - } - -+void *ath11k_core_dma_alloc_coherent(struct device *dev, size_t size, -+ dma_addr_t *dma_handle, gfp_t flag); - #endif /* _CORE_H_ */ -diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c -index 5bb6fd17f..7fad6e447 100644 ---- a/drivers/net/wireless/ath/ath11k/debugfs.c -+++ b/drivers/net/wireless/ath/ath11k/debugfs.c -@@ -468,6 +468,78 @@ static const struct file_operations fops_bcn_stats = { - .llseek = default_llseek, - }; +diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c +index a62ee05c54097..c76f665dc369d 100644 +--- a/drivers/net/wireless/ath/ath11k/mhi.c ++++ b/drivers/net/wireless/ath/ath11k/mhi.c +@@ -434,6 +434,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) + case ATH11K_HW_QCA6390_HW20: + case ATH11K_HW_WCN6855_HW20: + case ATH11K_HW_WCN6855_HW21: ++ case ATH11K_HW_QCA206X_HW21: + ath11k_mhi_config = &ath11k_mhi_config_qca6390; + break; + default: +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index 3c6005ab9a717..93dd259bd85ad 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -27,6 +27,8 @@ + #define QCN9074_DEVICE_ID 0x1104 + #define WCN6855_DEVICE_ID 0x1103 -+static ssize_t ath11k_debugfs_write_coex_config(struct file *file, -+ const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ath11k_base *ab = file->private_data; -+ struct ath11k *ar = ath11k_ab_to_ar(ab, 0); -+ char buf[64] = {0}; -+ ssize_t ret; -+ int rc; -+ u32 config_type, config_arg1; -+ char sep[] = " "; -+ char *token, *cur; -+ struct wmi_coex_config_params param; -+ -+ if (*ppos != 0 || count >= sizeof(buf) || count == 0) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -+ if (ret < 0) -+ goto out; -+ -+ /* drop the possible '\n' from the end */ -+ if (buf[*ppos - 1] == '\n') -+ buf[*ppos - 1] = '\0'; -+ -+ ath11k_info(ab, "%s: %s\n", __func__, buf); -+ ret = count; -+ cur = buf; -+ -+ token = strsep(&cur, sep); -+ rc = kstrtou32(token, 0, &config_type); -+ if (rc) { -+ ath11k_warn(ab, "%s convert error: config_type %s\n", __func__, token); -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ token = strim(cur); -+ rc = kstrtou32(token, 0, &config_arg1); -+ if (rc) { -+ ath11k_warn(ab, "%s convert error: config_arg1 %s\n", __func__, token); -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ -+ memset(¶m, 0, sizeof(struct wmi_coex_config_params)); -+ param.config_type = config_type; -+ param.config_arg1 = config_arg1; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ rc = ath11k_mac_send_coex_config(ar, ¶m); -+ if (rc) { -+ ath11k_warn(ab, "failed to send coex config using debugfs %d\n", rc); -+ ret = -EFAULT; -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -+out: -+ return ret; -+} -+ -+static const struct file_operations fops_coex_config = { -+ .write = ath11k_debugfs_write_coex_config, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+}; ++#define SUB_VERSION 0x1910010 + - static ssize_t ath11k_read_simulate_fw_crash(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -@@ -532,6 +604,10 @@ static ssize_t ath11k_write_simulate_fw_crash(struct file *file, - ath11k_info(ab, "user requested hw restart\n"); - queue_work(ab->workqueue_aux, &ab->reset_work); - ret = 0; -+ } else if (!strcmp(buf, "mhi-rddm")) { -+ ath11k_info(ab, "force target rddm\n"); -+ ath11k_hif_force_rddm(ab); -+ ret = 0; - } else { - ret = -EINVAL; - goto exit; -@@ -957,9 +1033,12 @@ static ssize_t ath11k_read_sram_dump(struct file *file, - - static int ath11k_release_sram_dump(struct inode *inode, struct file *file) + static const struct pci_device_id ath11k_pci_id_table[] = { + { PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) }, + { PCI_VDEVICE(QCOM, WCN6855_DEVICE_ID) }, +@@ -806,7 +808,19 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + break; + case 0x10: + case 0x11: +- ab->hw_rev = ATH11K_HW_WCN6855_HW21; ++ //ab->hw_rev = ATH11K_HW_WCN6855_HW21; ++ sub_version = ath11k_pci_read32(ab, SUB_VERSION); ++ ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n", sub_version); ++ switch (sub_version) { ++ case 0x1019A0E1: ++ case 0x1019B0E1: ++ case 0x1019C0E1: ++ case 0x1019D0E1: ++ ab->hw_rev = ATH11K_HW_QCA206X_HW21; ++ break; ++ default: ++ ab->hw_rev = ATH11K_HW_WCN6855_HW21; ++ } + break; + default: + goto unsupported_wcn6855_soc; +@@ -1017,6 +1031,7 @@ static struct pci_driver ath11k_pci_driver = { + static int ath11k_pci_init(void) { -+ struct ath11k_base *ab = inode->i_private; - vfree(file->private_data); - file->private_data = NULL; - -+ debugfs_create_file("coex_config", 0600, ab->debugfs_soc, ab, -+ &fops_coex_config); - return 0; - } - -diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c -index d070bcb3f..6b6d0ce4f 100644 ---- a/drivers/net/wireless/ath/ath11k/dp.c -+++ b/drivers/net/wireless/ath/ath11k/dp.c -@@ -254,9 +254,9 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring, - } - - if (!cached) -- ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size, -+ ring->vaddr_unaligned = ath11k_core_dma_alloc_coherent(ab->dev, ring->size, - &ring->paddr_unaligned, -- GFP_KERNEL); -+ GFP_KERNEL | GFP_DMA32); - - if (!ring->vaddr_unaligned) - return -ENOMEM; -@@ -527,9 +527,9 @@ static int ath11k_dp_scatter_idle_link_desc_setup(struct ath11k_base *ab, - return -EINVAL; - - for (i = 0; i < num_scatter_buf; i++) { -- slist[i].vaddr = dma_alloc_coherent(ab->dev, -+ slist[i].vaddr = ath11k_core_dma_alloc_coherent(ab->dev, - HAL_WBM_IDLE_SCATTER_BUF_SIZE_MAX, -- &slist[i].paddr, GFP_KERNEL); -+ &slist[i].paddr, GFP_KERNEL | GFP_DMA32); - if (!slist[i].vaddr) { - ret = -ENOMEM; - goto err; -@@ -607,9 +607,9 @@ static int ath11k_dp_link_desc_bank_alloc(struct ath11k_base *ab, - desc_sz = last_bank_sz; - - desc_bank[i].vaddr_unaligned = -- dma_alloc_coherent(ab->dev, desc_sz, -+ ath11k_core_dma_alloc_coherent(ab->dev, desc_sz, - &desc_bank[i].paddr_unaligned, -- GFP_KERNEL); -+ GFP_KERNEL | GFP_DMA32); - if (!desc_bank[i].vaddr_unaligned) { - ret = -ENOMEM; - goto err; -diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c -index a993e74bb..5b1320b4b 100644 ---- a/drivers/net/wireless/ath/ath11k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c -@@ -2549,7 +2549,7 @@ static int ath11k_dp_rx_process_msdu(struct ath11k *ar, - lrx_desc = (struct hal_rx_desc *)last_buf->data; - rx_attention = ath11k_dp_rx_get_attention(ab, lrx_desc); - if (!ath11k_dp_rx_h_attn_msdu_done(rx_attention)) { -- ath11k_warn(ab, "msdu_done bit in attention is not set\n"); -+ ath11k_dbg(ab, ATH11K_DBG_DATA, "msdu_done bit in attention is not set\n"); - ret = -EIO; - goto free_out; - } -diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c -index 0a99aa7dd..efff993c9 100644 ---- a/drivers/net/wireless/ath/ath11k/hal.c -+++ b/drivers/net/wireless/ath/ath11k/hal.c -@@ -8,6 +8,7 @@ - #include "debug.h" - #include "hal_desc.h" - #include "hif.h" -+#include "core.h" - - static const struct hal_srng_config hw_srng_config_template[] = { - /* TODO: max_rings can populated by querying HW capabilities */ -@@ -196,8 +197,8 @@ static int ath11k_hal_alloc_cont_rdp(struct ath11k_base *ab) - size_t size; - - size = sizeof(u32) * HAL_SRNG_RING_ID_MAX; -- hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, -- GFP_KERNEL); -+ hal->rdp.vaddr = ath11k_core_dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr, -+ GFP_KERNEL | GFP_DMA32); - if (!hal->rdp.vaddr) - return -ENOMEM; - -@@ -224,8 +225,8 @@ static int ath11k_hal_alloc_cont_wrp(struct ath11k_base *ab) - size_t size; - - size = sizeof(u32) * HAL_SRNG_NUM_LMAC_RINGS; -- hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, -- GFP_KERNEL); -+ hal->wrp.vaddr = ath11k_core_dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr, -+ GFP_KERNEL | GFP_DMA32); - if (!hal->wrp.vaddr) - return -ENOMEM; - -diff --git a/drivers/net/wireless/ath/ath11k/hif.h b/drivers/net/wireless/ath/ath11k/hif.h -index 659b80d2a..7eca43a91 100644 ---- a/drivers/net/wireless/ath/ath11k/hif.h -+++ b/drivers/net/wireless/ath/ath11k/hif.h -@@ -30,6 +30,7 @@ struct ath11k_hif_ops { - void (*ce_irq_enable)(struct ath11k_base *ab); - void (*ce_irq_disable)(struct ath11k_base *ab); - void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx); -+ int (*target_crash)(struct ath11k_base *ab); - }; + int ret; ++ u32 sub_version; - static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab) -@@ -90,6 +91,13 @@ static inline int ath11k_hif_resume(struct ath11k_base *ab) - return 0; - } + ret = pci_register_driver(&ath11k_pci_driver); + if (ret) +-- +GitLab -+static inline int ath11k_hif_force_rddm(struct ath11k_base *ab) -+{ -+ if (ab->hif.ops->target_crash) -+ return ab->hif.ops->target_crash(ab); -+ return 0; -+} -+ - static inline u32 ath11k_hif_read32(struct ath11k_base *sc, u32 address) - { - return sc->hif.ops->read32(sc, address); -diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c -index d7b5ec6e6..1e82683f9 100644 ---- a/drivers/net/wireless/ath/ath11k/hw.c -+++ b/drivers/net/wireless/ath/ath11k/hw.c -@@ -100,6 +100,7 @@ static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab, - config->num_wow_filters = 0x16; - config->num_keep_alive_pattern = 0; - config->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; -+ config->host_service_flags |= WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT; - } +From 707933ef2a20db8f7c3d9d3c654a8dcb2f582436 Mon Sep 17 00:00:00 2001 +From: "neil.shi" <neil.shi@quectel.com> +Date: Tue, 23 May 2023 17:04:27 +0800 +Subject: [PATCH] wifi: ath11k: [DBS PATCH 3/6]: support 2 stations and report + addresses - static void ath11k_hw_ipq8074_reo_setup(struct ath11k_base *ab) -@@ -900,6 +901,18 @@ static u32 ath11k_hw_wcn6750_get_tcl_ring_selector(struct sk_buff *skb) - return skb_get_hash(skb); - } +Report 2 station interfaces if chip has more than 1 +num_rxmda_per_pdev in hw_params, and report addresses +for these interfaces. -+bool ath11k_hw_supports_6g_cc_ext(struct ath11k *ar) -+{ -+ return (test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT, -+ ar->ab->wmi_ab.svc_map)) && ar->supports_6ghz; -+} -+ -+bool ath11k_hw_supports_tpc_ext(struct ath11k *ar) -+{ -+ return ath11k_hw_supports_6g_cc_ext(ar) && -+ test_bit(WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT, ar->ab->wmi_ab.svc_map); -+} -+ - const struct ath11k_hw_ops ipq8074_ops = { - .get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id, - .wmi_init_config = ath11k_init_wmi_config_ipq8074, -diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h -index d51a99669..b23494409 100644 ---- a/drivers/net/wireless/ath/ath11k/hw.h -+++ b/drivers/net/wireless/ath/ath11k/hw.h -@@ -225,6 +225,11 @@ struct ath11k_hw_params { - bool tcl_ring_retry; - u32 tx_ring_size; - bool smp2p_wow_exit; -+ bool wakeup_mhi; -+ u32 rfkill_pin; -+ u32 rfkill_cfg; -+ u32 rfkill_on_level; -+ bool coex_isolation; - bool support_fw_mac_sequence; - }; - -@@ -321,6 +326,9 @@ static inline int ath11k_hw_mac_id_to_srng_id(struct ath11k_hw_params *hw, - return 0; - } +Signed-off-by: neil.shi <neil.shi@quectel.com> +--- + drivers/net/wireless/ath/ath11k/mac.c | 83 ++++++++++++++++++++------- + 1 file changed, 63 insertions(+), 20 deletions(-) -+bool ath11k_hw_supports_6g_cc_ext(struct ath11k *ar); -+bool ath11k_hw_supports_tpc_ext(struct ath11k *ar); -+ - struct ath11k_fw_ie { - __le32 id; - __le32 len; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c -index b328a0599..8a034a971 100644 +index cb77dd6ce9665..c7fa31deefacd 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -23,6 +23,7 @@ - #include "debugfs_sta.h" - #include "hif.h" - #include "wow.h" -+#include "unitest.h" - - #define CHAN2G(_channel, _freq, _flags) { \ - .band = NL80211_BAND_2GHZ, \ -@@ -254,6 +255,10 @@ static const u32 ath11k_smps_map[] = { - [WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE, - }; - -+static struct wiphy_vendor_command ath11k_vendor_cmds[] = { -+ ath11k_unit_test_command, -+}; -+ - static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); - -@@ -629,6 +634,17 @@ struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id) - return NULL; - } - -+enum wmi_vdev_type ath11k_mac_get_ar_vdev_type(struct ath11k *ar) -+{ -+ struct ath11k_vif *arvif; -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ return arvif->vdev_type; -+ } -+ -+ return WMI_VDEV_TYPE_UNSPEC; -+} -+ - struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id) - { - int i; -@@ -2980,6 +2996,27 @@ static bool ath11k_mac_vif_recalc_sta_he_txbf(struct ath11k *ar, - hemode |= FIELD_PREP(HE_MODE_SU_TX_BFER, HE_SU_BFER_ENABLE); - } - -+ ath11k_info(ar->ab, "mac0-5 cap %x-%x-%x-%x-%x-%x\n", -+ he_cap_elem.mac_cap_info[0], -+ he_cap_elem.mac_cap_info[1], -+ he_cap_elem.mac_cap_info[2], -+ he_cap_elem.mac_cap_info[3], -+ he_cap_elem.mac_cap_info[4], -+ he_cap_elem.mac_cap_info[5]); -+ ath11k_info(ar->ab, "phy0-5 cap %x-%x-%x-%x-%x-%x\n", -+ he_cap_elem.phy_cap_info[0], -+ he_cap_elem.phy_cap_info[1], -+ he_cap_elem.phy_cap_info[2], -+ he_cap_elem.phy_cap_info[3], -+ he_cap_elem.phy_cap_info[4], -+ he_cap_elem.phy_cap_info[5]); -+ ath11k_info(ar->ab, "phy6-10 cap %x-%x-%x-%x-%x\n", -+ he_cap_elem.phy_cap_info[6], -+ he_cap_elem.phy_cap_info[7], -+ he_cap_elem.phy_cap_info[8], -+ he_cap_elem.phy_cap_info[9], -+ he_cap_elem.phy_cap_info[10]); -+ ath11k_info(ar->ab, "WMI_VDEV_PARAM_SET_HEMU_MODE 3 0x%x\n", hemode); - ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id, param, hemode); - if (ret) { - ath11k_warn(ar->ab, "failed to submit vdev param txbf 0x%x: %d\n", -@@ -3025,7 +3062,14 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, - - rcu_read_unlock(); - -+ if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { -+ ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", -+ arvif->vdev_id, bss_conf->bssid); -+ return; -+ } -+ - peer_arg.is_assoc = true; -+ - ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg); - if (ret) { - ath11k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n", -@@ -3048,12 +3092,6 @@ static void ath11k_bss_assoc(struct ieee80211_hw *hw, - return; - } - -- if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) { -- ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n", -- arvif->vdev_id, bss_conf->bssid); -- return; -- } -- - WARN_ON(arvif->is_up); - - arvif->aid = vif->cfg.aid; -@@ -3396,6 +3434,16 @@ static int ath11k_mac_config_obss_pd(struct ath11k *ar, - return 0; - } - -+static bool ath11k_mac_supports_station_tpc(struct ath11k *ar, -+ struct ath11k_vif *arvif, -+ const struct cfg80211_chan_def *chandef) -+{ -+ return ath11k_hw_supports_tpc_ext(ar) && -+ arvif->vdev_type == WMI_VDEV_TYPE_STA && -+ chandef->chan && -+ chandef->chan->band == NL80211_BAND_6GHZ; -+} -+ - static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *info, -@@ -3596,8 +3644,13 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw, - ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "vdev_id %i txpower %d\n", - arvif->vdev_id, info->txpower); - -- arvif->txpower = info->txpower; -- ath11k_mac_txpower_recalc(ar); -+ if (ath11k_mac_supports_station_tpc(ar, arvif, &info->chandef)) { -+ ath11k_dbg(ar->ab, ATH11K_DBG_MAC, -+ "discard tx power, change to set TPC power\n"); -+ } else { -+ arvif->txpower = info->txpower; -+ ath11k_mac_txpower_recalc(ar); -+ } - } - - if (changed & BSS_CHANGED_PS && -@@ -5463,8 +5516,6 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) - if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) { - nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; - nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -- if (nsts > (ar->num_rx_chains - 1)) -- nsts = ar->num_rx_chains - 1; - value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET); - } - -@@ -5505,7 +5556,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif) - static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) - { - bool subfer, subfee; -- int sound_dim = 0, nsts = 0; -+ int sound_dim = 0; - - subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)); - subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)); -@@ -5515,11 +5566,6 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) - subfer = false; - } - -- if (ar->num_rx_chains < 2) { -- *vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); -- subfee = false; -- } -- - /* If SU Beaformer is not set, then disable MU Beamformer Capability */ - if (!subfer) - *vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); -@@ -5532,9 +5578,7 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) - sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; - *vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; - -- nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); -- nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -- *vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; -+ /* TODO: Need to check invalid STS and Sound_dim values set by FW? */ - - /* Enable Sounding Dimension Field only if SU BF is enabled */ - if (subfer) { -@@ -5546,15 +5590,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap) - *vht_cap |= sound_dim; - } - -- /* Enable Beamformee STS Field only if SU BF is enabled */ -- if (subfee) { -- if (nsts > (ar->num_rx_chains - 1)) -- nsts = ar->num_rx_chains - 1; -- -- nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; -- nsts &= IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK; -- *vht_cap |= nsts; -- } -+ /* Use the STS advertised by FW unless SU Beamformee is not supported*/ -+ if (!subfee) -+ *vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK); - } - - static struct ieee80211_sta_vht_cap -@@ -6386,6 +6424,14 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) - } - } - -+ if (ath11k_hw_supports_6g_cc_ext(ar)) { -+ struct cur_regulatory_info *reg_info; -+ -+ reg_info = &ab->reg_info_store[ar->pdev_idx]; -+ ath11k_dbg(ab, ATH11K_DBG_MAC, "mac interface added to change reg rules\n"); -+ ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_LPI_AP); -+ } -+ - mutex_unlock(&ar->conf_mutex); - - rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], -@@ -6404,6 +6450,7 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) - { - struct ath11k *ar = hw->priv; - struct htt_ppdu_stats_info *ppdu_stats, *tmp; -+ struct scan_chan_list_params *params, *tmp_ch; - int ret; - - ath11k_mac_drain_tx(ar); -@@ -6419,6 +6466,7 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) - mutex_unlock(&ar->conf_mutex); - - cancel_delayed_work_sync(&ar->scan.timeout); -+ cancel_work_sync(&ar->channel_update_work); - cancel_work_sync(&ar->regd_update_work); - cancel_work_sync(&ar->ab->update_11d_work); - -@@ -6434,6 +6482,13 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) - } - spin_unlock_bh(&ar->data_lock); - -+ spin_lock_bh(&ar->channel_update_lock); -+ list_for_each_entry_safe(params, tmp_ch, &ar->channel_update_queue, list) { -+ list_del(¶ms->list); -+ kfree(params); -+ } -+ spin_unlock_bh(&ar->channel_update_lock); -+ - rcu_assign_pointer(ar->ab->pdevs_active[ar->pdev_idx], NULL); - - synchronize_rcu(); -@@ -7266,6 +7321,12 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif, - return ret; - } - -+ if (ath11k_mac_supports_station_tpc(ar, arvif, chandef)) { -+ ath11k_mac_fill_reg_tpc_info(ar, arvif->vif, &arvif->chanctx); -+ ath11k_wmi_send_vdev_set_tpc_power(ar, arvif->vdev_id, -+ &arvif->reg_tpc_info); -+ } -+ - if (!restart) - ar->num_started_vdevs++; - -@@ -7588,6 +7649,469 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw, - return 0; - } - -+static u8 ath11k_mac_get_tpe_count(u8 txpwr_intrprt, u8 txpwr_cnt) -+{ -+ switch (txpwr_intrprt) { -+ /* Refer "Table 9-276-Meaning of Maximum Transmit Power Count subfield -+ * if the Maximum Transmit Power Interpretation subfield is 0 or 2" of -+ * "IEEE Std 802.11ax 2021". -+ */ -+ case IEEE80211_TPE_LOCAL_EIRP: -+ case IEEE80211_TPE_REG_CLIENT_EIRP: -+ txpwr_cnt = txpwr_cnt <= 3 ? txpwr_cnt : 3; -+ txpwr_cnt = txpwr_cnt + 1; -+ break; -+ /* Refer "Table 9-277-Meaning of Maximum Transmit Power Count subfield -+ * if Maximum Transmit Power Interpretation subfield is 1 or 3" of -+ * "IEEE Std 802.11ax 2021". -+ */ -+ case IEEE80211_TPE_LOCAL_EIRP_PSD: -+ case IEEE80211_TPE_REG_CLIENT_EIRP_PSD: -+ txpwr_cnt = txpwr_cnt <= 4 ? txpwr_cnt : 4; -+ txpwr_cnt = txpwr_cnt ? (BIT(txpwr_cnt - 1)) : 1; -+ break; -+ } -+ -+ return txpwr_cnt; -+} -+ -+static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def) -+{ -+ if (chan_def->chan->flags & IEEE80211_CHAN_PSD) { -+ switch (chan_def->width) { -+ case NL80211_CHAN_WIDTH_20: -+ return 1; -+ case NL80211_CHAN_WIDTH_40: -+ return 2; -+ case NL80211_CHAN_WIDTH_80: -+ return 4; -+ case NL80211_CHAN_WIDTH_80P80: -+ case NL80211_CHAN_WIDTH_160: -+ return 8; -+ default: -+ return 1; -+ } -+ } else { -+ switch (chan_def->width) { -+ case NL80211_CHAN_WIDTH_20: -+ return 1; -+ case NL80211_CHAN_WIDTH_40: -+ return 2; -+ case NL80211_CHAN_WIDTH_80: -+ return 3; -+ case NL80211_CHAN_WIDTH_80P80: -+ case NL80211_CHAN_WIDTH_160: -+ return 4; -+ default: -+ return 1; -+ } -+ } -+} -+ -+static u16 ath11k_mac_get_6g_start_frequency(struct cfg80211_chan_def *chan_def) -+{ -+ u16 diff_seq; -+ -+ /* It is to get the lowest channel number's center frequency of the chan. -+ * For example, -+ * bandwidth=40 MHz, center frequency is 5965, lowest channel is 1 -+ * with center frequency 5955, its diff is 5965 - 5955 = 10. -+ * bandwidth=80 MHz, center frequency is 5985, lowest channel is 1 -+ * with center frequency 5955, its diff is 5985 - 5955 = 30. -+ * bandwidth=160 MHz, center frequency is 6025, lowest channel is 1 -+ * with center frequency 5955, its diff is 6025 - 5955 = 70. -+ */ -+ switch (chan_def->width) { -+ case NL80211_CHAN_WIDTH_160: -+ diff_seq = 70; -+ break; -+ case NL80211_CHAN_WIDTH_80: -+ case NL80211_CHAN_WIDTH_80P80: -+ diff_seq = 30; -+ break; -+ case NL80211_CHAN_WIDTH_40: -+ diff_seq = 10; -+ break; -+ default: -+ diff_seq = 0; -+ } -+ -+ return chan_def->center_freq1 - diff_seq; -+} -+ -+static u16 ath11k_mac_get_seg_freq(struct cfg80211_chan_def *chan_def, -+ u16 start_seq, u8 seq) -+{ -+ u16 seg_seq; -+ -+ /* It is to get the center frequency of the specific bandwidth. -+ * start_seq means the lowest channel number's center frequency. -+ * seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz&80P80. -+ * For example, -+ * lowest channel is 1, its center frequency 5955, -+ * center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0. -+ * lowest channel is 1, its center frequency 5955, -+ * center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10. -+ * lowest channel is 1, its center frequency 5955, -+ * center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30. -+ * lowest channel is 1, its center frequency 5955, -+ * center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70. -+ */ -+ if (chan_def->width == NL80211_CHAN_WIDTH_80P80 && seq == 3) -+ return chan_def->center_freq2; -+ -+ seg_seq = 10 * (BIT(seq) - 1); -+ return seg_seq + start_seq; -+} -+ -+static void ath11k_mac_get_psd_channel(struct ath11k *ar, -+ u16 step_freq, -+ u16 *start_freq, -+ u16 *center_freq, -+ u8 i, -+ struct ieee80211_channel **temp_chan, -+ s8 *tx_power) -+{ -+ /* It is to get the the center frequency for each 20 MHz. -+ * For example, if the chan is 160 MHz and center frequency is 6025, -+ * then it include 8 channels, they are 1/5/9/13/17/21/25/29, -+ * channel number 1's center frequency is 5955, it is parameter start_freq. -+ * parameter i is the step of the 8 channels. i is 0~7 for the 8 channels. -+ * the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7, -+ * and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095, -+ * the gap is 20 for each channel, parameter step_freq means the gap. -+ * after get the center frequency of each channel, it is easy to find the -+ * struct ieee80211_channel of it and get the max_reg_power. -+ */ -+ *center_freq = *start_freq + i * step_freq; -+ *temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq); -+ *tx_power = (*temp_chan)->max_reg_power; -+} -+ -+static void ath11k_mac_get_eirp_power(struct ath11k *ar, -+ u16 *start_freq, -+ u16 *center_freq, -+ u8 i, -+ struct ieee80211_channel **temp_chan, -+ struct cfg80211_chan_def *def, -+ s8 *tx_power) -+{ -+ /* It is to get the the center frequency for 20 MHz/40 MHz/80 MHz/ -+ * 160 MHz&80P80 bandwidth, and then plus 10 to the center frequency, -+ * it is the center frequency of a channel number. -+ * For example, when configured channel number is 1. -+ * center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975, -+ * then it is channel number 5. -+ * center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995, -+ * then it is channel number 9. -+ * center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035, -+ * then it is channel number 17. -+ * after get the center frequency of each channel, it is easy to find the -+ * struct ieee80211_channel of it and get the max_reg_power. -+ */ -+ *center_freq = ath11k_mac_get_seg_freq(def, *start_freq, i); -+ -+ /* For the 20 MHz, its center frequency is same with same channel */ -+ if (i != 0) -+ *center_freq += 10; -+ -+ *temp_chan = ieee80211_get_channel(ar->hw->wiphy, *center_freq); -+ *tx_power = (*temp_chan)->max_reg_power; -+} -+ -+void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar, -+ struct ieee80211_vif *vif, -+ struct ieee80211_chanctx_conf *ctx) -+{ -+ struct ath11k_base *ab = ar->ab; -+ struct ath11k_vif *arvif = (void *)vif->drv_priv; -+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; -+ struct ath11k_reg_tpc_power_info *reg_tpc_info = &arvif->reg_tpc_info; -+ struct ieee80211_channel *chan, *temp_chan; -+ u8 pwr_lvl_idx, num_pwr_levels, pwr_reduction; -+ bool is_psd_power = false, is_tpe_present = false; -+ s8 max_tx_power[IEEE80211_MAX_NUM_PWR_LEVEL], -+ psd_power, tx_power, eirp_power; -+ u16 oper_freq, start_freq, center_freq; -+ -+ chan = ctx->def.chan; -+ oper_freq = ctx->def.chan->center_freq; -+ start_freq = ath11k_mac_get_6g_start_frequency(&ctx->def); -+ pwr_reduction = bss_conf->pwr_reduction; -+ -+ if (arvif->reg_tpc_info.num_pwr_levels) { -+ is_tpe_present = true; -+ num_pwr_levels = arvif->reg_tpc_info.num_pwr_levels; -+ } else { -+ num_pwr_levels = ath11k_mac_get_num_pwr_levels(&ctx->def); -+ } -+ -+ for (pwr_lvl_idx = 0; pwr_lvl_idx < num_pwr_levels; pwr_lvl_idx++) { -+ /* STA received TPE IE*/ -+ if (is_tpe_present) { -+ /* local power is PSD power*/ -+ if (chan->flags & IEEE80211_CHAN_PSD) { -+ /* Connecting AP is psd power */ -+ if (reg_tpc_info->is_psd_power) { -+ is_psd_power = true; -+ ath11k_mac_get_psd_channel(ar, 20, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &tx_power); -+ psd_power = temp_chan->psd; -+ eirp_power = tx_power; -+ max_tx_power[pwr_lvl_idx] = -+ min_t(s8, -+ psd_power, -+ reg_tpc_info->tpe[pwr_lvl_idx]); -+ /* Connecting AP is not psd power */ -+ } else { -+ ath11k_mac_get_eirp_power(ar, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &ctx->def, -+ &tx_power); -+ psd_power = temp_chan->psd; -+ /* convert psd power to EIRP power based -+ * on channel width -+ */ -+ tx_power = -+ min_t(s8, tx_power, -+ psd_power + 13 + pwr_lvl_idx * 3); -+ max_tx_power[pwr_lvl_idx] = -+ min_t(s8, -+ tx_power, -+ reg_tpc_info->tpe[pwr_lvl_idx]); -+ } -+ /* local power is not PSD power */ -+ } else { -+ /* Connecting AP is psd power */ -+ if (reg_tpc_info->is_psd_power) { -+ is_psd_power = true; -+ ath11k_mac_get_psd_channel(ar, 20, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &tx_power); -+ eirp_power = tx_power; -+ max_tx_power[pwr_lvl_idx] = -+ reg_tpc_info->tpe[pwr_lvl_idx]; -+ /* Connecting AP is not psd power */ -+ } else { -+ ath11k_mac_get_eirp_power(ar, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &ctx->def, -+ &tx_power); -+ max_tx_power[pwr_lvl_idx] = -+ min_t(s8, -+ tx_power, -+ reg_tpc_info->tpe[pwr_lvl_idx]); -+ } -+ } -+ /* STA not received TPE IE */ -+ } else { -+ /* local power is PSD power*/ -+ if (chan->flags & IEEE80211_CHAN_PSD) { -+ is_psd_power = true; -+ ath11k_mac_get_psd_channel(ar, 20, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &tx_power); -+ psd_power = temp_chan->psd; -+ eirp_power = tx_power; -+ max_tx_power[pwr_lvl_idx] = psd_power; -+ } else { -+ ath11k_mac_get_eirp_power(ar, -+ &start_freq, -+ ¢er_freq, -+ pwr_lvl_idx, -+ &temp_chan, -+ &ctx->def, -+ &tx_power); -+ max_tx_power[pwr_lvl_idx] = -+ min_t(s8, -+ tx_power, -+ reg_tpc_info->tpe[pwr_lvl_idx]); -+ } -+ } -+ -+ if (is_psd_power) { -+ /* If AP local power constraint is present */ -+ if (pwr_reduction) -+ eirp_power = eirp_power - pwr_reduction; -+ -+ /* If firmware updated max tx power is non zero, then take -+ * the min of firmware updated ap tx power -+ * and max power derived from above mentioned parameters. -+ */ -+ ath11k_dbg(ab, ATH11K_DBG_MAC, -+ "eirp power : %d firmware report power : %d\n", -+ eirp_power, ar->max_allowed_tx_power); -+ if (ar->max_allowed_tx_power) -+ eirp_power = min_t(s8, -+ eirp_power, -+ ar->max_allowed_tx_power); -+ } else { -+ /* If AP local power constraint is present */ -+ if (pwr_reduction) -+ max_tx_power[pwr_lvl_idx] = -+ max_tx_power[pwr_lvl_idx] - pwr_reduction; -+ /* If firmware updated max tx power is non zero, then take -+ * the min of firmware updated ap tx power -+ * and max power derived from above mentioned parameters. -+ */ -+ if (ar->max_allowed_tx_power) -+ max_tx_power[pwr_lvl_idx] = -+ min_t(s8, -+ max_tx_power[pwr_lvl_idx], -+ ar->max_allowed_tx_power); -+ } -+ reg_tpc_info->chan_power_info[pwr_lvl_idx].chan_cfreq = center_freq; -+ reg_tpc_info->chan_power_info[pwr_lvl_idx].tx_power = -+ max_tx_power[pwr_lvl_idx]; -+ } -+ -+ reg_tpc_info->num_pwr_levels = num_pwr_levels; -+ reg_tpc_info->is_psd_power = is_psd_power; -+ reg_tpc_info->eirp_power = eirp_power; -+ reg_tpc_info->power_type_6g = -+ ath11k_ieee80211_ap_pwr_type_convert(vif->bss_conf.power_type); -+} -+ -+static void ath11k_mac_parse_tx_pwr_env(struct ath11k *ar, -+ struct ieee80211_vif *vif, -+ struct ieee80211_chanctx_conf *ctx) -+{ -+ struct ath11k_base *ab = ar->ab; -+ struct ath11k_vif *arvif = (void *)vif->drv_priv; -+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; -+ struct ieee80211_tx_pwr_env *single_tpe; -+ enum wmi_reg_6ghz_client_type client_type; -+ struct cur_regulatory_info *reg_info; -+ int i; -+ u8 pwr_count, pwr_interpret, pwr_category; -+ u8 psd_index = 0, non_psd_index = 0, local_tpe_count = 0, reg_tpe_count = 0; -+ bool use_local_tpe, non_psd_set = false, psd_set = false; -+ -+ reg_info = &ab->reg_info_store[ar->pdev_idx]; -+ client_type = reg_info->client_type; -+ -+ for (i = 0; i < bss_conf->tx_pwr_env_num; i++) { -+ single_tpe = &bss_conf->tx_pwr_env[i]; -+ pwr_category = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_CATEGORY); -+ pwr_interpret = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_INTERPRET); -+ -+ if (pwr_category == client_type) { -+ if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP || -+ pwr_interpret == IEEE80211_TPE_LOCAL_EIRP_PSD) -+ local_tpe_count++; -+ else if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP || -+ pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP_PSD) -+ reg_tpe_count++; -+ } -+ } -+ -+ if (!reg_tpe_count && !local_tpe_count) { -+ ath11k_warn(ab, -+ "no transmit power envelope match client power type %d\n", -+ client_type); -+ return; -+ } else if (!reg_tpe_count) { -+ use_local_tpe = true; -+ } else { -+ use_local_tpe = false; -+ } -+ -+ for (i = 0; i < bss_conf->tx_pwr_env_num; i++) { -+ single_tpe = &bss_conf->tx_pwr_env[i]; -+ pwr_category = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_CATEGORY); -+ pwr_interpret = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_INTERPRET); -+ -+ if (pwr_category != client_type) -+ continue; -+ -+ /* get local transmit power envelope */ -+ if (use_local_tpe) { -+ if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP) { -+ non_psd_index = i; -+ non_psd_set = true; -+ } else if (pwr_interpret == IEEE80211_TPE_LOCAL_EIRP_PSD) { -+ psd_index = i; -+ psd_set = true; -+ } -+ /* get regulatory transmit power envelope */ -+ } else { -+ if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP) { -+ non_psd_index = i; -+ non_psd_set = true; -+ } else if (pwr_interpret == IEEE80211_TPE_REG_CLIENT_EIRP_PSD) { -+ psd_index = i; -+ psd_set = true; -+ } -+ } -+ } -+ -+ if (non_psd_set && !psd_set) { -+ single_tpe = &bss_conf->tx_pwr_env[non_psd_index]; -+ pwr_count = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_COUNT); -+ pwr_interpret = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_INTERPRET); -+ arvif->reg_tpc_info.is_psd_power = false; -+ arvif->reg_tpc_info.eirp_power = 0; -+ -+ arvif->reg_tpc_info.num_pwr_levels = -+ ath11k_mac_get_tpe_count(pwr_interpret, pwr_count); -+ for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) { -+ ath11k_dbg(ab, ATH11K_DBG_MAC, -+ "non PSD power[%d] : %d\n", -+ i, single_tpe->tx_power[i]); -+ arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[i] / 2; -+ } -+ } -+ -+ if (psd_set) { -+ single_tpe = &bss_conf->tx_pwr_env[psd_index]; -+ pwr_count = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_COUNT); -+ pwr_interpret = u8_get_bits(single_tpe->tx_power_info, -+ IEEE80211_TX_PWR_ENV_INFO_INTERPRET); -+ arvif->reg_tpc_info.is_psd_power = true; -+ -+ if (pwr_count == 0) { -+ ath11k_dbg(ab, ATH11K_DBG_MAC, -+ "TPE PSD power : %d\n", single_tpe->tx_power[0]); -+ arvif->reg_tpc_info.num_pwr_levels = -+ ath11k_mac_get_num_pwr_levels(&ctx->def); -+ for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) -+ arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[0] / 2; -+ } else { -+ arvif->reg_tpc_info.num_pwr_levels = -+ ath11k_mac_get_tpe_count(pwr_interpret, pwr_count); -+ for (i = 0; i < arvif->reg_tpc_info.num_pwr_levels; i++) { -+ ath11k_dbg(ab, ATH11K_DBG_MAC, -+ "TPE PSD power[%d] : %d\n", -+ i, single_tpe->tx_power[i]); -+ arvif->reg_tpc_info.tpe[i] = single_tpe->tx_power[i] / 2; -+ } -+ } -+ } -+} -+ - static int - ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, -@@ -7599,6 +8123,8 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, - struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif); - int ret; - struct peer_create_params param; -+ struct cur_regulatory_info *reg_info; -+ enum ieee80211_ap_reg_power power_type; - - mutex_lock(&ar->conf_mutex); - -@@ -7606,6 +8132,20 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, - "chanctx assign ptr %p vdev_id %i\n", - ctx, arvif->vdev_id); - -+ if (ath11k_hw_supports_6g_cc_ext(ar) && -+ ctx->def.chan->band == NL80211_BAND_6GHZ && -+ arvif->vdev_type == WMI_VDEV_TYPE_STA) { -+ reg_info = &ab->reg_info_store[ar->pdev_idx]; -+ power_type = vif->bss_conf.power_type; -+ ath11k_dbg(ab, ATH11K_DBG_MAC, "mac chanctx power type %d\n", -+ power_type); -+ if (power_type == IEEE80211_REG_UNSET_AP) -+ power_type = IEEE80211_REG_LPI_AP; -+ ath11k_reg_handle_chan_list(ab, reg_info, power_type); -+ arvif->chanctx = *ctx; -+ ath11k_mac_parse_tx_pwr_env(ar, vif, ctx); -+ } -+ - /* for QCA6390 bss peer must be created before vdev_start */ - if (ab->hw_params.vdev_start_delay && - arvif->vdev_type != WMI_VDEV_TYPE_AP && -@@ -9276,6 +9816,31 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, +@@ -8774,6 +8774,31 @@ static int ath11k_mac_setup_channels_rates(struct ath11k *ar, return 0; } @@ -1523,7 +274,7 @@ index b328a0599..8a034a971 100644 static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) { struct ath11k_base *ab = ar->ab; -@@ -9295,28 +9860,43 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) +@@ -8793,28 +8818,43 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) return -ENOMEM; } @@ -1587,15 +338,7 @@ index b328a0599..8a034a971 100644 ar->hw->wiphy->iface_combinations = combinations; ar->hw->wiphy->n_iface_combinations = 1; -@@ -9367,6 +9947,7 @@ static const struct wiphy_iftype_ext_capab ath11k_iftypes_ext_capa[] = { - - static void __ath11k_mac_unregister(struct ath11k *ar) - { -+ cancel_work_sync(&ar->channel_update_work); - cancel_work_sync(&ar->regd_update_work); - - ieee80211_unregister_hw(ar->hw); -@@ -9381,6 +9962,8 @@ static void __ath11k_mac_unregister(struct ath11k *ar) +@@ -8875,6 +8915,8 @@ static void __ath11k_mac_unregister(struct ath11k *ar) kfree(ar->hw->wiphy->iface_combinations[0].limits); kfree(ar->hw->wiphy->iface_combinations); @@ -1604,7 +347,7 @@ index b328a0599..8a034a971 100644 SET_IEEE80211_DEV(ar->hw, NULL); } -@@ -9423,6 +10006,7 @@ static int __ath11k_mac_register(struct ath11k *ar) +@@ -8917,6 +8959,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ath11k_pdev_caps_update(ar); SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr); @@ -1612,1607 +355,130 @@ index b328a0599..8a034a971 100644 SET_IEEE80211_DEV(ar->hw, ab->dev); -@@ -9565,6 +10149,8 @@ static int __ath11k_mac_register(struct ath11k *ar) - ar->hw->wiphy->iftype_ext_capab = ath11k_iftypes_ext_capa; - ar->hw->wiphy->num_iftype_ext_capab = - ARRAY_SIZE(ath11k_iftypes_ext_capa); -+ ar->hw->wiphy->vendor_commands = ath11k_vendor_cmds; -+ ar->hw->wiphy->n_vendor_commands = ARRAY_SIZE(ath11k_vendor_cmds); - - if (ar->supports_6ghz) { - wiphy_ext_feature_set(ar->hw->wiphy, -@@ -9766,6 +10352,9 @@ int ath11k_mac_allocate(struct ath11k_base *ab) - - INIT_DELAYED_WORK(&ar->scan.timeout, ath11k_scan_timeout_work); - INIT_WORK(&ar->regd_update_work, ath11k_regd_update_work); -+ INIT_WORK(&ar->channel_update_work, ath11k_regd_update_chan_list_work); -+ INIT_LIST_HEAD(&ar->channel_update_queue); -+ spin_lock_init(&ar->channel_update_lock); - - INIT_WORK(&ar->wmi_mgmt_tx_work, ath11k_mgmt_over_wmi_tx_work); - skb_queue_head_init(&ar->wmi_mgmt_tx_queue); -@@ -9836,3 +10425,27 @@ int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif, +-- +GitLab - return 0; - } -+ -+static int ath11k_mac_vif_send_coex_config(struct ath11k_vif *arvif, -+ struct wmi_coex_config_params *param) -+{ -+ return ath11k_wmi_send_coex_config(arvif->ar, param); -+} -+ -+int ath11k_mac_send_coex_config(struct ath11k *ar, -+ struct wmi_coex_config_params *param) -+{ -+ struct ath11k_vif *arvif; -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ param->vdev_id = arvif->vdev_id; -+ ret = ath11k_mac_vif_send_coex_config(arvif, param); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/ath/ath11k/mac.h b/drivers/net/wireless/ath/ath11k/mac.h -index 0231783ad..205140e31 100644 ---- a/drivers/net/wireless/ath/ath11k/mac.h -+++ b/drivers/net/wireless/ath/ath11k/mac.h -@@ -158,7 +158,7 @@ struct ath11k_vif *ath11k_mac_get_vif_up(struct ath11k_base *ab); +From 6591470d389d674f100568393112c169841db26f Mon Sep 17 00:00:00 2001 +From: "neil.shi" <neil.shi@quectel.com> +Date: Tue, 23 May 2023 17:07:21 +0800 +Subject: [PATCH] wifi: ath11k: [DBS PATCH 6/6]: send coex config to firmware + for QCA206X - struct ath11k *ath11k_mac_get_ar_by_vdev_id(struct ath11k_base *ab, u32 vdev_id); - struct ath11k *ath11k_mac_get_ar_by_pdev_id(struct ath11k_base *ab, u32 pdev_id); -- -+enum wmi_vdev_type ath11k_mac_get_ar_vdev_type(struct ath11k *ar); - void ath11k_mac_drain_tx(struct ath11k *ar); - void ath11k_mac_peer_cleanup_all(struct ath11k *ar); - int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx); -@@ -175,4 +175,9 @@ int ath11k_mac_wait_tx_complete(struct ath11k *ar); - int ath11k_mac_vif_set_keepalive(struct ath11k_vif *arvif, - enum wmi_sta_keepalive_method method, - u32 interval); -+int ath11k_mac_send_coex_config(struct ath11k *ar, -+ struct wmi_coex_config_params *param); -+void ath11k_mac_fill_reg_tpc_info(struct ath11k *ar, -+ struct ieee80211_vif *vif, -+ struct ieee80211_chanctx_conf *ctx); - #endif -diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c -index 3ac689f1d..24578bd5e 100644 ---- a/drivers/net/wireless/ath/ath11k/mhi.c -+++ b/drivers/net/wireless/ath/ath11k/mhi.c -@@ -414,7 +414,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - goto free_controller; - } else { - mhi_ctrl->iova_start = 0; -- mhi_ctrl->iova_stop = 0xFFFFFFFF; -+ mhi_ctrl->iova_stop = 0xFFFFFFFFF; - } +Signed-off-by: neil.shi <neil.shi@quectel.com> +--- + drivers/net/wireless/ath/ath11k/core.c | 27 +++++++++ + drivers/net/wireless/ath/ath11k/hw.h | 1 + + drivers/net/wireless/ath/ath11k/wmi.c | 26 +++++++++ + drivers/net/wireless/ath/ath11k/wmi.h | 77 ++++++++++++++++++++++++++ + 4 files changed, 131 insertions(+) - mhi_ctrl->rddm_size = RDDM_DUMP_SIZE; -@@ -434,6 +434,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci) - case ATH11K_HW_QCA6390_HW20: - case ATH11K_HW_WCN6855_HW20: - case ATH11K_HW_WCN6855_HW21: -+ case ATH11K_HW_QCA206X_HW21: - ath11k_mhi_config = &ath11k_mhi_config_qca6390; - break; - default: -@@ -525,3 +526,18 @@ int ath11k_mhi_resume(struct ath11k_pci *ab_pci) +diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c +index 96ed5b7cd0048..849c7c12198e0 100644 +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -16,6 +16,7 @@ + #include "debug.h" + #include "hif.h" + #include "wow.h" ++#include "wmi.h" - return 0; + unsigned int ath11k_debug_mask; + EXPORT_SYMBOL(ath11k_debug_mask); +@@ -115,6 +116,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .tcl_ring_retry = true, + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, ++ .coex_isolation = false, + }, + { + .hw_rev = ATH11K_HW_IPQ6018_HW10, +@@ -204,6 +206,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = false, ++ .coex_isolation = false, + }, + { + .name = "qca6390 hw2.0", +@@ -371,6 +374,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = false, ++ .coex_isolation = false, + }, + { + .name = "wcn6855 hw2.0", +@@ -418,6 +422,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .fw_wmi_diag_event = true, + .current_cc_support = true, + .dbr_debug_support = false, ++ .coex_isolation = false, + }, + { + .name = "qca206x hw2.1", +@@ -456,6 +525,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .tx_ring_size = DP_TCL_DATA_RING_SIZE, + .smp2p_wow_exit = false, + .support_fw_mac_sequence = true, ++ .coex_isolation = false, + }, + { + .name = "wcn6855 hw2.1", +@@ -1448,6 +1454,18 @@ static void ath11k_core_pdev_destroy(struct ath11k_base *ab) + ath11k_debugfs_pdev_destroy(ab); } -+ -+ -+int ath11k_mhi_force_rddm(struct ath11k_pci *ab_pci) -+{ -+ struct ath11k_base *ab = ab_pci->ab; -+ int ret; -+ -+ ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl); -+ if (ret) { -+ ath11k_warn(ab, "failed to resume mhi: %d", ret); -+ return ret; -+ } -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/ath/ath11k/mhi.h b/drivers/net/wireless/ath/ath11k/mhi.h -index 8d9f852da..215428b87 100644 ---- a/drivers/net/wireless/ath/ath11k/mhi.h -+++ b/drivers/net/wireless/ath/ath11k/mhi.h -@@ -25,5 +25,6 @@ void ath11k_mhi_clear_vector(struct ath11k_base *ab); - - int ath11k_mhi_suspend(struct ath11k_pci *ar_pci); - int ath11k_mhi_resume(struct ath11k_pci *ar_pci); -+int ath11k_mhi_force_rddm(struct ath11k_pci *ab_pci); - #endif -diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c -index 09e65c5e5..59de93c0b 100644 ---- a/drivers/net/wireless/ath/ath11k/pci.c -+++ b/drivers/net/wireless/ath/ath11k/pci.c -@@ -18,7 +18,7 @@ - #include "qmi.h" - - #define ATH11K_PCI_BAR_NUM 0 --#define ATH11K_PCI_DMA_MASK 32 -+#define ATH11K_PCI_DMA_MASK 36 - - #define TCSR_SOC_HW_VERSION 0x0224 - #define TCSR_SOC_HW_VERSION_MAJOR_MASK GENMASK(11, 8) -@@ -28,6 +28,8 @@ - #define QCN9074_DEVICE_ID 0x1104 - #define WCN6855_DEVICE_ID 0x1103 - -+#define SUB_VERSION 0x1910010 -+ - static const struct pci_device_id ath11k_pci_id_table[] = { - { PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) }, - { PCI_VDEVICE(QCOM, WCN6855_DEVICE_ID) }, -@@ -37,6 +39,124 @@ static const struct pci_device_id ath11k_pci_id_table[] = { - - MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table); - -+static struct cnss_pci_reg register_rddm_fail_debug[] = { -+ {"PCIE_BHI_VERSION_LOWER", HWIO_PCIE_PCIE_BHI_VERSION_LOWER_ADDR, 0}, -+ {"PCIE_BHI_VERSION_UPPER", HWIO_PCIE_PCIE_BHI_VERSION_UPPER_ADDR, 0}, -+ {"PCIE_BHI_IMGADDR_LOWER", HWIO_PCIE_PCIE_BHI_IMGADDR_LOWER_ADDR, 0}, -+ {"PCIE_BHI_IMGADDR_UPPER", HWIO_PCIE_PCIE_BHI_IMGADDR_UPPER_ADDR, 0}, -+ {"PCIE_BHI_IMGSIZE", HWIO_PCIE_PCIE_BHI_IMGSIZE_ADDR, 0}, -+ {"PCIE_BHI_IMGTXDB", HWIO_PCIE_PCIE_BHI_IMGTXDB_ADDR, 0}, -+ {"PCIE_BHI_INTVEC", HWIO_PCIE_PCIE_BHI_INTVEC_ADDR, 0}, -+ {"PCIE_BHI_EXECENV", HWIO_PCIE_PCIE_BHI_EXECENV_ADDR, 0}, -+ {"PCIE_BHI_STATUS", HWIO_PCIE_PCIE_BHI_STATUS_ADDR, 0}, -+ {"PCIE_BHI_ERRCODE", HWIO_PCIE_PCIE_BHI_ERRCODE_ADDR, 0}, -+ {"PCIE_BHI_ERRDBG1", HWIO_PCIE_PCIE_BHI_ERRDBG1_ADDR, 0}, -+ {"PCIE_BHI_ERRDBG2", HWIO_PCIE_PCIE_BHI_ERRDBG2_ADDR, 0}, -+ {"PCIE_BHI_ERRDBG3", HWIO_PCIE_PCIE_BHI_ERRDBG3_ADDR, 0}, -+ {"PCIE_BHI_SERIALNUM", HWIO_PCIE_PCIE_BHI_SERIALNUM_ADDR, 0}, -+ {"PCIE_BHI_SBLANTIROLLVER", HWIO_PCIE_PCIE_BHI_SBLANTIROLLVER_ADDR, 0}, -+ {"PCIE_BHI_NUMSEG", HWIO_PCIE_PCIE_BHI_NUMSEG_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_0", HWIO_PCIE_PCIE_BHI_MSMHWID_0_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_1", HWIO_PCIE_PCIE_BHI_MSMHWID_1_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_2", HWIO_PCIE_PCIE_BHI_MSMHWID_2_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_3", HWIO_PCIE_PCIE_BHI_MSMHWID_3_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_4", HWIO_PCIE_PCIE_BHI_MSMHWID_4_ADDR, 0}, -+ {"PCIE_BHI_MSMHWID_5", HWIO_PCIE_PCIE_BHI_MSMHWID_5_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_0", HWIO_PCIE_PCIE_BHI_OEMPKHASH_0_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_1", HWIO_PCIE_PCIE_BHI_OEMPKHASH_1_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_2", HWIO_PCIE_PCIE_BHI_OEMPKHASH_2_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_3", HWIO_PCIE_PCIE_BHI_OEMPKHASH_3_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_4", HWIO_PCIE_PCIE_BHI_OEMPKHASH_4_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_5", HWIO_PCIE_PCIE_BHI_OEMPKHASH_5_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_6", HWIO_PCIE_PCIE_BHI_OEMPKHASH_6_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_7", HWIO_PCIE_PCIE_BHI_OEMPKHASH_7_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_8", HWIO_PCIE_PCIE_BHI_OEMPKHASH_8_ADDR, 0}, -+ {"PCIE_BHI_OEMPKHASH_9", HWIO_PCIE_PCIE_BHI_OEMPKHASH_9_ADDR, 0}, -+ {"PCIE_BHI_TXVECDB", HWIO_PCIE_PCIE_BHI_TXVECDB_ADDR, 0}, -+ {"PCIE_BHI_TXVECSTATUS", HWIO_PCIE_PCIE_BHI_TXVECSTATUS_ADDR, 0}, -+ {"PCIE_BHI_RXVECDB", HWIO_PCIE_PCIE_BHI_RXVECDB_ADDR, 0}, -+ {"PCIE_BHI_RXVECSTATUS", HWIO_PCIE_PCIE_BHI_RXVECSTATUS_ADDR, 0}, -+ /* After dump this register, recovery will fail for QCA6490 */ -+ //{"PCIE_WLAON_RESET_DBG_SW_ENTRY", WLAON_RESET_DBG_SW_ENTRY, 0}, -+ {NULL}, -+}; -+ -+static struct cnss_pci_reg register_to_dump[] = { -+ {"QDSS_APB_DEC_CS_QDSSCSR_ETRIRQCTRL", QDSS_APB_DEC_CS_QDSSCSR_ETRIRQCTRL, 0}, -+ {"QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETF", QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETF, 0}, -+ {"QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR0", QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR0, 0}, -+ {"QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR1", QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR1, 0}, -+ {"Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_0", Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_0, 0}, -+ {"Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_1", Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_1, 0}, -+ {"Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_2", Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_2, 0}, -+ {NULL}, -+}; -+ -+#define LINE_LEN_MAX 80 -+ -+static int ath11k_register_dump(struct ath11k_base *ab, -+ u8 **buf, -+ size_t *buf_len, -+ struct cnss_pci_reg *regs, -+ size_t num) -+{ -+ u32 i; -+ u32 offset = 0; -+ size_t line_len; -+ ssize_t len; -+ char (*line_ptr)[LINE_LEN_MAX]; -+ -+ *buf_len = 0; -+ -+ line_ptr = (char (*)[LINE_LEN_MAX])vzalloc(num * LINE_LEN_MAX); -+ if (!line_ptr) -+ return -ENOMEM; -+ -+ for (i = 0; regs[i].name; i++) { -+ regs[i].value = ath11k_pcic_read32(ab, regs[i].offset); -+ ath11k_info(ab, "%s[0x%x] = 0x%x\n", -+ regs[i].name, regs[i].offset, regs[i].value); -+ len = snprintf(line_ptr[i], LINE_LEN_MAX, "%s[0x%x] = 0x%x\n", -+ regs[i].name, regs[i].offset, regs[i].value); -+ *buf_len += len; -+ } -+ -+ ath11k_info(ab, "%s buf len=%lu\n", __func__, *buf_len); -+ *buf = vzalloc(*buf_len); -+ if (!*buf) -+ return -ENOMEM; -+ -+ for (i = 0; i < num; ++i) { -+ line_len = strlen(line_ptr[i]); -+ memcpy(*buf + offset, line_ptr[i], line_len); -+ offset += line_len; -+ } -+ -+ vfree(line_ptr); -+ -+ return 0; -+} -+ -+void ath11k_pci_register_dump(struct ath11k_pci *ab_pci) ++static int ath11k_core_config_coex_isolation(struct ath11k_base *ab) +{ -+ size_t num; -+ struct register_crash_data *crash_data = &ab_pci->reg_data; ++ struct ath11k *ar = ath11k_ab_to_ar(ab, 0); ++ struct wmi_coex_config_params param; + -+ num = sizeof(register_to_dump) / sizeof(struct cnss_pci_reg) - 1; -+ ath11k_register_dump(ab_pci->ab, -+ &crash_data->reg_buf, -+ &crash_data->reg_buf_len, -+ register_to_dump, -+ num); ++ memset(¶m, 0, sizeof(struct wmi_coex_config_params)); ++ param.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION; ++ param.config_arg1 = WMI_COEX_ISOLATION_ARG1_DEFAUT; + -+ num = sizeof(register_rddm_fail_debug) / sizeof(struct cnss_pci_reg) - 1; -+ ath11k_register_dump(ab_pci->ab, -+ &crash_data->reg_rddm_buf, -+ &crash_data->reg_rddm_buf_len, -+ register_rddm_fail_debug, -+ num); ++ return ath11k_wmi_send_coex_config(ar, ¶m); +} + - static int ath11k_pci_bus_wake_up(struct ath11k_base *ab) - { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); -@@ -108,7 +228,12 @@ static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset) - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - u32 window_start, val; - -- window_start = ath11k_pci_get_window_start(ab, offset); -+ if (ab->hw_params.static_window_map) -+ window_start = ath11k_pci_get_window_start(ab, offset); -+ else -+ window_start = ATH11K_PCI_WINDOW_START; -+ -+ //window_start = ath11k_pci_get_window_start(ab, offset); - - if (window_start == ATH11K_PCI_WINDOW_START) { - spin_lock_bh(&ab_pci->window_lock); -@@ -669,19 +794,21 @@ static int ath11k_pci_start(struct ath11k_base *ab) + static int ath11k_core_start(struct ath11k_base *ab) { - struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); - -- /* TODO: for now don't restore ASPM in case of single MSI -- * vector as MHI register reading in M2 causes system hang. -- */ -- if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) -- ath11k_pci_aspm_restore(ab_pci); -- else -- ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); -+ ath11k_pci_aspm_restore(ab_pci); - - ath11k_pcic_start(ab); - - return 0; - } - -+static int ath11k_pci_force_rddm(struct ath11k_base *ab) -+{ -+ struct ath11k_pci *ar_pci; -+ -+ ar_pci = ath11k_pci_priv(ab); -+ return ath11k_mhi_force_rddm(ar_pci); -+} -+ - static const struct ath11k_hif_ops ath11k_pci_hif_ops = { - .start = ath11k_pci_start, - .stop = ath11k_pcic_stop, -@@ -700,6 +827,7 @@ static const struct ath11k_hif_ops ath11k_pci_hif_ops = { - .ce_irq_enable = ath11k_pci_hif_ce_irq_enable, - .ce_irq_disable = ath11k_pci_hif_ce_irq_disable, - .get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx, -+ .target_crash = ath11k_pci_force_rddm, - }; - - static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor) -@@ -733,6 +861,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, - u32 soc_hw_version_major, soc_hw_version_minor, addr; - const struct ath11k_pci_ops *pci_ops; int ret; -+ u32 sub_version; -+ int ops_init = 0; - - ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); - -@@ -800,6 +930,13 @@ static int ath11k_pci_probe(struct pci_dev *pdev, - ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; - ath11k_pci_read_hw_version(ab, &soc_hw_version_major, - &soc_hw_version_minor); -+ pci_ops = &ath11k_pci_ops_qca6390; -+ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); -+ if (ret) { -+ ath11k_err(ab, "failed to register PCI ops: %d\n", ret); -+ goto err_pci_free_region; -+ } -+ ops_init = 1; - switch (soc_hw_version_major) { - case 2: - switch (soc_hw_version_minor) { -@@ -809,7 +946,19 @@ static int ath11k_pci_probe(struct pci_dev *pdev, - break; - case 0x10: - case 0x11: -- ab->hw_rev = ATH11K_HW_WCN6855_HW21; -+ //ab->hw_rev = ATH11K_HW_WCN6855_HW21; -+ sub_version = ath11k_pcic_read32(ab, SUB_VERSION); -+ ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n", sub_version); -+ switch (sub_version) { -+ case 0x1019A0E1: -+ case 0x1019B0E1: -+ case 0x1019C0E1: -+ case 0x1019D0E1: -+ ab->hw_rev = ATH11K_HW_QCA206X_HW21; -+ break; -+ default: -+ ab->hw_rev = ATH11K_HW_WCN6855_HW21; -+ } - break; - default: - goto unsupported_wcn6855_soc; -@@ -823,7 +972,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev, - goto err_pci_free_region; - } - -- pci_ops = &ath11k_pci_ops_qca6390; - break; - default: - dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", -@@ -832,10 +980,12 @@ static int ath11k_pci_probe(struct pci_dev *pdev, - goto err_pci_free_region; +@@ -1545,6 +1563,15 @@ static int ath11k_core_start(struct ath11k_base *ab) + goto err_reo_cleanup; } -- ret = ath11k_pcic_register_pci_ops(ab, pci_ops); -- if (ret) { -- ath11k_err(ab, "failed to register PCI ops: %d\n", ret); -- goto err_pci_free_region; -+ if(ops_init == 1){ -+ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); ++ if (ab->hw_params.coex_isolation) { ++ ret = ath11k_core_config_coex_isolation(ab); + if (ret) { -+ ath11k_err(ab, "failed to register PCI ops: %d\n", ret); -+ goto err_pci_free_region; -+ } - } - - ret = ath11k_pcic_init_msi_config(ab); -@@ -1021,6 +1171,7 @@ static struct pci_driver ath11k_pci_driver = { - static int ath11k_pci_init(void) - { - int ret; -+ u32 sub_version; - - ret = pci_register_driver(&ath11k_pci_driver); - if (ret) -diff --git a/drivers/net/wireless/ath/ath11k/pci.h b/drivers/net/wireless/ath/ath11k/pci.h -index e9a01f344..2b13b2900 100644 ---- a/drivers/net/wireless/ath/ath11k/pci.h -+++ b/drivers/net/wireless/ath/ath11k/pci.h -@@ -14,6 +14,7 @@ - #define PCIE_SOC_GLOBAL_RESET_V 1 - - #define WLAON_WARM_SW_ENTRY 0x1f80504 -+#define WLAON_RESET_DBG_SW_ENTRY 0x01F80508 - #define WLAON_SOC_RESET_CAUSE_REG 0x01f8060c - - #define PCIE_Q6_COOKIE_ADDR 0x01f80500 -@@ -53,6 +54,65 @@ - #define WLAON_QFPROM_PWR_CTRL_REG 0x01f8031c - #define QFPROM_PWR_CTRL_VDD4BLOW_MASK 0x4 - -+#define HWIO_PCIE_PCIE_BHI_VERSION_LOWER_ADDR (0x1e0e200) -+#define HWIO_PCIE_PCIE_BHI_VERSION_UPPER_ADDR (0x1e0e204) -+#define HWIO_PCIE_PCIE_BHI_IMGADDR_LOWER_ADDR (0x1e0e208) -+#define HWIO_PCIE_PCIE_BHI_IMGADDR_UPPER_ADDR (0x1e0e20c) -+#define HWIO_PCIE_PCIE_BHI_IMGSIZE_ADDR (0x1e0e210) -+#define HWIO_PCIE_PCIE_BHI_IMGTXDB_ADDR (0x1e0e218) -+#define HWIO_PCIE_PCIE_BHI_INTVEC_ADDR (0x1e0e220) -+#define HWIO_PCIE_PCIE_BHI_EXECENV_ADDR (0x1e0e228) -+#define HWIO_PCIE_PCIE_BHI_STATUS_ADDR (0x1e0e22c) -+#define HWIO_PCIE_PCIE_BHI_ERRCODE_ADDR (0x1e0e230) -+#define HWIO_PCIE_PCIE_BHI_ERRDBG1_ADDR (0x1e0e234) -+#define HWIO_PCIE_PCIE_BHI_ERRDBG2_ADDR (0x1e0e238) -+#define HWIO_PCIE_PCIE_BHI_ERRDBG3_ADDR (0x1e0e23c) -+#define HWIO_PCIE_PCIE_BHI_SERIALNUM_ADDR (0x1e0e240) -+#define HWIO_PCIE_PCIE_BHI_SBLANTIROLLVER_ADDR (0x1e0e244) -+#define HWIO_PCIE_PCIE_BHI_NUMSEG_ADDR (0x1e0e248) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_0_ADDR (0x1e0e24c) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_1_ADDR (0x1e0e250) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_2_ADDR (0x1e0e254) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_3_ADDR (0x1e0e258) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_4_ADDR (0x1e0e25c) -+#define HWIO_PCIE_PCIE_BHI_MSMHWID_5_ADDR (0x1e0e260) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_0_ADDR (0x1e0e264) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_1_ADDR (0x1e0e268) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_2_ADDR (0x1e0e26c) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_3_ADDR (0x1e0e270) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_4_ADDR (0x1e0e274) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_5_ADDR (0x1e0e278) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_6_ADDR (0x1e0e27c) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_7_ADDR (0x1e0e280) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_8_ADDR (0x1e0e284) -+#define HWIO_PCIE_PCIE_BHI_OEMPKHASH_9_ADDR (0x1e0e288) -+#define HWIO_PCIE_PCIE_BHI_TXVECDB_ADDR (0x1e0e360) -+#define HWIO_PCIE_PCIE_BHI_TXVECSTATUS_ADDR (0x1e0e368) -+#define HWIO_PCIE_PCIE_BHI_RXVECDB_ADDR (0x1e0e394) -+#define HWIO_PCIE_PCIE_BHI_RXVECSTATUS_ADDR (0x1e0e39c) -+ -+#define QDSS_APB_DEC_CS_QDSSCSR_ETRIRQCTRL (0x1C0106C) -+#define QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETF (0x1C01070) -+#define QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR0 (0x1C01074) -+#define QDSS_APB_DEC_CS_QDSSCSR_PRESERVEETR1 (0x1C01078) -+#define Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_0 (0x00DA102C) -+#define Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_1 (0x00DA202C) -+#define Q6SS_PRIVCSR_QDSP6SS_QTMR_V1_CNTP_CTL_2 (0x00DA302C) -+ -+struct cnss_pci_reg { -+ char *name; -+ u32 offset; -+ u32 value; -+}; -+ -+struct register_crash_data { -+ u8 *reg_buf; -+ size_t reg_buf_len; -+ u8 *reg_rddm_buf; -+ size_t reg_rddm_buf_len; -+}; -+ -+ - enum ath11k_pci_flags { - ATH11K_PCI_ASPM_RESTORE, - }; -@@ -72,6 +132,8 @@ struct ath11k_pci { - /* enum ath11k_pci_flags */ - unsigned long flags; - u16 link_ctl; -+ struct register_crash_data reg_data; -+ - }; - - static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) -@@ -80,4 +142,5 @@ static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) - } - - int ath11k_pci_get_msi_irq(struct ath11k_base *ab, unsigned int vector); -+void ath11k_pci_register_dump(struct ath11k_pci *ab_pci); - #endif -diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c -index c63083633..2f95d5b68 100644 ---- a/drivers/net/wireless/ath/ath11k/pcic.c -+++ b/drivers/net/wireless/ath/ath11k/pcic.c -@@ -115,6 +115,17 @@ static const struct ath11k_msi_config ath11k_msi_config[] = { - }, - .hw_rev = ATH11K_HW_WCN6750_HW10, - }, -+ { -+ .total_vectors = 32, -+ .total_users = 4, -+ .users = (struct ath11k_msi_user[]) { -+ { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, -+ { .name = "CE", .num_vectors = 10, .base_vector = 3 }, -+ { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, -+ { .name = "DP", .num_vectors = 18, .base_vector = 14 }, -+ }, -+ .hw_rev = ATH11K_HW_QCA206X_HW21, -+ }, - }; - - int ath11k_pcic_init_msi_config(struct ath11k_base *ab) -@@ -460,8 +471,6 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) - { - int i; - -- set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); -- - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - -@@ -471,6 +480,8 @@ void ath11k_pcic_ext_irq_enable(struct ath11k_base *ab) - } - ath11k_pcic_ext_grp_enable(irq_grp); - } -+ -+ set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); - } - EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable); - -@@ -598,7 +609,10 @@ static int ath11k_pcic_ext_irq_config(struct ath11k_base *ab) - ath11k_dbg(ab, ATH11K_DBG_PCI, - "irq %d group %d\n", irq, i); - -- irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); -+ if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) -+ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY | IRQ_MOVE_PCNTXT); -+ else -+ irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); - ret = request_irq(irq, ath11k_pcic_ext_interrupt_handler, - irq_flags, "DP_EXT_IRQ", irq_grp); - if (ret) { -@@ -648,6 +662,8 @@ int ath11k_pcic_config_irq(struct ath11k_base *ab) - - tasklet_setup(&ce_pipe->intr_tq, ath11k_pcic_ce_tasklet); - -+ if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) -+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT); - ret = request_irq(irq, ath11k_pcic_ce_interrupt_handler, - irq_flags, irq_name[irq_idx], ce_pipe); - if (ret) { -diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c -index 41fad03a3..a5f582638 100644 ---- a/drivers/net/wireless/ath/ath11k/qmi.c -+++ b/drivers/net/wireless/ath/ath11k/qmi.c -@@ -1971,6 +1971,51 @@ static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab) - } - } - -+static size_t ath11k_qmi_get_remote_buf_len(struct fw_remote_mem *fw_mem) -+{ -+ unsigned int i; -+ size_t len = 0; -+ -+ for (i = 0; i < ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01; i++) { -+ if (fw_mem[i].vaddr && fw_mem[i].size) -+ len += fw_mem[i].size; -+ } -+ return len; -+} -+ -+int ath11k_qmi_remote_dump(struct ath11k_base *ab) -+{ -+ struct fw_remote_crash_data *crash_data = &ab->remote_crash_data; -+ struct fw_remote_mem *fw_mem = ab->remote_mem; -+ u8 i; -+ u32 offset = 0; -+ -+ crash_data->remote_buf_len = ath11k_qmi_get_remote_buf_len(fw_mem); -+ ath11k_info(ab, "%s remote buffer len=%lu\n", __func__, crash_data->remote_buf_len); -+ crash_data->remote_buf = vzalloc(crash_data->remote_buf_len); -+ if (!crash_data->remote_buf) -+ return -ENOMEM; -+ -+ for (i = 0; i < ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01; i++) { -+ if (fw_mem[i].vaddr && fw_mem[i].size) { -+ ath11k_info(ab, "remote mem: 0x%p, size: 0x%lx\n", fw_mem[i].vaddr, -+ fw_mem[i].size); -+ memcpy(crash_data->remote_buf + offset, fw_mem[i].vaddr, fw_mem[i].size); -+ offset += fw_mem[i].size; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(ath11k_qmi_remote_dump); -+ -+static void ath11k_qmi_set_remote_mem(struct fw_remote_mem *fw_mem, -+ void *vaddr, size_t size, -+ uint32_t segnum) -+{ -+ fw_mem[segnum].vaddr = vaddr; -+ fw_mem[segnum].size = size; -+} -+ - static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) - { - int i; -@@ -1995,10 +2040,10 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) - chunk->vaddr = NULL; - } - -- chunk->vaddr = dma_alloc_coherent(ab->dev, -+ chunk->vaddr = ath11k_core_dma_alloc_coherent(ab->dev, - chunk->size, - &chunk->paddr, -- GFP_KERNEL | __GFP_NOWARN); -+ GFP_KERNEL | __GFP_NOWARN | GFP_DMA32); - if (!chunk->vaddr) { - if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) { - ath11k_dbg(ab, ATH11K_DBG_QMI, -@@ -2015,6 +2060,15 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) - chunk->type); - return -EINVAL; - } -+ -+ if (chunk->type == QMI_WLANFW_MEM_TYPE_DDR_V01) { -+ ath11k_qmi_set_remote_mem(ab->remote_mem, -+ chunk->vaddr, -+ chunk->size, -+ i); -+ ath11k_info(ab, "vaddr=0x%p size=0x%x\n", chunk->vaddr, chunk->size); ++ ath11k_err(ab, "failed to set coex isolation: %d\n", ++ ret); ++ goto err_reo_cleanup; + } -+ - chunk->prev_type = chunk->type; - chunk->prev_size = chunk->size; - } -@@ -2518,9 +2572,9 @@ static int ath11k_qmi_m3_load(struct ath11k_base *ab) - if (m3_mem->vaddr || m3_mem->size) - goto skip_m3_alloc; - -- m3_mem->vaddr = dma_alloc_coherent(ab->dev, -+ m3_mem->vaddr = ath11k_core_dma_alloc_coherent(ab->dev, - fw->size, &m3_mem->paddr, -- GFP_KERNEL); -+ GFP_KERNEL | GFP_DMA32); - if (!m3_mem->vaddr) { - ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n", - fw->size); -@@ -3306,6 +3360,9 @@ int ath11k_qmi_init_service(struct ath11k_base *ab) - spin_lock_init(&ab->qmi.event_lock); - INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work); - -+ memset(ab->remote_mem, 0, -+ sizeof(struct fw_remote_mem) * ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01); -+ - ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01, - ATH11K_QMI_WLFW_SERVICE_VERS_V01, - ab->qmi.service_ins_id); -diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h -index d477e2be8..a5c8887b7 100644 ---- a/drivers/net/wireless/ath/ath11k/qmi.h -+++ b/drivers/net/wireless/ath/ath11k/qmi.h -@@ -518,5 +518,6 @@ void ath11k_qmi_deinit_service(struct ath11k_base *ab); - int ath11k_qmi_init_service(struct ath11k_base *ab); - void ath11k_qmi_free_resource(struct ath11k_base *ab); - int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab); -+int ath11k_qmi_remote_dump(struct ath11k_base *ab); - - #endif -diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c -index 7f9fb968d..9f28c82c2 100644 ---- a/drivers/net/wireless/ath/ath11k/reg.c -+++ b/drivers/net/wireless/ath/ath11k/reg.c -@@ -55,6 +55,17 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) - ath11k_dbg(ar->ab, ATH11K_DBG_REG, - "Regulatory Notification received for %s\n", wiphy_name(wiphy)); - -+ if ((request->initiator == NL80211_REGDOM_SET_BY_DRIVER) && -+ (ar->state == ATH11K_STATE_ON)) { -+ ath11k_dbg(ar->ab, ATH11K_DBG_REG, -+ "dynamically updated by driver\n"); -+ ret = ath11k_reg_update_chan_list(ar, true); -+ if (ret) -+ ath11k_warn(ar->ab, "failed to update channel list: %d\n", ret); -+ -+ return; + } + - /* Currently supporting only General User Hints. Cell base user - * hints to be handled later. - * Hints from other sources like Core, Beacons are not expected for -@@ -112,32 +123,7 @@ int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) - struct channel_param *ch; - enum nl80211_band band; - int num_channels = 0; -- int i, ret, left; -- -- if (wait && ar->state_11d != ATH11K_11D_IDLE) { -- left = wait_for_completion_timeout(&ar->completed_11d_scan, -- ATH11K_SCAN_TIMEOUT_HZ); -- if (!left) { -- ath11k_dbg(ar->ab, ATH11K_DBG_REG, -- "failed to receive 11d scan complete: timed out\n"); -- ar->state_11d = ATH11K_11D_IDLE; -- } -- ath11k_dbg(ar->ab, ATH11K_DBG_REG, -- "11d scan wait left time %d\n", left); -- } -- -- if (wait && -- (ar->scan.state == ATH11K_SCAN_STARTING || -- ar->scan.state == ATH11K_SCAN_RUNNING)) { -- left = wait_for_completion_timeout(&ar->scan.completed, -- ATH11K_SCAN_TIMEOUT_HZ); -- if (!left) -- ath11k_dbg(ar->ab, ATH11K_DBG_REG, -- "failed to receive hw scan complete: timed out\n"); -- -- ath11k_dbg(ar->ab, ATH11K_DBG_REG, -- "hw scan wait left time %d\n", left); -- } -+ int i, ret = 0; - - if (ar->state == ATH11K_STATE_RESTARTING) - return 0; -@@ -219,8 +205,15 @@ int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) - } - } - -- ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); -- kfree(params); -+ if (wait) { -+ spin_lock_bh(&ar->channel_update_lock); -+ list_add_tail(¶ms->list, &ar->channel_update_queue); -+ spin_unlock_bh(&ar->channel_update_lock); -+ queue_work(ar->ab->workqueue, &ar->channel_update_work); -+ } else { -+ ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); -+ kfree(params); -+ } - - return ret; - } -@@ -294,12 +287,6 @@ int ath11k_regd_update(struct ath11k *ar) - if (ret) - goto err; - -- if (ar->state == ATH11K_STATE_ON) { -- ret = ath11k_reg_update_chan_list(ar, true); -- if (ret) -- goto err; -- } -- return 0; - err: - ath11k_warn(ab, "failed to perform regd update : %d\n", ret); -@@ -413,6 +400,10 @@ static void ath11k_reg_intersect_rules(struct ieee80211_reg_rule *rule1, - - /* Use the flags of both the rules */ - new_rule->flags = rule1->flags | rule2->flags; -+ if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD)) -+ new_rule->psd = min_t(s8, rule1->psd, rule2->psd); -+ else -+ new_rule->flags &= ~NL80211_RRF_PSD; - - /* To be safe, lts use the max cac timeout of both rules */ - new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms, -@@ -516,13 +507,14 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw) - static void - ath11k_reg_update_rule(struct ieee80211_reg_rule *reg_rule, u32 start_freq, - u32 end_freq, u32 bw, u32 ant_gain, u32 reg_pwr, -- u32 reg_flags) -+ s8 psd, u32 reg_flags) - { - reg_rule->freq_range.start_freq_khz = MHZ_TO_KHZ(start_freq); - reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(end_freq); - reg_rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw); - reg_rule->power_rule.max_antenna_gain = DBI_TO_MBI(ant_gain); - reg_rule->power_rule.max_eirp = DBM_TO_MBM(reg_pwr); -+ reg_rule->psd = psd; - reg_rule->flags = reg_flags; - } - -@@ -552,7 +544,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, - reg_rule->start_freq, - ETSI_WEATHER_RADAR_BAND_LOW, bw, - reg_rule->ant_gain, reg_rule->reg_power, -- flags); -+ reg_rule->psd_eirp, flags); - - ath11k_dbg(ab, ATH11K_DBG_REG, - "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -@@ -573,7 +565,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, - - ath11k_reg_update_rule(regd->reg_rules + i, start_freq, - end_freq, bw, reg_rule->ant_gain, -- reg_rule->reg_power, flags); -+ reg_rule->reg_power, reg_rule->psd_eirp, flags); - - regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT; - -@@ -594,7 +586,7 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, - ETSI_WEATHER_RADAR_BAND_HIGH, - reg_rule->end_freq, bw, - reg_rule->ant_gain, reg_rule->reg_power, -- flags); -+ reg_rule->psd_eirp, flags); - - ath11k_dbg(ab, ATH11K_DBG_REG, - "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", -@@ -607,25 +599,64 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, - *rule_idx = i; - } - -+enum wmi_reg_6ghz_ap_type -+ath11k_ieee80211_ap_pwr_type_convert(enum ieee80211_ap_reg_power power_type) -+{ -+ switch (power_type) { -+ case IEEE80211_REG_LPI_AP: -+ return WMI_REG_INDOOR_AP; -+ case IEEE80211_REG_SP_AP: -+ return WMI_REG_STANDARD_POWER_AP; -+ case IEEE80211_REG_VLP_AP: -+ return WMI_REG_VERY_LOW_POWER_AP; -+ default: -+ return WMI_REG_MAX_AP_TYPE; -+ } -+} -+ - struct ieee80211_regdomain * - ath11k_reg_build_regd(struct ath11k_base *ab, -- struct cur_regulatory_info *reg_info, bool intersect) -+ struct cur_regulatory_info *reg_info, bool intersect, -+ enum wmi_vdev_type vdev_type, -+ enum ieee80211_ap_reg_power power_type) - { - struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL; -- struct cur_reg_rule *reg_rule; -+ struct cur_reg_rule *reg_rule, *reg_rule_6ghz; - u8 i = 0, j = 0, k = 0; - u8 num_rules; - u16 max_bw; -- u32 flags; -+ u32 flags, reg_6ghz_number, max_bw_6ghz; - char alpha2[3]; - - num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules; -- /* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list. -- * This can be updated after complete 6 GHz regulatory support is added. -- */ -- if (reg_info->is_ext_reg_event) -- num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; -+ if (reg_info->is_ext_reg_event) { -+ if (vdev_type == WMI_VDEV_TYPE_STA) { -+ enum wmi_reg_6ghz_ap_type ap_type; -+ -+ ap_type = ath11k_ieee80211_ap_pwr_type_convert(power_type); -+ -+ if (ap_type == WMI_REG_MAX_AP_TYPE) -+ ap_type = WMI_REG_INDOOR_AP; -+ reg_6ghz_number = reg_info->num_6ghz_rules_client -+ [ap_type][WMI_REG_DEFAULT_CLIENT]; -+ if (reg_6ghz_number == 0) { -+ ap_type = WMI_REG_INDOOR_AP; -+ reg_6ghz_number = reg_info->num_6ghz_rules_client -+ [ap_type][WMI_REG_DEFAULT_CLIENT]; -+ } -+ reg_rule_6ghz = reg_info->reg_rules_6ghz_client_ptr -+ [ap_type][WMI_REG_DEFAULT_CLIENT]; -+ max_bw_6ghz = reg_info->max_bw_6ghz_client -+ [ap_type][WMI_REG_DEFAULT_CLIENT]; -+ } else { -+ reg_6ghz_number = reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP]; -+ reg_rule_6ghz = -+ reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP]; -+ max_bw_6ghz = reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]; -+ } -+ num_rules += reg_6ghz_number; -+ } - - if (!num_rules) - goto ret; -@@ -672,14 +703,13 @@ ath11k_reg_build_regd(struct ath11k_base *ab, - * per other BW rule flags we pass from here - */ - flags = NL80211_RRF_AUTO_BW; -- } else if (reg_info->is_ext_reg_event && -- reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] && -- (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) { -- reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] + -- k++; -- max_bw = min_t(u16, reg_rule->max_bw, -- reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]); -+ } else if (reg_info->is_ext_reg_event && reg_6ghz_number && -+ (k < reg_6ghz_number)) { -+ reg_rule = reg_rule_6ghz + k++; -+ max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz); - flags = NL80211_RRF_AUTO_BW; -+ if (reg_rule->psd_flag) -+ flags |= NL80211_RRF_PSD; - } else { - break; - } -@@ -690,7 +720,7 @@ ath11k_reg_build_regd(struct ath11k_base *ab, - reg_rule->start_freq, - reg_rule->end_freq, max_bw, - reg_rule->ant_gain, reg_rule->reg_power, -- flags); -+ reg_rule->psd_eirp, flags); - - /* Update dfs cac timeout if the dfs domain is ETSI and the - * new rule covers weather radar band. -@@ -746,6 +776,50 @@ ath11k_reg_build_regd(struct ath11k_base *ab, - return new_regd; - } - -+void ath11k_regd_update_chan_list_work(struct work_struct *work) -+{ -+ struct ath11k *ar = container_of(work, struct ath11k, -+ channel_update_work); -+ struct scan_chan_list_params *params, *tmp; -+ int left; -+ -+ spin_lock_bh(&ar->channel_update_lock); -+ -+ list_for_each_entry_safe(params, tmp, &ar->channel_update_queue, list) { -+ list_del(¶ms->list); -+ spin_unlock_bh(&ar->channel_update_lock); -+ -+ if (ar->state_11d != ATH11K_11D_IDLE) { -+ left = wait_for_completion_timeout(&ar->completed_11d_scan, -+ ATH11K_SCAN_TIMEOUT_HZ); -+ if (!left) { -+ ath11k_dbg(ar->ab, ATH11K_DBG_REG, -+ "failed to receive 11d scan complete: timed out\n"); -+ ar->state_11d = ATH11K_11D_IDLE; -+ } -+ ath11k_dbg(ar->ab, ATH11K_DBG_REG, -+ "reg 11d scan wait left time %d\n", left); -+ } -+ -+ if ((ar->scan.state == ATH11K_SCAN_STARTING || -+ ar->scan.state == ATH11K_SCAN_RUNNING)) { -+ left = wait_for_completion_timeout(&ar->scan.completed, -+ ATH11K_SCAN_TIMEOUT_HZ); -+ if (!left) -+ ath11k_dbg(ar->ab, ATH11K_DBG_REG, -+ "failed to receive hw scan complete: timed out\n"); -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_REG, -+ "reg hw scan wait left time %d\n", left); -+ } -+ -+ ath11k_wmi_send_scan_chan_list_cmd(ar, params); -+ kfree(params); -+ spin_lock_bh(&ar->channel_update_lock); -+ } -+ spin_unlock_bh(&ar->channel_update_lock); -+} -+ - void ath11k_regd_update_work(struct work_struct *work) - { - struct ath11k *ar = container_of(work, struct ath11k, -@@ -766,6 +840,7 @@ void ath11k_regd_update_work(struct work_struct *work) - void ath11k_reg_init(struct ath11k *ar) - { - ar->hw->wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED; -+ ar->hw->wiphy->flags |= WIPHY_FLAG_NOTIFY_REGDOM_BY_DRIVER; - ar->hw->wiphy->reg_notifier = ath11k_reg_notifier; - } - -@@ -773,6 +848,12 @@ void ath11k_reg_free(struct ath11k_base *ab) - { - int i; - -+ for (i = 0; i < ab->num_radios; i++) -+ ath11k_reg_reset_info(&ab->reg_info_store[i]); -+ -+ kfree(ab->reg_info_store); -+ ab->reg_info_store = NULL; -+ - for (i = 0; i < ab->hw_params.max_radios; i++) { - kfree(ab->default_regd[i]); - kfree(ab->new_regd[i]); -diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h -index 2f284f263..fef5927c6 100644 ---- a/drivers/net/wireless/ath/ath11k/reg.h -+++ b/drivers/net/wireless/ath/ath11k/reg.h -@@ -28,9 +28,14 @@ enum ath11k_dfs_region { - void ath11k_reg_init(struct ath11k *ar); - void ath11k_reg_free(struct ath11k_base *ab); - void ath11k_regd_update_work(struct work_struct *work); -+void ath11k_regd_update_chan_list_work(struct work_struct *work); - struct ieee80211_regdomain * - ath11k_reg_build_regd(struct ath11k_base *ab, -- struct cur_regulatory_info *reg_info, bool intersect); -+ struct cur_regulatory_info *reg_info, bool intersect, -+ enum wmi_vdev_type vdev_type, -+ enum ieee80211_ap_reg_power power_type); -+enum wmi_reg_6ghz_ap_type -+ath11k_ieee80211_ap_pwr_type_convert(enum ieee80211_ap_reg_power power_type); - int ath11k_regd_update(struct ath11k *ar); - int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); - #endif -diff --git a/drivers/net/wireless/ath/ath11k/testmode.h b/drivers/net/wireless/ath/ath11k/testmode.h -index 2f62f2c44..a944086cf 100644 ---- a/drivers/net/wireless/ath/ath11k/testmode.h -+++ b/drivers/net/wireless/ath/ath11k/testmode.h -@@ -8,17 +8,29 @@ - - #ifdef CONFIG_NL80211_TESTMODE - --void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, struct sk_buff *skb); -+void ath11k_tm_wmi_event_unsegmented(struct ath11k_base *ab, u32 cmd_id, -+ struct sk_buff *skb); -+int ath11k_tm_process_event(struct ath11k_base *ab, u32 cmd_id, -+ const struct wmi_ftm_event_msg *ftm_msg, -+ u16 length); - int ath11k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - void *data, int len); - - #else - --static inline void ath11k_tm_wmi_event(struct ath11k_base *ab, u32 cmd_id, -- struct sk_buff *skb) -+static inline void ath11k_tm_wmi_event_unsegmented(struct ath11k_base *ab, -+ u32 cmd_id, -+ struct sk_buff *skb) - { - } - -+static inline int ath11k_tm_process_event(struct ath11k_base *ab, u32 cmd_id, -+ const struct wmi_ftm_event_msg *msg, -+ u16 length) -+{ -+ return 0; -+} -+ - static inline int ath11k_tm_cmd(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - void *data, int len) -diff --git a/drivers/net/wireless/ath/ath11k/unitest.c b/drivers/net/wireless/ath/ath11k/unitest.c -new file mode 100644 -index 000000000..541925af0 ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/unitest.c -@@ -0,0 +1,96 @@ -+// SPDX-License-Identifier: BSD-3-Clause-Clear -+/** -+ * Copyright (c) 2020 The Linux Foundation. All rights reserved. -+ */ -+ -+#include <net/netlink.h> -+#include "debug.h" -+#include "unitest.h" -+ -+const struct nla_policy ath11k_unitest_policy[UNITEST_MAX + 1] = { -+ [UNITEST_MODULE_ID] = {.type = NLA_U32}, -+ [UNITEST_ARGS_NUM] = {.type = NLA_U32}, -+ [UNITEST_ARGS] = {.type = NLA_BINARY, -+ .len = MAX_UNITEST_MEMORY_LEN}, -+}; -+ -+/** -+ * ath11k_unit_test() - send unit test command -+ * @wiphy: wiphy structure pointer -+ * @wdev: Wireless device structure pointer -+ * @data: Pointer to the data received -+ * @data_len: Length of @data -+ * -+ * Return: 0 on success; errno on failure -+ */ -+ -+int ath11k_unit_test(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len) -+{ -+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); -+ struct ath11k *ar = hw->priv; -+ struct ath11k_base *ab = ar->ab; -+ struct nlattr *tb[UNITEST_MAX + 1]; -+ int status = 0; -+ u32 module_id, num_args, temp_num_args, len; -+ bool sta_found = false; -+ struct ath11k_vif *arvif; -+ struct unit_test_cmd utest_cmd = {0}; -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ if (arvif->vdev_type != WMI_VDEV_TYPE_STA || -+ arvif->vdev_subtype != WMI_VDEV_SUBTYPE_NONE) -+ continue; -+ sta_found = true; -+ break; -+ } -+ if (!sta_found) { -+ ath11k_warn(ar->ab, "no sta found."); -+ return -EINVAL; -+ } -+ -+ utest_cmd.vdev_id = arvif->vdev_id; -+ -+ if (nla_parse(tb, UNITEST_MAX, data, data_len, ath11k_unitest_policy, NULL)) { -+ ath11k_warn(ab, "Invalid ATTR"); -+ return -EINVAL; -+ } -+ -+ if (!tb[UNITEST_MODULE_ID]) { -+ ath11k_warn(ab, "attr unitest module id failed"); -+ return -EINVAL; -+ } -+ module_id = nla_get_u32(tb[UNITEST_MODULE_ID]); -+ utest_cmd.module_id = module_id; -+ -+ if (!tb[UNITEST_ARGS_NUM]) { -+ ath11k_warn(ab, "attr unitest args num failed"); -+ return -EINVAL; -+ } -+ num_args = nla_get_u32(tb[UNITEST_ARGS_NUM]); -+ utest_cmd.num_args = num_args; -+ if (num_args > UNIT_TEST_MAX_NUM_ARGS) { -+ ath11k_warn(ab, "num args exceed"); -+ return -EINVAL; -+ } -+ -+ if (!tb[UNITEST_ARGS]) { -+ ath11k_warn(ab, "attr unitest args failed"); -+ return -EINVAL; -+ } -+ len = nla_len(tb[UNITEST_ARGS]); -+ temp_num_args = len / sizeof(u32); -+ if (num_args != temp_num_args) { -+ ath11k_warn(ab, "num args mismatch"); -+ return -EINVAL; -+ } -+ nla_memcpy(utest_cmd.args, tb[UNITEST_ARGS], len); -+ -+ status = ath11k_wmi_set_unit_test(ar, &utest_cmd); -+ if (status) { -+ ath11k_warn(ab, "Unable to post unit test message (status-%d)", status); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -diff --git a/drivers/net/wireless/ath/ath11k/unitest.h b/drivers/net/wireless/ath/ath11k/unitest.h -new file mode 100644 -index 000000000..9fee1cd68 ---- /dev/null -+++ b/drivers/net/wireless/ath/ath11k/unitest.h -@@ -0,0 +1,44 @@ -+/* SPDX-License-Identifier: BSD-3-Clause-Clear */ -+/** -+ * Copyright (c) 2020 The Linux Foundation. All rights reserved. -+ */ -+ -+#ifndef _UNIT_TEST_H_ -+#define _UNIT_TEST_H_ -+ -+#define VENDOR_ID 0x001374 -+#define QCA_NL80211_VENDOR_UNITEST_SUBCMD 84 -+#define MAX_UNITEST_MEMORY_LEN 128 -+ -+enum qca_wlan_vendor_attr_unit_test { -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_INVALID = 0, -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_MODULE_ID, -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_ARGS_NUM, -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_ARGS, -+ /* keep last */ -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_AFTER_LAST, -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_MAX = -+ QCA_WLAN_VENDOR_ATTR_UNIT_TEST_AFTER_LAST - 1, -+}; -+ -+#define UNITEST_INVALID QCA_WLAN_VENDOR_ATTR_UNIT_TEST_INVALID -+#define UNITEST_MODULE_ID QCA_WLAN_VENDOR_ATTR_UNIT_TEST_MODULE_ID -+#define UNITEST_ARGS QCA_WLAN_VENDOR_ATTR_UNIT_TEST_ARGS -+#define UNITEST_ARGS_NUM QCA_WLAN_VENDOR_ATTR_UNIT_TEST_ARGS_NUM -+#define UNITEST_MAX QCA_WLAN_VENDOR_ATTR_UNIT_TEST_MAX -+ -+#define ath11k_unit_test_command \ -+{\ -+ .info.vendor_id = VENDOR_ID,\ -+ .info.subcmd = QCA_NL80211_VENDOR_UNITEST_SUBCMD,\ -+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |\ -+ WIPHY_VENDOR_CMD_NEED_NETDEV |\ -+ WIPHY_VENDOR_CMD_NEED_RUNNING,\ -+ .doit = ath11k_unit_test,\ -+ .policy = VENDOR_CMD_RAW_DATA,\ -+ .maxattr = QCA_WLAN_VENDOR_ATTR_UNIT_TEST_MAX,\ -+} -+ -+int ath11k_unit_test(struct wiphy *wiphy, struct wireless_dev *wdev, -+ const void *data, int data_len); -+#endif + err_reo_cleanup: +diff --git a/drivers/net/wireless/ath/ath11k/hw.h b/drivers/net/wireless/ath/ath11k/hw.h +index 8a3f24862edc4..4da64301d2974 100644 +--- a/drivers/net/wireless/ath/ath11k/hw.h ++++ b/drivers/net/wireless/ath/ath11k/hw.h +@@ -200,6 +200,7 @@ struct ath11k_hw_params { + bool fw_wmi_diag_event; + bool current_cc_support; + bool dbr_debug_support; ++ bool coex_isolation; + bool global_reset; + const struct cfg80211_sar_capa *bios_sar_capa; + bool m3_fw_support; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c -index 1c07f55c2..04e9fdd69 100644 +index 9037919a3ae90..5050c0dfe2508 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c -@@ -2379,6 +2379,69 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar, +@@ -8880,6 +8880,32 @@ return ret; } - -+int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, -+ u32 vdev_id, -+ struct ath11k_reg_tpc_power_info *param) -+{ -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct wmi_vdev_set_tpc_power_cmd *cmd; -+ struct wmi_vdev_ch_power_info *ch; -+ struct sk_buff *skb; -+ struct wmi_tlv *tlv; -+ u8 *ptr; -+ int i, ret, len; -+ -+ len = sizeof(*cmd) + TLV_HDR_SIZE; -+ len += (sizeof(struct wmi_vdev_ch_power_info) * param->num_pwr_levels); -+ -+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ ptr = skb->data; -+ -+ cmd = (struct wmi_vdev_set_tpc_power_cmd *)ptr; -+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_VDEV_SET_TPC_POWER_CMD) | -+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); -+ cmd->vdev_id = vdev_id; -+ cmd->psd_power = param->is_psd_power; -+ cmd->eirp_power = param->eirp_power; -+ cmd->power_type_6ghz = param->power_type_6g; -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "wmi tpc vdev_id %d is_psd_power %d eirp_power %d power_type_6g %d\n", -+ vdev_id, param->is_psd_power, param->eirp_power, param->power_type_6g); -+ -+ ptr += sizeof(*cmd); -+ tlv = (struct wmi_tlv *)ptr; -+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_STRUCT) | -+ FIELD_PREP(WMI_TLV_LEN, param->num_pwr_levels * sizeof(*ch)); -+ -+ ptr += TLV_HDR_SIZE; -+ ch = (struct wmi_vdev_ch_power_info *)ptr; -+ -+ for (i = 0; i < param->num_pwr_levels; i++, ch++) { -+ ch->tlv_header = FIELD_PREP(WMI_TLV_TAG, -+ WMI_TAG_VDEV_CH_POWER_INFO) | -+ FIELD_PREP(WMI_TLV_LEN, -+ sizeof(*ch) - TLV_HDR_SIZE); -+ -+ ch->chan_cfreq = param->chan_power_info[i].chan_cfreq; -+ ch->tx_power = param->chan_power_info[i].tx_power; -+ -+ ath11k_dbg(ar->ab, ATH11K_DBG_WMI, -+ "wmi tpc chan_cfreq %d tx_power %d\n", -+ ch->chan_cfreq, ch->tx_power); -+ } -+ -+ ret = ath11k_wmi_cmd_send(wmi, skb, -+ WMI_VDEV_SET_TPC_POWER_CMDID); -+ if (ret) { -+ ath11k_warn(ar->ab, "failed to send WMI_VDEV_SET_TPC_POWER_CMDID\n"); -+ dev_kfree_skb(skb); -+ } -+ return ret; -+} -+ - int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar, - struct scan_cancel_param *param) - { -@@ -4069,6 +4132,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg, - wmi_cfg->sched_params = tg_cfg->sched_params; - wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; - wmi_cfg->twt_ap_sta_count = tg_cfg->twt_ap_sta_count; -+ wmi_cfg->host_service_flags = tg_cfg->host_service_flags; - wmi_cfg->host_service_flags &= - ~(1 << WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT); - wmi_cfg->host_service_flags |= (tg_cfg->is_reg_cc_ext_event_supported << -@@ -4749,6 +4813,11 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, - soc->pdevs[0].pdev_id = 0; - } - -+ if (!soc->reg_info_store) -+ soc->reg_info_store = kcalloc(soc->num_radios, -+ sizeof(*soc->reg_info_store), -+ GFP_ATOMIC); -+ - return 0; - } - -@@ -5028,6 +5097,7 @@ static int ath11k_pull_vdev_start_resp_tlv(struct ath11k_base *ab, struct sk_buf - vdev_rsp->mac_id = ev->mac_id; - vdev_rsp->cfgd_tx_streams = ev->cfgd_tx_streams; - vdev_rsp->cfgd_rx_streams = ev->cfgd_rx_streams; -+ vdev_rsp->max_allowed_tx_power = ev->max_allowed_tx_power; - - kfree(tb); - return 0; -@@ -7070,33 +7140,34 @@ static bool ath11k_reg_is_world_alpha(char *alpha) - return false; - } - --static int ath11k_reg_chan_list_event(struct ath11k_base *ab, -- struct sk_buff *skb, -- enum wmi_reg_chan_list_cmd_type id) -+void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info) - { -- struct cur_regulatory_info *reg_info = NULL; -- struct ieee80211_regdomain *regd = NULL; -- bool intersect = false; -- int ret = 0, pdev_idx, i, j; -- struct ath11k *ar; -+ int i, j; - -- reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); -- if (!reg_info) { -- ret = -ENOMEM; -- goto fallback; -- } -+ if (reg_info) { -+ kfree(reg_info->reg_rules_2ghz_ptr); - -- if (id == WMI_REG_CHAN_LIST_CC_ID) -- ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); -- else -- ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); -+ kfree(reg_info->reg_rules_5ghz_ptr); - -- if (ret) { -- ath11k_warn(ab, "failed to extract regulatory info from received event\n"); -- goto fallback; -+ for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) { -+ kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); -+ for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++) -+ kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]); -+ } -+ -+ memset(reg_info, 0, sizeof(*reg_info)); - } -+} - -- ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id); -+int ath11k_reg_handle_chan_list(struct ath11k_base *ab, -+ struct cur_regulatory_info *reg_info, -+ enum ieee80211_ap_reg_power power_type) -+{ -+ struct ieee80211_regdomain *regd; -+ bool intersect = false; -+ int pdev_idx; -+ struct ath11k *ar; -+ enum wmi_vdev_type vdev_type; - - if (reg_info->status_code != REG_SET_CC_STATUS_PASS) { - /* In case of failure to set the requested ctry, -@@ -7104,7 +7175,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - * and return from here. - */ - ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n"); -- goto mem_free; -+ return -EINVAL; - } - - pdev_idx = reg_info->phy_id; -@@ -7112,13 +7183,13 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - /* Avoid default reg rule updates sent during FW recovery if - * it is already available - */ -- spin_lock(&ab->base_lock); -+ spin_lock_bh(&ab->base_lock); - if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) && - ab->default_regd[pdev_idx]) { -- spin_unlock(&ab->base_lock); -- goto mem_free; -+ spin_unlock_bh(&ab->base_lock); -+ goto retfail; - } -- spin_unlock(&ab->base_lock); -+ spin_unlock_bh(&ab->base_lock); - - if (pdev_idx >= ab->num_radios) { - /* Process the event for phy0 only if single_pdev_only -@@ -7127,7 +7198,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - */ - if (ab->hw_params.single_pdev_only && - pdev_idx < ab->hw_params.num_rxmda_per_pdev) -- goto mem_free; -+ goto retfail; - else - goto fallback; - } -@@ -7138,7 +7209,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] && - !memcmp((char *)ab->default_regd[pdev_idx]->alpha2, - (char *)reg_info->alpha2, 2)) -- goto mem_free; -+ goto retfail; - - /* Intersect new rules with default regd if a new country setting was - * requested, i.e a default regd was already set during initialization -@@ -7150,13 +7221,25 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - !ath11k_reg_is_world_alpha((char *)reg_info->alpha2)) - intersect = true; - -- regd = ath11k_reg_build_regd(ab, reg_info, intersect); -+ ar = ab->pdevs[pdev_idx].ar; -+ vdev_type = ath11k_mac_get_ar_vdev_type(ar); -+ -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+ "wmi handle chan list power type %d vdev type %d intersect %d\n", -+ power_type, vdev_type, intersect); -+ -+ regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type); - if (!regd) { - ath11k_warn(ab, "failed to build regd from reg_info\n"); - goto fallback; - } - -- spin_lock(&ab->base_lock); -+ if (power_type == IEEE80211_REG_UNSET_AP) { -+ ath11k_reg_reset_info(&ab->reg_info_store[pdev_idx]); -+ ab->reg_info_store[pdev_idx] = *reg_info; -+ } -+ -+ spin_lock_bh(&ab->base_lock); - if (ab->default_regd[pdev_idx]) { - /* The initial rules from FW after WMI Init is to build - * the default regd. From then on, any rules updated for -@@ -7176,9 +7259,9 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - ab->default_regd[pdev_idx] = regd; - } - ab->dfs_region = reg_info->dfs_region; -- spin_unlock(&ab->base_lock); -+ spin_unlock_bh(&ab->base_lock); - -- goto mem_free; -+ return 0; - - fallback: - /* Fallback to older reg (by sending previous country setting -@@ -7190,20 +7273,45 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, - */ - /* TODO: This is rare, but still should also be handled */ - WARN_ON(1); --mem_free: -- if (reg_info) { -- kfree(reg_info->reg_rules_2ghz_ptr); -- kfree(reg_info->reg_rules_5ghz_ptr); -- if (reg_info->is_ext_reg_event) { -- for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) -- kfree(reg_info->reg_rules_6ghz_ap_ptr[i]); - -- for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++) -- for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++) -- kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]); -- } -- kfree(reg_info); -+retfail: -+ -+ return -EINVAL; -+} -+ -+static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb, -+ enum wmi_reg_chan_list_cmd_type id) -+{ -+ struct cur_regulatory_info *reg_info; -+ int ret; -+ -+ reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); -+ if (!reg_info) -+ return -ENOMEM; -+ -+ if (id == WMI_REG_CHAN_LIST_CC_ID) -+ ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info); -+ else -+ ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info); -+ -+ if (ret) { -+ ath11k_warn(ab, "failed to extract regulatory info from received event\n"); -+ goto mem_free; -+ } -+ -+ ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP); -+ if (ret) { -+ ath11k_dbg(ab, ATH11K_DBG_WMI, -+ "failed to process regulatory info from received event\n"); -+ goto mem_free; - } -+ -+ kfree(reg_info); -+ return 0; -+ -+mem_free: -+ ath11k_reg_reset_info(reg_info); -+ kfree(reg_info); - return ret; - } - -@@ -7363,7 +7471,7 @@ static void ath11k_vdev_start_resp_event(struct ath11k_base *ab, struct sk_buff - } - - ar->last_wmi_vdev_start_status = 0; -- -+ ar->max_allowed_tx_power = vdev_start_resp.max_allowed_tx_power; - status = vdev_start_resp.status; - - if (WARN_ON_ONCE(status)) { -@@ -8308,6 +8416,37 @@ ath11k_wmi_pdev_csa_switch_count_status_event(struct ath11k_base *ab, - kfree(tb); - } - -+static void -+ath11k_wmi_tm_event_segmented(struct ath11k_base *ab, u32 cmd_id, -+ struct sk_buff *skb) -+{ -+ const void **tb; -+ const struct wmi_ftm_event_msg *ev; -+ u16 length; -+ int ret; -+ -+ tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); -+ if (IS_ERR(tb)) { -+ ret = PTR_ERR(tb); -+ ath11k_warn(ab, "failed to parse ftm event tlv: %d\n", ret); -+ return; -+ } -+ -+ ev = tb[WMI_TAG_ARRAY_BYTE]; -+ if (!ev) { -+ ath11k_warn(ab, "failed to fetch ftm msg\n"); -+ kfree(tb); -+ return; -+ } -+ -+ length = skb->len - TLV_HDR_SIZE; -+ ret = ath11k_tm_process_event(ab, cmd_id, ev, length); -+ if (ret) -+ ath11k_warn(ab, "Failed to process ftm event\n"); -+ -+ kfree(tb); -+} -+ - static void - ath11k_wmi_pdev_dfs_radar_detected_event(struct ath11k_base *ab, struct sk_buff *skb) - { -@@ -8734,7 +8873,10 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb) - ath11k_wmi_pdev_csa_switch_count_status_event(ab, skb); - break; - case WMI_PDEV_UTF_EVENTID: -- ath11k_tm_wmi_event(ab, id, skb); -+ if (test_bit(ATH11K_FLAG_FTM_SEGMENTED, &ab->dev_flags)) -+ ath11k_wmi_tm_event_segmented(ab, id, skb); -+ else -+ ath11k_tm_wmi_event_unsegmented(ab, id, skb); - break; - case WMI_PDEV_TEMPERATURE_EVENTID: - ath11k_wmi_pdev_temperature_event(ab, skb); -@@ -9794,3 +9936,76 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar, - - return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID); - } -+ -+int ath11k_wmi_set_unit_test(struct ath11k *ar, struct unit_test_cmd *unit_test) -+{ -+ struct ath11k_pdev_wmi *wmi = ar->wmi; -+ struct sk_buff *skb; -+ struct wmi_unit_test_cmd_fixed_param *cmd; -+ u32 len, args_tlv_len; -+ u8 *buf_ptr; -+ u32 *args; -+ struct wmi_tlv *tlv; -+ u32 i; -+ -+ args_tlv_len = TLV_HDR_SIZE + unit_test->num_args * sizeof(u32); -+ -+ len = sizeof(struct wmi_unit_test_cmd_fixed_param) + args_tlv_len; -+ skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len); -+ if (!skb) -+ return -ENOMEM; -+ -+ cmd = (struct wmi_unit_test_cmd_fixed_param *)skb->data; -+ buf_ptr = (u8 *)cmd; -+ cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, -+ WMI_TAG_UNIT_TEST_CMD) | -+ FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); -+ cmd->vdev_id = unit_test->vdev_id; -+ cmd->module_id = unit_test->module_id; -+ cmd->num_args = unit_test->num_args; -+ -+ buf_ptr += sizeof(*cmd); -+ -+ tlv = (struct wmi_tlv *)buf_ptr; -+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) | -+ FIELD_PREP(WMI_TLV_LEN, unit_test->num_args * sizeof(u32)); -+ args = (u32 *)(buf_ptr + TLV_HDR_SIZE); -+ ath11k_info(ar->ab, "module id = 0x%x, num args = %u", -+ unit_test->module_id, unit_test->num_args); -+ for (i = 0; (i < unit_test->num_args && i < UNIT_TEST_MAX_NUM_ARGS); i++) { -+ args[i] = unit_test->args[i]; -+ ath11k_info(ar->ab, "0x%x,", unit_test->args[i]); -+ } -+ -+ return ath11k_wmi_cmd_send(wmi, skb, WMI_UNIT_TEST_CMDID); -+} -+ + +int ath11k_wmi_send_coex_config(struct ath11k *ar, + struct wmi_coex_config_params *param) +{ @@ -3235,194 +501,21 @@ index 1c07f55c2..04e9fdd69 100644 + cmd->config_arg4 = param->config_arg4; + cmd->config_arg5 = param->config_arg5; + cmd->config_arg6 = param->config_arg6; -+ ath11k_warn(ar->ab, "wmi send coex cfg vdev %d type %u args %u %u %u %u %u %u\n", -+ cmd->vdev_id, cmd->config_type, cmd->config_arg1, -+ cmd->config_arg2, cmd->config_arg3, cmd->config_arg4, -+ cmd->config_arg5, cmd->config_arg6); + + return ath11k_wmi_cmd_send(wmi, skb, WMI_COEX_CONFIG_CMDID); +} ++ + int ath11k_wmi_simulate_radar(struct ath11k *ar) + { + struct ath11k_vif *arvif; diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h -index 100bb816b..9b0fb96aa 100644 +index 373d38538db0c..d63073eaaec3d 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h -@@ -15,6 +15,8 @@ struct ath11k; - struct ath11k_fw_stats; - struct ath11k_fw_dbglog; - struct ath11k_vif; -+struct ath11k_base; -+struct ath11k_reg_tpc_power_info; - - #define PSOC_HOST_MAX_NUM_SS (8) - -@@ -327,6 +329,36 @@ enum wmi_tlv_cmd_id { - WMI_VDEV_SET_CUSTOM_AGGR_SIZE_CMDID, - WMI_VDEV_ENCRYPT_DECRYPT_DATA_REQ_CMDID, - WMI_VDEV_ADD_MAC_ADDR_TO_RX_FILTER_CMDID, -+ /** WMI commands related to dbg arp stats */ -+ WMI_VDEV_SET_ARP_STAT_CMDID, -+ WMI_VDEV_GET_ARP_STAT_CMDID, -+ /** get tx power for the current vdev */ -+ WMI_VDEV_GET_TX_POWER_CMDID, -+ /* limit STA offchannel activity */ -+ WMI_VDEV_LIMIT_OFFCHAN_CMDID, -+ /** To set custom software retries per-AC for vdev */ -+ WMI_VDEV_SET_CUSTOM_SW_RETRY_TH_CMDID, -+ /** To set chainmask configuration for vdev */ -+ WMI_VDEV_CHAINMASK_CONFIG_CMDID, -+ WMI_VDEV_GET_BCN_RECEPTION_STATS_CMDID, -+ /* request LTE-Coex info */ -+ WMI_VDEV_GET_MWS_COEX_INFO_CMDID, -+ /** delete all peer (excluding bss peer) */ -+ WMI_VDEV_DELETE_ALL_PEER_CMDID, -+ /* To set bss max idle time related parameters */ -+ WMI_VDEV_BSS_MAX_IDLE_TIME_CMDID, -+ /** Indicates firmware to trigger Audio sync */ -+ WMI_VDEV_AUDIO_SYNC_TRIGGER_CMDID, -+ /** Gives Qtimer value to firmware */ -+ WMI_VDEV_AUDIO_SYNC_QTIMER_CMDID, -+ /** Preferred channel list for each vdev */ -+ WMI_VDEV_SET_PCL_CMDID, -+ /** VDEV_GET_BIG_DATA_CMD IS DEPRECATED - DO NOT USE */ -+ WMI_VDEV_GET_BIG_DATA_CMDID, -+ /** Get per vdev BIG DATA stats phase 2 */ -+ WMI_VDEV_GET_BIG_DATA_P2_CMDID, -+ /** set TPC PSD/non-PSD power */ -+ WMI_VDEV_SET_TPC_POWER_CMDID, - WMI_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_GRP_PEER), - WMI_PEER_DELETE_CMDID, - WMI_PEER_FLUSH_TIDS_CMDID, -@@ -1878,6 +1910,8 @@ enum wmi_tlv_tag { - WMI_TAG_PDEV_NON_SRG_OBSS_BSSID_ENABLE_BITMAP_CMD, - WMI_TAG_REGULATORY_RULE_EXT_STRUCT = 0x3A9, - WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT, -+ WMI_TAG_VDEV_SET_TPC_POWER_CMD = 0x3B5, -+ WMI_TAG_VDEV_CH_POWER_INFO, - WMI_TAG_PDEV_SET_BIOS_SAR_TABLE_CMD = 0x3D8, - WMI_TAG_PDEV_SET_BIOS_GEO_TABLE_CMD, - WMI_TAG_MAX -@@ -2112,6 +2146,7 @@ enum wmi_tlv_service { - /* The second 128 bits */ - WMI_MAX_EXT_SERVICE = 256, - WMI_TLV_SERVICE_SCAN_CONFIG_PER_CHANNEL = 265, -+ WMI_TLV_SERVICE_EXT_TPC_REG_SUPPORT = 280, - WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT = 281, - WMI_TLV_SERVICE_BIOS_SAR_SUPPORT = 326, - WMI_TLV_SERVICE_SUPPORT_11D_FOR_HOST_SCAN = 357, -@@ -2330,6 +2365,7 @@ struct wmi_init_cmd { - #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) - #define WMI_RSRC_CFG_FLAG2_CALC_NEXT_DTIM_COUNT_SET BIT(9) - #define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) -+#define WMI_RSRC_CFG_HOST_SERVICE_FLAG_NAN_IFACE_SUPPORT BIT(0) - - #define WMI_CFG_HOST_SERVICE_FLAG_REG_CC_EXT 4 - -@@ -2393,6 +2429,7 @@ struct wmi_resource_config { - u32 twt_ap_pdev_count; - u32 twt_ap_sta_count; - u32 max_nlo_ssids; -+ u32 num_packet_filters; - u32 num_pkt_filters; - u32 num_max_sta_vdevs; - u32 max_bssid_indicator; -@@ -3167,6 +3204,31 @@ struct wlan_ssid { - u8 ssid[WLAN_SSID_MAX_LEN]; - }; - -+struct wmi_vdev_ch_power_info { -+ u32 tlv_header; -+ u32 chan_cfreq; /* Channel center frequency (MHz) */ -+ /* Unit: dBm, either PSD/EIRP power for this frequency or -+ * incremental for non-PSD BW -+ */ -+ u32 tx_power; -+} __packed; -+ -+struct wmi_vdev_set_tpc_power_cmd { -+ u32 tlv_header; -+ u32 vdev_id; -+ u32 psd_power; /* Value: 0 or 1, is PSD power or not */ -+ u32 eirp_power; /* Maximum EIRP power (dBm units), valid only if power is PSD */ -+ u32 power_type_6ghz; /* Type: WMI_6GHZ_REG_TYPE, used for halphy CTL lookup */ -+ /* This fixed_param TLV is followed by the below TLVs: -+ * num_pwr_levels of wmi_vdev_ch_power_info -+ * For PSD power, it is the PSD/EIRP power of the frequency (20 MHz chunks). -+ * For non-PSD power, the power values are for 20, 40, and till -+ * BSS BW power levels. -+ * The num_pwr_levels will be checked by sw how many elements present -+ * in the variable-length array. -+ */ -+} __packed; -+ - #define WMI_IE_BITMAP_SIZE 8 +@@ -6322,6 +6323,82 @@ enum wmi_sta_keepalive_method { - /* prefix used by scan requestor ids on the host */ -@@ -3765,6 +3827,7 @@ struct wmi_stop_scan_cmd { - }; - - struct scan_chan_list_params { -+ struct list_head list; - u32 pdev_id; - u16 nallchans; - struct channel_param ch_param[]; -@@ -4143,6 +4206,7 @@ struct wmi_vdev_start_resp_event { - }; - u32 cfgd_tx_streams; - u32 cfgd_rx_streams; -+ s32 max_allowed_tx_power; - } __packed; - - /* VDEV start response status codes */ -@@ -4975,6 +5039,7 @@ struct ath11k_targ_cap { - }; - - enum wmi_vdev_type { -+ WMI_VDEV_TYPE_UNSPEC = 0, - WMI_VDEV_TYPE_AP = 1, - WMI_VDEV_TYPE_STA = 2, - WMI_VDEV_TYPE_IBSS = 3, -@@ -5695,6 +5760,15 @@ struct target_resource_config { - u32 use_pdev_id; - u32 peer_map_unmap_v2_support; - u32 sched_params; -+ u32 max_nlo_ssids; -+ u32 num_packet_filters; -+ u32 num_max_sta_vdevs; -+ u32 max_bssid_indicator; -+ u32 ul_resp_config; -+ u32 msdu_flow_override_config0; -+ u32 msdu_flow_override_config1; -+ u32 flags2; -+ u32 host_service_flags; - u32 twt_ap_pdev_count; - u32 twt_ap_sta_count; - u8 is_reg_cc_ext_event_supported; -@@ -6320,6 +6394,105 @@ enum wmi_sta_keepalive_method { - #define WMI_STA_KEEPALIVE_INTERVAL_DEFAULT 30 - #define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0 - -+#define UNIT_TEST_MAX_NUM_ARGS 8 -+ -+struct unit_test_cmd { -+ u32 vdev_id; -+ u32 module_id; -+ u32 num_args; -+ u32 args[UNIT_TEST_MAX_NUM_ARGS]; -+}; -+ -+struct wmi_unit_test_cmd_fixed_param { -+ u32 tlv_header; -+ u32 vdev_id; -+ u32 module_id; -+ u32 num_args; -+ u32 diag_token; -+ /** -+ * TLV (tag length value) parameters follow the wmi_unit_test_cmd_fixed_param -+ * structure. The TLV's are: -+ * u32 args[]; -+ */ -+} __packed; -+ + const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, + size_t len, gfp_t gfp); +enum wmi_coex_config_type { + WMI_COEX_CONFIG_PAGE_P2P_TDM = 1, + WMI_COEX_CONFIG_PAGE_STA_TDM = 2, @@ -3498,256 +591,189 @@ index 100bb816b..9b0fb96aa 100644 +} __packed; + +#define WMI_COEX_ISOLATION_ARG1_DEFAUT 30 -+#define WMI_COEX_BTC_MODE_ARG1_DEFAULT 1 + - const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr, - size_t len, gfp_t gfp); int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb, -@@ -6483,6 +6656,8 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, + u32 cmd_id); + struct sk_buff *ath11k_wmi_alloc_skb(struct ath11k_wmi_base *wmi_sc, u32 len); +@@ -6171,6 +6247,7 @@ int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar, const u8 mac_addr[ETH_ALEN]); int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap, struct ath11k_fw_dbglog *dbglog); -+int ath11k_wmi_set_unit_test(struct ath11k *ar, struct unit_test_cmd *unit_test); +int ath11k_wmi_send_coex_config(struct ath11k *ar, struct wmi_coex_config_params *param); int ath11k_wmi_wow_config_pno(struct ath11k *ar, u32 vdev_id, struct wmi_pno_scan_req *pno_scan); int ath11k_wmi_wow_del_pattern(struct ath11k *ar, u32 vdev_id, u32 pattern_id); -@@ -6505,4 +6680,11 @@ int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar); - int ath11k_wmi_sta_keepalive(struct ath11k *ar, - const struct wmi_sta_keepalive_arg *arg); - -+void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info); -+int ath11k_reg_handle_chan_list(struct ath11k_base *ab, -+ struct cur_regulatory_info *reg_info, -+ enum ieee80211_ap_reg_power power_type); -+int ath11k_wmi_send_vdev_set_tpc_power(struct ath11k *ar, -+ u32 vdev_id, -+ struct ath11k_reg_tpc_power_info *param); - #endif -diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h -index 153a8c3e7..a8ef1aead 100644 ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -115,6 +115,8 @@ struct wiphy; - * This may be due to the driver or due to regulatory bandwidth - * restrictions. - * @IEEE80211_CHAN_NO_EHT: EHT operation is not permitted on this channel. -+ * @IEEE80211_CHAN_PSD: power spectral density (in dBm) -+ * on this channel - */ - enum ieee80211_channel_flags { - IEEE80211_CHAN_DISABLED = 1<<0, -@@ -138,6 +140,7 @@ enum ieee80211_channel_flags { - IEEE80211_CHAN_16MHZ = 1<<18, - IEEE80211_CHAN_NO_320MHZ = 1<<19, - IEEE80211_CHAN_NO_EHT = 1<<20, -+ IEEE80211_CHAN_PSD = 1<<21, - }; - - #define IEEE80211_CHAN_NO_HT40 \ -@@ -171,6 +174,7 @@ enum ieee80211_channel_flags { - * on this channel. - * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered. - * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels. -+ * @psd: power spectral density (in dBm) - */ - struct ieee80211_channel { - enum nl80211_band band; -@@ -187,6 +191,7 @@ struct ieee80211_channel { - enum nl80211_dfs_state dfs_state; - unsigned long dfs_state_entered; - unsigned int dfs_cac_ms; -+ s8 psd; - }; - - /** -diff --git a/include/net/regulatory.h b/include/net/regulatory.h -index b2cb4a9eb..ebf9e028d 100644 ---- a/include/net/regulatory.h -+++ b/include/net/regulatory.h -@@ -213,6 +213,7 @@ struct ieee80211_reg_rule { - u32 flags; - u32 dfs_cac_ms; - bool has_wmm; -+ s8 psd; - }; - - struct ieee80211_regdomain { -diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h -index 88eb85c63..d9e5a4276 100644 ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -4213,6 +4213,8 @@ enum nl80211_wmm_rule { - * as the primary or any of the secondary channels isn't possible - * @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel - * in current regulatory domain. -+ * @NL80211_FREQUENCY_ATTR_PSD: power spectral density (in dBm) -+ * is allowed on this channel in current regulatory domain. - * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number - * currently defined - * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use -@@ -4251,6 +4253,7 @@ enum nl80211_frequency_attr { - NL80211_FREQUENCY_ATTR_16MHZ, - NL80211_FREQUENCY_ATTR_NO_320MHZ, - NL80211_FREQUENCY_ATTR_NO_EHT, -+ NL80211_FREQUENCY_ATTR_PSD, - - /* keep last */ - __NL80211_FREQUENCY_ATTR_AFTER_LAST, -@@ -4351,6 +4354,8 @@ enum nl80211_reg_type { - * a given frequency range. The value is in mBm (100 * dBm). - * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. - * If not present or 0 default CAC time will be used. -+ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm). -+ * This could be negative. - * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number - * currently defined - * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use -@@ -4368,6 +4373,8 @@ enum nl80211_reg_rule_attr { - - NL80211_ATTR_DFS_CAC_TIME, +-- +GitLab -+ NL80211_ATTR_POWER_RULE_PSD, -+ - /* keep last */ - __NL80211_REG_RULE_ATTR_AFTER_LAST, - NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 -@@ -4450,6 +4457,7 @@ enum nl80211_sched_scan_match_attr { - * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed - * @NL80211_RRF_NO_HE: HE operation not allowed - * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed -+ * @NL80211_RRF_PSD: channels has power spectral density value - * @NL80211_RRF_NO_EHT: EHT operation not allowed - */ - enum nl80211_reg_rule_flags { -@@ -4470,7 +4478,8 @@ enum nl80211_reg_rule_flags { - NL80211_RRF_NO_160MHZ = 1<<16, - NL80211_RRF_NO_HE = 1<<17, - NL80211_RRF_NO_320MHZ = 1<<18, -- NL80211_RRF_NO_EHT = 1<<19, -+ NL80211_RRF_PSD = 1<<19, -+ NL80211_RRF_NO_EHT = 1<<20, - }; - #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR -diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c -index 9596ae1aa..26065fe35 100644 ---- a/kernel/dma/direct.c -+++ b/kernel/dma/direct.c -@@ -317,6 +317,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, - __dma_direct_free_pages(dev, page, size); - return NULL; - } -+EXPORT_SYMBOL(dma_direct_alloc); +From 0f02da05404b27449b01cc3b3a992dcb6f795287 Mon Sep 17 00:00:00 2001 +From: "neil.shi" <neil.shi@quectel.com> +Date: Tue, 23 May 2023 17:41:00 +0800 +Subject: [PATCH] wifi: ath11k: merge all patches to 6.1.11, fix exceptions and + compilation errors - void dma_direct_free(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs) -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 931a03f45..5f64d3716 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -1115,6 +1115,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy, - if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset)) - goto nla_put_failure; +Signed-off-by: neil.shi <neil.shi@quectel.com> +--- + drivers/net/wireless/ath/ath11k/debugfs.c | 1 + + drivers/net/wireless/ath/ath11k/hw.h | 6 ++++ + drivers/net/wireless/ath/ath11k/pci.c | 35 ++++++++++++++++------- + drivers/net/wireless/ath/ath11k/pcic.c | 11 +++++++ + 4 files changed, 43 insertions(+), 10 deletions(-) -+ if ((chan->flags & IEEE80211_CHAN_PSD) && -+ nla_put_s8(msg, NL80211_FREQUENCY_ATTR_PSD, chan->psd)) -+ goto nla_put_failure; -+ - if ((chan->flags & IEEE80211_CHAN_DISABLED) && - nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) - goto nla_put_failure; -@@ -8578,6 +8582,11 @@ static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom, - reg_rule->dfs_cac_ms)) - goto nla_put_failure; +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index 61c8840a0559..798c1010b215 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -228,7 +228,12 @@ static u32 ath11k_pci_window_read32(struct ath11k_base *ab, u32 offset) + struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); + u32 window_start, val; -+ if ((reg_rule->flags & NL80211_RRF_PSD) && -+ nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD, -+ reg_rule->psd)) -+ goto nla_put_failure; +- window_start = ath11k_pci_get_window_start(ab, offset); ++ if (ab->hw_params.static_window_map) ++ window_start = ath11k_pci_get_window_start(ab, offset); ++ else ++ window_start = ATH11K_PCI_WINDOW_START; + - nla_nest_end(msg, nl_reg_rule); - } - -@@ -8751,6 +8760,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = - [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, - [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, - [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 }, -+ [NL80211_ATTR_POWER_RULE_PSD] = { .type = NLA_S8 }, - }; - - static int parse_reg_rule(struct nlattr *tb[], -@@ -8772,6 +8782,14 @@ static int parse_reg_rule(struct nlattr *tb[], ++ //window_start = ath11k_pci_get_window_start(ab, offset); - reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]); + if (window_start == ATH11K_PCI_WINDOW_START) { + spin_lock_bh(&ab_pci->window_lock); +@@ -852,6 +857,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + u32 soc_hw_version_major, soc_hw_version_minor, addr; + const struct ath11k_pci_ops *pci_ops; + int ret; ++ u32 sub_version; ++ int ops_init = 0; -+ if (reg_rule->flags & NL80211_RRF_PSD) { -+ if (!tb[NL80211_ATTR_POWER_RULE_PSD]) -+ return -EINVAL; -+ -+ reg_rule->psd = -+ nla_get_s8(tb[NL80211_ATTR_POWER_RULE_PSD]); -+ } -+ - freq_range->start_freq_khz = - nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); - freq_range->end_freq_khz = -diff --git a/net/wireless/reg.c b/net/wireless/reg.c -index 0317cf9da..e60861610 100644 ---- a/net/wireless/reg.c -+++ b/net/wireless/reg.c -@@ -1589,6 +1589,8 @@ static u32 map_regdom_flags(u32 rd_flags) - channel_flags |= IEEE80211_CHAN_NO_320MHZ; - if (rd_flags & NL80211_RRF_NO_EHT) - channel_flags |= IEEE80211_CHAN_NO_EHT; -+ if (rd_flags & NL80211_RRF_PSD) -+ channel_flags |= IEEE80211_CHAN_PSD; - return channel_flags; - } + ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); -@@ -1795,6 +1797,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, - chan->dfs_cac_ms = reg_rule->dfs_cac_ms; +@@ -899,8 +906,8 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + case QCA6390_DEVICE_ID: + ath11k_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); +- switch (soc_hw_version_major) { +- case 2: ++ switch (soc_hw_version_major) { ++ case 2: + ab->hw_rev = ATH11K_HW_QCA6390_HW20; + break; + default: +@@ -920,6 +927,13 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; + ath11k_pci_read_hw_version(ab, &soc_hw_version_major, + &soc_hw_version_minor); ++ pci_ops = &ath11k_pci_ops_qca6390; ++ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); ++ if (ret) { ++ ath11k_err(ab, "failed to register PCI ops: %d\n", ret); ++ goto err_pci_free_region; ++ } ++ ops_init = 1; + switch (soc_hw_version_major) { + case 2: + switch (soc_hw_version_minor) { +@@ -930,7 +944,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + case 0x10: + case 0x11: + //ab->hw_rev = ATH11K_HW_WCN6855_HW21; +- sub_version = ath11k_pci_read32(ab, SUB_VERSION); ++ sub_version = ath11k_pcic_read32(ab, SUB_VERSION); + ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n", sub_version); + switch (sub_version) { + case 0x1019A0E1: +@@ -955,7 +969,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + goto err_pci_free_region; } -+ if (chan->flags & IEEE80211_CHAN_PSD) -+ chan->psd = reg_rule->psd; -+ - return; - } - -@@ -1815,6 +1820,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, - chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; +- pci_ops = &ath11k_pci_ops_qca6390; + break; + default: + dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", +@@ -964,11 +977,13 @@ static int ath11k_pci_probe(struct pci_dev *pdev, + goto err_pci_free_region; } -+ if (chan->flags & IEEE80211_CHAN_PSD) -+ chan->psd = reg_rule->psd; -+ - if (chan->orig_mpwr) { - /* - * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER -@@ -1884,6 +1892,12 @@ static void handle_channel_adjacent_rules(struct wiphy *wiphy, - rrule2->dfs_cac_ms); - } +- ret = ath11k_pcic_register_pci_ops(ab, pci_ops); +- if (ret) { +- ath11k_err(ab, "failed to register PCI ops: %d\n", ret); +- goto err_pci_free_region; +- } ++ if(ops_init == 1){ ++ ret = ath11k_pcic_register_pci_ops(ab, pci_ops); ++ if (ret) { ++ ath11k_err(ab, "failed to register PCI ops: %d\n", ret); ++ goto err_pci_free_region; ++ } ++ } -+ if ((rrule1->flags & NL80211_RRF_PSD) && -+ (rrule2->flags & NL80211_RRF_PSD)) -+ chan->psd = min_t(s8, rrule1->psd, rrule2->psd); -+ else -+ chan->flags &= ~NL80211_RRF_PSD; -+ - return; - } + ret = ath11k_pcic_init_msi_config(ab); + if (ret) { +diff --git a/drivers/net/wireless/ath/ath11k/pcic.c b/drivers/net/wireless/ath/ath11k/pcic.c +index 063e97815455..82233e30c835 100644 +--- a/drivers/net/wireless/ath/ath11k/pcic.c ++++ b/drivers/net/wireless/ath/ath11k/pcic.c +@@ -115,6 +115,17 @@ static const struct ath11k_msi_config ath11k_msi_config[] = { + }, + .hw_rev = ATH11K_HW_WCN6750_HW10, + }, ++ { ++ .total_vectors = 32, ++ .total_users = 4, ++ .users = (struct ath11k_msi_user[]) { ++ { .name = "MHI", .num_vectors = 3, .base_vector = 0 }, ++ { .name = "CE", .num_vectors = 10, .base_vector = 3 }, ++ { .name = "WAKE", .num_vectors = 1, .base_vector = 13 }, ++ { .name = "DP", .num_vectors = 18, .base_vector = 14 }, ++ }, ++ .hw_rev = ATH11K_HW_QCA206X_HW21, ++ }, + }; -@@ -2577,6 +2591,9 @@ static void handle_channel_custom(struct wiphy *wiphy, - chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; - } + int ath11k_pcic_init_msi_config(struct ath11k_base *ab) +-- +GitLab +From d4d6f1583876b3702603939ac41b98498cf6dd10 Mon Sep 17 00:00:00 2001 +From: Thomas Crider <gloriouseggroll@gmail.com> +Date: Thu, 7 Dec 2023 17:22:18 -0500 +Subject: [PATCH] wifi-fixup -+ if (chan->flags & IEEE80211_CHAN_PSD) -+ chan->psd = reg_rule->psd; -+ - chan->max_power = chan->max_reg_power; - } +--- + drivers/net/wireless/ath/ath11k/core.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) --- +diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c +index 77daa0882..765b91e8d 100644 +--- a/drivers/net/wireless/ath/ath11k/core.c ++++ b/drivers/net/wireless/ath/ath11k/core.c +@@ -420,7 +420,8 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .supports_shadow_regs = true, + .idle_ps = true, + .supports_sta_ps = true, +- .cold_boot_calib = false, ++ .coldboot_cal_mm = false, ++ .coldboot_cal_ftm = false, + .fw_mem_mode = 0, + .num_vdevs = 16 + 1, + .num_peers = 512, +@@ -433,7 +434,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .hal_params = &ath11k_hw_hal_params_qca6390, + .supports_dynamic_smps_6ghz = false, + .alloc_cacheable_memory = false, +- .wakeup_mhi = true, + .supports_rssi_stats = true, + .fw_wmi_diag_event = true, + .current_cc_support = true, +@@ -461,9 +461,6 @@ static const struct ath11k_hw_params ath11k_hw_params[] = { + .target_ce_count = 9, + .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, + .svc_to_ce_map_len = 14, +- .rfkill_pin = 0, +- .rfkill_cfg = 0, +- .rfkill_on_level = 0, + .single_pdev_only = true, + .rxdma1_enable = false, + .num_rxmda_per_pdev = 2, +-- 2.43.0 diff --git a/SOURCES/tkg.patch b/SOURCES/tkg.patch index 3c405c8..f73878f 100644 --- a/SOURCES/tkg.patch +++ b/SOURCES/tkg.patch @@ -20,9 +20,9 @@ index 361ea7ab30ea..0c5cf69b241a 100644 -int sysctl_vfs_cache_pressure __read_mostly = 100; +int sysctl_vfs_cache_pressure __read_mostly = 50; EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); - + __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); --- +-- 2.28.0 @@ -31,7 +31,7 @@ index f788cd61df21..2bfbb4213707 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -20,9 +20,9 @@ - + /* * part of the period that we allow rt tasks to run in us. - * default: 0.95s @@ -39,10 +39,10 @@ index f788cd61df21..2bfbb4213707 100644 */ -int sysctl_sched_rt_runtime = 950000; +int sysctl_sched_rt_runtime = 980000; - + #ifdef CONFIG_SYSCTL static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ; --- +-- 2.28.0 @@ -60,9 +60,9 @@ index 3ae8678e1145..da708eed0f1e 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -92,6 +92,38 @@ config THREAD_INFO_IN_TASK - + menu "General setup" - + +config ZENIFY + bool "A selection of patches from Zen/Liquorix kernel and additional tweaks for a better gaming experience" + default y @@ -98,7 +98,7 @@ index 3ae8678e1145..da708eed0f1e 100644 config BROKEN bool --- +-- 2.28.0 @@ -123,13 +123,13 @@ index e64e59b536d3..bfb55ef7ebbe 100644 @@ -691,6 +691,9 @@ choice config DEFAULT_VEGAS bool "Vegas" if TCP_CONG_VEGAS=y - + + config DEFAULT_YEAH + bool "YeAH" if TCP_CONG_YEAH=y + config DEFAULT_VENO bool "Veno" if TCP_CONG_VENO=y - + @@ -724,6 +727,7 @@ config DEFAULT_TCP_CONG default "htcp" if DEFAULT_HTCP default "hybla" if DEFAULT_HYBLA @@ -138,7 +138,7 @@ index e64e59b536d3..bfb55ef7ebbe 100644 default "westwood" if DEFAULT_WESTWOOD default "veno" if DEFAULT_VENO default "reno" if DEFAULT_RENO --- +-- 2.28.0 @@ -187,8 +187,8 @@ index 74300e337c3c..9277f22c10a7 100644 +#endif (1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG)| (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG); - --- + +-- 2.28.0 @@ -209,7 +209,7 @@ index 84badf00647e..6a922bca9f39 100644 @@ -471,6 +471,9 @@ choice config DEFAULT_SFQ bool "Stochastic Fair Queue" if NET_SCH_SFQ - + + config DEFAULT_CAKE + bool "Common Applications Kept Enhanced" if NET_SCH_CAKE + @@ -223,8 +223,8 @@ index 84badf00647e..6a922bca9f39 100644 + default "cake" if DEFAULT_CAKE default "pfifo_fast" endif - --- + +-- 2.28.0 @@ -253,10 +253,10 @@ index bc05c3588aa3..b0cefe94920d 100644 -#define MAPCOUNT_ELF_CORE_MARGIN (5) -#define DEFAULT_MAX_MAP_COUNT (USHRT_MAX - MAPCOUNT_ELF_CORE_MARGIN) +#define DEFAULT_MAX_MAP_COUNT (262144) - + extern int sysctl_max_map_count; - --- + +-- 2.28.0 @@ -281,10 +281,10 @@ index b0cefe94920d..890165099b07 100644 */ -#define DEFAULT_MAX_MAP_COUNT (262144) +#define DEFAULT_MAX_MAP_COUNT (16777216) - + extern int sysctl_max_map_count; - --- + +-- 2.28.0 @@ -304,7 +304,7 @@ index 4eab3d70e880..79669aa39d79 100644 +++ b/block/elevator.c @@ -561,8 +561,8 @@ } - + /* - * For single queue devices, default to using mq-deadline. If we have multiple - * queues or mq-deadline is not available, default to "none". @@ -316,13 +316,13 @@ index 4eab3d70e880..79669aa39d79 100644 @@ -573,7 +573,7 @@ !blk_mq_is_shared_tags(q->tag_set->flags)) return NULL; - + - return elevator_find_get(q, "mq-deadline"); + return elevator_find_get(q, "bfq"); } - + /* --- +-- 2.28.0 From 3c229f434aca65c4ca61772bc03c3e0370817b92 Mon Sep 17 00:00:00 2001 @@ -343,13 +343,13 @@ index cf2468da68e9..007dea784451 100644 @@ -851,7 +851,7 @@ ._index = i, \ } - + -#define VM_READAHEAD_PAGES (SZ_128K / PAGE_SIZE) +#define VM_READAHEAD_PAGES (SZ_2M / PAGE_SIZE) - + void page_cache_ra_unbounded(struct readahead_control *, unsigned long nr_to_read, unsigned long lookahead_count); --- +-- 2.28.0 @@ -405,13 +405,13 @@ index 36a469150ff9..aee891c9b78a 100644 @@ -3510,6 +3510,8 @@ if (!strcmp(str, "no_hwp")) no_hwp = 1; - + + if (!strcmp(str, "enable")) + no_load = 0; if (!strcmp(str, "force")) force_load = 1; if (!strcmp(str, "hwp_only")) --- +-- 2.28.0 From 379cbab18b5c75c622b93e2c5abdfac141fe9654 Mon Sep 17 00:00:00 2001 @@ -555,7 +555,7 @@ Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com> 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h -index 5f1ae07d724b88..97cda629c9e909 100644 +index e83c4c095..21b8dfa5d 100644 --- a/include/linux/pageblock-flags.h +++ b/include/linux/pageblock-flags.h @@ -48,7 +48,7 @@ extern unsigned int pageblock_order; diff --git a/SOURCES/v10-0002-HID-asus-make-asus_kbd_init-generic-remove-rog_n.patch b/SOURCES/v10-0002-HID-asus-make-asus_kbd_init-generic-remove-rog_n.patch index e4fb261..670480b 100644 --- a/SOURCES/v10-0002-HID-asus-make-asus_kbd_init-generic-remove-rog_n.patch +++ b/SOURCES/v10-0002-HID-asus-make-asus_kbd_init-generic-remove-rog_n.patch @@ -17,19 +17,19 @@ diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 855972a4470f..cdd998a761fe 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c -@@ -1076,9 +1076,9 @@ +@@ -386,9 +386,9 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu return ret; } -static int asus_kbd_init(struct hid_device *hdev) +static int asus_kbd_init(struct hid_device *hdev, u8 report_id) { -- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, +- const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, + const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; int ret; -@@ -1090,9 +1090,10 @@ +@@ -400,9 +400,10 @@ static int asus_kbd_init(struct hid_device *hdev) } static int asus_kbd_get_functions(struct hid_device *hdev, @@ -37,18 +37,18 @@ index 855972a4470f..cdd998a761fe 100644 + unsigned char *kbd_func, + u8 report_id) { -- u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; -+ u8 buf[] = { report_id, 0x05, 0x20, 0x31, 0x00, 0x08 }; +- const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; ++ const u8 buf[] = { report_id, 0x05, 0x20, 0x31, 0x00, 0x08 }; u8 *readbuf; int ret; -@@ -1121,51 +1122,6 @@ +@@ -431,51 +432,6 @@ static int asus_kbd_get_functions(struct hid_device *hdev, return ret; } -static int rog_nkey_led_init(struct hid_device *hdev) -{ -- u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; +- const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; - u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20, - 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; - u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, @@ -94,7 +94,7 @@ index 855972a4470f..cdd998a761fe 100644 static void asus_schedule_work(struct asus_kbd_leds *led) { unsigned long flags; -@@ -1248,17 +1204,27 @@ +@@ -558,17 +514,27 @@ static int asus_kbd_register_leds(struct hid_device *hdev) int ret; if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) { |