Re: [External] Re: [PATCH 1/2] platorm/x86: thinkpad_acpi: sysfs interface to reduce wlan tx power

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

>-----Original Message-----
>From: Barnabás Pőcze <pobrn@xxxxxxxxxxxxxx>
>Sent: Sunday, February 14, 2021 5:48 AM
>To: Nitin Joshi1 <njoshi1@xxxxxxxxxx>
>Cc: Nitin Joshi <nitjoshi@xxxxxxxxx>; hdegoede@xxxxxxxxxx; ibm-acpi-
>devel@xxxxxxxxxxxxxxxxxxxxx; platform-driver-x86@xxxxxxxxxxxxxxx; Mark RH
>Pearson <markpearson@xxxxxxxxxx>
>Subject: RE: [External] Re: [PATCH 1/2] platorm/x86: thinkpad_acpi: sysfs
>interface to reduce wlan tx power
>
>Hi
>
>
>2021. február 12., péntek 11:40 keltezéssel, Nitin Joshi1
><njoshi1@xxxxxxxxxx> írta:
>
>> [...]
>> >>
>>
>>+/**************************************************************
>*
>> >*****
>> >> +*****
>> >> + * DPRC(Dynamic Power Reduction Control) subdriver, for the Lenovo
>> >> +WWAN
>> >> + * and WLAN feature.
>> >> + */
>> >> +#define DPRC_GET_WLAN_STATE             0x20000
>> >> +#define DPRC_SET_WLAN_POWER_REDUCE      0x00030010
>> >> +#define DPRC_SET_WLAN_POWER_FULL        0x00030100
>> >> +static int has_wlantxreduce;
>> >
>> >I think `bool` would be better.
>>
>> Ack . I will modify  it in next version.
>>
>> >
>> >
>> >> +static int wlan_txreduce;
>> >> +
>> >> +static int dprc_command(int command, int *output) {
>> >> +	acpi_handle dprc_handle;
>> >> +
>> >> +	if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "DPRC",
>> >&dprc_handle))) {
>> >> +		/* Platform doesn't support DPRC */
>> >> +		return -ENODEV;
>> >> +	}
>> >> +
>> >> +	if (!acpi_evalf(dprc_handle, output, NULL, "dd", command))
>> >> +		return -EIO;
>> >> +
>> >> +	/*
>> >> +	 * METHOD_ERR gets returned on devices where few commands are
>> >not supported
>> >> +	 * for example WLAN power reduce command is not supported on
>> >some devices.
>> >> +	 */
>> >> +	if (*output & METHOD_ERR)
>> >> +		return -ENODEV;
>> >> +
>> >> +	return 0;
>> >> +}
>> >> +
>> >> +static int get_wlan_state(int *has_wlantxreduce, int
>> >> +*wlan_txreduce) {
>> >> +	int output, err;
>> >> +
>> >> +	/* Get current WLAN Power Transmission state */
>> >> +	err = dprc_command(DPRC_GET_WLAN_STATE, &output);
>> >> +	if (err)
>> >> +		return err;
>> >> +
>> >> +	if (output & BIT(4))
>> >
>> >I believe it'd be preferable to name `BIT(4)` and `BIT(8)`. E.g.:
>> >
>> >  #define DPRC_GET_WLAN_STATE_RES_REDUCED BIT(4)
>> >  #define DPRC_GET_WLAN_STATE_RES_FULL    BIT(8)
>> >
>> >(or any name you like).
>> >
>> Ack . I will modify  it in next version.
>>
>> >
>> >> +		*wlan_txreduce = 1;
>> >> +	else if (output & BIT(8))
>> >> +		*wlan_txreduce = 0;
>> >> +	else
>> >> +		*wlan_txreduce = -1;
>> >
>> >Can you elaborate what -1 means here? Unknown/not
>> >available/invalid/error?
>>
>> -1 means "error" .
>> I had found that when "DPRC" method return METHOD_ERR i.e BIT(31) as 0
>then it goes to this condition.
>> So , therefore I had added METHOD_ERR check in dprc_command() and
>now , this doesnot goes here.
>> But, I have still kept it here , just in case if any other error occurred .
>> Can you please suggest , if I should remove it (i.e remove *wlan_txreduce = -
>1; )?  as I still think, there is no harm keeping like this.
>>
>
>If `dprc_command()` handles all error cases (i.e. it is not possible that
>`dprc_command()` returns 0, but there was an error) - which seems to be the
>case - then I think in that branch you should return -ENODATA and not touch
>`wlan_txreduce`. Because if that branch runs, then there was no error, but the
>state cannot be determined, so I think -ENODATA is an appropriate error code.
Ack . Noted, I will check it
>
>
>> >
>> >
>> >> +
>> >> +	*has_wlantxreduce = 1;
>> >
>> >Is it necessary for the getter to set this? Couldn't it be set in
>> >`tpacpi_dprc_init()` once during initialization?
>>
>> Actually, yes we can keep it in init function also but I have not kept
>> it because of other patch (PATCH 2/2) which I had sent . patch 1 (this
>> patch) and patch 2 ( other patch which create sysfs of WWWAN Antenna
>type) both uses "DPRC" method . So , we will need a flag to create sysfs
>because few system will not have this "wlan tx reduce"
>> even if it has "DPRC" method exists and vice versa .
>> So , in this case, we need to explicitly check whether it require to create
>corresponding sysfs  or not.
>>
>
>I was thinking of something like the following:
>
>  static int tpacpi_dprc_init(...) {
>    ...
>    int err = get_wlan_state(&reduced);
>    if (err && err != -ENODEV)
>      return err;
>    else if (!err)
>      has_wlantxreduce = true;
>
>    err = get_wwan_antenna(&antenna);
>    if (err && err != -ENODEV)
>      return err;
>    else if (!err)
>      has_antennatype = true; /* as I've commented on the second patch, this
>                                 variable is probably not needed */
>    ...
>
Ack . I will check it

>If I'm not mistaken this is enough not to need the second argument in either
>`get_wlan_state()` or `get_wwan_antenna()`. Note, that if both functions may
>return -ENODATA, you might also want to add `err != -ENODATA` to the
>conditions.
>
Ack . yes.

>
>> >
>> >
>> >> +	return 0;
>> >> +}
>> >> +
>> >> +/* sysfs wlan entry */
>> >> +static ssize_t wlan_tx_strength_reduce_show(struct device *dev,
>> >> +				struct device_attribute *attr,
>> >> +				char *buf)
>> >
>> >Please align the arguments:
>> >
>> >  ..._show(struct device *dev,
>> >           struct device_attribute ...
>> >           ...);
>> >
>> Ack . I will modify  it in next version.
>> Also , I will correct it in my other patch(PATCH 2/2) also.
>>
>> >
>> >> +{
>> >> +	int err;
>> >> +
>> >> +	err = get_wlan_state(&has_wlantxreduce, &wlan_txreduce);
>> >> +	if (err)
>> >> +		return err;
>> >> +
>> >
>> >Wouldn't it be better to return -ENODATA or something similar when
>> >`wlan_txreduce` == -1?
>>
>> Ack . I think EOPNOTSUPP will be better ? reason is that "DPRC" method is
>available but there is error . So , its more likely that command is not
>supported.
>> However, I will modify it after I get feedback about my previous comment.
>>
>
>I think the place to determine whether the operation is supported or not is in
>`tpacpi_dprc_init()` and the attribute should not be created if it's not
>supported.
Ack . I will check it and send next patch version soon.
>
>
>> >
>> >
>> >> +	return sysfs_emit(buf, "%d\n", wlan_txreduce); }
>> >> +
>> >> +static ssize_t wlan_tx_strength_reduce_store(struct device *dev,
>> >> +				struct device_attribute *attr,
>> >> +				const char *buf, size_t count)
>> >
>> >Same here.
>> >
>> Ack . I will modify  it in next version.
>> >
>> >> +{
>> >> +	int output, err;
>> >> +	unsigned long t;
>> >> +
>> >> +	if (parse_strtoul(buf, 1, &t))
>> >
>> >Maybe `kstrtobool`?
>>
>> Thank you for your suggestion.
>> I can use 'kstrtobool' and will modify on my next version.
>>
>> >
>> >
>> >> +		return -EINVAL;
>> >> +
>> >> +	tpacpi_disclose_usertask(attr->attr.name,
>> >> +				"WLAN tx strength reduced %lu\n", t);
>> >> +
>> >> +	switch (t) {
>> >> +	case 0:
>> >> +		err = dprc_command(DPRC_SET_WLAN_POWER_FULL,
>> >&output);
>> >> +		break;
>> >> +	case 1:
>> >> +		err = dprc_command(DPRC_SET_WLAN_POWER_REDUCE,
>> >&output);
>> >> +		break;
>> >> +	default:
>> >> +		err = -EINVAL;
>> >> +		dev_err(&tpacpi_pdev->dev, "Unknown operating mode.
>> >Ignoring\n");
>> >> +		break;
>> >> +	}
>> >> +
>> >
>> >If I'm not mistaken, `err` is never returned, so the write() will
>> >always seem to succeed.
>>
>> Yes , its correct . I will use 'kstrtobool' and will drop this : "err = -EINVAL;"
>> Is it Ok ?
>>
>
>If you use `kstrtobool()`, you can even drop the entire switch statement.
Ack . yes , I think so too.
>
>
>> >
>> >
>> >> +	sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
>> >"wlan_tx_strength_reduce");
>> >> +	return count;
>> >> +}
>> >> +static DEVICE_ATTR_RW(wlan_tx_strength_reduce);
>> >> +
>> >> +static int tpacpi_dprc_init(struct ibm_init_struct *iibm) {
>> >> +	int wlantx_err, err;
>> >> +
>> >> +	wlantx_err = get_wlan_state(&has_wlantxreduce, &wlan_txreduce);
>> >> +	/*
>> >> +	 * If support isn't available (ENODEV) for both devices then quit, but
>> >> +	 * don't return an error.
>> >> +	 */
>> >> +	if (wlantx_err == -ENODEV)
>> >> +		return 0;
>> >> +	/* Otherwise, if there was an error return it */
>> >> +	if (wlantx_err && (wlantx_err != -ENODEV))
>> >> +		return wlantx_err;
>> >> +
>> >> +	if (has_wlantxreduce) {
>> >> +		err = sysfs_create_file(&tpacpi_pdev->dev.kobj,
>> >> +				&dev_attr_wlan_tx_strength_reduce.attr);
>> >
>> >I believe `device_create_file()` would be better.
>> >
>> Since, file will be created in /sys/ directory , hence I think its better to use
>sysfs_create_file.
>> Also, by checking in this  file, it looks like sysfs_create_file will be more
>reasonable to do .
>>
>> Please let me know, if its Ok to continue using sysfs_create_file or
>> you still feel. we need to use
>> device_create_file()  also feel free to correct me, if I am wrong.
>>
>
>There's not much difference, so sysfs_{create,remove}_file() would work just
>as fine here. The reason why I believe `device_{create,remove}_file()` is
>possibly preferable is that you don't need to reference the kobj and the
>attribute when calling it, and you're adding an attribute to a *device* (not any
>kobj), so device_*() functions are a better fit syntactically in my opinion. But in
>the end, both will achieve the same effect, so you are free to choose
>whichever you like.
Ack . Noted.
I would like to keep sysfs_{ create,remove}_file() now.

I will recheck code, incorporate comments and send next patch version soon.

>
>> >
>> >> +		if (err)
>> >> +			return err;
>> >> +	}
>> >> +	return 0;
>> >> +}
>> >> +
>> >> +static void dprc_exit(void)
>> >> +{
>> >> +	if (has_wlantxreduce)
>> >> +		sysfs_remove_file(&tpacpi_pdev->dev.kobj,
>> >> +&dev_attr_wlan_tx_strength_reduce.attr);
>> >
>> >And similarly, `device_remove_file()`.
>>
>> Same comment as above . I feel, sysfs_remove_file is more reasonable to do.
>> [...]
>
>
>Regards,
>Barnabás Pőcze

Thanks & Regards,
Nitin Joshi

_______________________________________________
ibm-acpi-devel mailing list
ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel




[Index of Archives]     [Linux ACPI]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Photo]     [Yosemite Photos]     [Yosemite Advice]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux