|
@@ -1809,30 +1809,45 @@ int hdd_set_p2p_noa(struct net_device *dev, uint8_t *command)
|
|
|
|
|
|
int hdd_set_p2p_opps(struct net_device *dev, uint8_t *command)
|
|
|
{
|
|
|
- hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
|
|
- tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
|
|
|
- tP2pPsConfig NoA;
|
|
|
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
|
|
+ tHalHandle handle = WLAN_HDD_GET_HAL_CTX(adapter);
|
|
|
+ tP2pPsConfig noa;
|
|
|
char *param;
|
|
|
int legacy_ps, opp_ps, ctwindow;
|
|
|
int ret;
|
|
|
|
|
|
param = strnchr(command, strlen(command), ' ');
|
|
|
if (param == NULL) {
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
|
|
|
- "%s: strnchr failed to find delimiter", __func__);
|
|
|
+ hdd_err("strnchr failed to find delimiter");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
param++;
|
|
|
ret = sscanf(param, "%d %d %d", &legacy_ps, &opp_ps, &ctwindow);
|
|
|
if (ret != 3) {
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
|
|
|
- "%s: P2P_SET GO PS: fail to read params, ret=%d",
|
|
|
- __func__, ret);
|
|
|
+ hdd_err("P2P_SET GO PS: fail to read params, ret=%d", ret);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((opp_ps != -1) && (opp_ps != 0) && (opp_ps != 1)) {
|
|
|
+ hdd_err("Invalid opp_ps value:%d", opp_ps);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
|
|
|
- "%s: P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
|
|
|
- __func__, legacy_ps, opp_ps, ctwindow);
|
|
|
+
|
|
|
+ /* P2P spec: 3.3.2 Power Management and discovery:
|
|
|
+ * CTWindow should be at least 10 TU.
|
|
|
+ * P2P spec: Table 27 - CTWindow and OppPS Parameters field format:
|
|
|
+ * CTWindow and OppPS Parameters together is 8 bits.
|
|
|
+ * CTWindow uses 7 bits (0-6, Bit 7 is for OppPS)
|
|
|
+ * 0 indicates that there shall be no CTWindow
|
|
|
+ */
|
|
|
+ if ((ctwindow != -1) && (ctwindow != 0) &&
|
|
|
+ (!((ctwindow >= 10) && (ctwindow <= 127)))) {
|
|
|
+ hdd_err("Invalid CT window value:%d", ctwindow);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ hdd_info("P2P_SET GO PS: legacy_ps=%d opp_ps=%d ctwindow=%d",
|
|
|
+ legacy_ps, opp_ps, ctwindow);
|
|
|
|
|
|
/* PS Selection
|
|
|
* Opportunistic Power Save (1)
|
|
@@ -1845,67 +1860,44 @@ int hdd_set_p2p_opps(struct net_device *dev, uint8_t *command)
|
|
|
* P2P_SET ctwindow 30
|
|
|
* Command Received at hdd_hostapd_ioctl is as below:
|
|
|
* P2P_SET_PS -1 -1 30 (legacy_ps = -1, opp_ps = -1, ctwindow = 30)
|
|
|
+ *
|
|
|
+ * e.g., 1: P2P_SET_PS 1 1 30
|
|
|
+ * Driver sets the Opps and CTwindow as 30 and send it to FW.
|
|
|
+ * e.g., 2: P2P_SET_PS 1 -1 15
|
|
|
+ * Driver caches the CTwindow value but not send the command to FW.
|
|
|
+ * e.g., 3: P2P_SET_PS 1 1 -1
|
|
|
+ * Driver sends the command to FW with Opps enabled and CT window as
|
|
|
+ * 15 (last cached CTWindow value).
|
|
|
+ * (or) : P2P_SET_PS 1 1 20
|
|
|
+ * Driver sends the command to FW with opps enabled and CT window
|
|
|
+ * as 20.
|
|
|
+ *
|
|
|
+ * legacy_ps param remains unused until required in the future.
|
|
|
*/
|
|
|
- if (ctwindow != -1) {
|
|
|
-
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
|
|
|
- "Opportunistic Power Save is %s",
|
|
|
- (true == pAdapter->ops) ? "Enable" : "Disable");
|
|
|
-
|
|
|
- if (ctwindow != pAdapter->ctw) {
|
|
|
- pAdapter->ctw = ctwindow;
|
|
|
-
|
|
|
- if (pAdapter->ops) {
|
|
|
- NoA.opp_ps = pAdapter->ops;
|
|
|
- NoA.ctWindow = pAdapter->ctw;
|
|
|
- NoA.duration = 0;
|
|
|
- NoA.single_noa_duration = 0;
|
|
|
- NoA.interval = 0;
|
|
|
- NoA.count = 0;
|
|
|
- NoA.psSelection =
|
|
|
- P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
|
|
|
- NoA.sessionid = pAdapter->sessionId;
|
|
|
-
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD,
|
|
|
- QDF_TRACE_LEVEL_INFO,
|
|
|
- "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
|
|
|
- "interval %d count %d single noa duration %d "
|
|
|
- "PsSelection %x", __func__,
|
|
|
- NoA.opp_ps, NoA.ctWindow,
|
|
|
- NoA.duration, NoA.interval, NoA.count,
|
|
|
- NoA.single_noa_duration,
|
|
|
- NoA.psSelection);
|
|
|
-
|
|
|
- sme_p2p_set_ps(hHal, &NoA);
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ if (ctwindow != -1)
|
|
|
+ adapter->ctw = ctwindow;
|
|
|
|
|
|
+ /* Send command to FW when OppPS is either enabled(1)/disbaled(0) */
|
|
|
if (opp_ps != -1) {
|
|
|
- pAdapter->ops = opp_ps;
|
|
|
-
|
|
|
- if ((opp_ps != -1) && (pAdapter->ctw)) {
|
|
|
- NoA.opp_ps = opp_ps;
|
|
|
- NoA.ctWindow = pAdapter->ctw;
|
|
|
- NoA.duration = 0;
|
|
|
- NoA.single_noa_duration = 0;
|
|
|
- NoA.interval = 0;
|
|
|
- NoA.count = 0;
|
|
|
- NoA.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
|
|
|
- NoA.sessionid = pAdapter->sessionId;
|
|
|
-
|
|
|
- QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
|
|
|
- "%s: P2P_PS_ATTR:oppPS %d ctWindow %d duration %d "
|
|
|
- "interval %d count %d single noa duration %d "
|
|
|
- "PsSelection %x", __func__, NoA.opp_ps,
|
|
|
- NoA.ctWindow, NoA.duration, NoA.interval,
|
|
|
- NoA.count, NoA.single_noa_duration,
|
|
|
- NoA.psSelection);
|
|
|
-
|
|
|
- sme_p2p_set_ps(hHal, &NoA);
|
|
|
- }
|
|
|
+ adapter->ops = opp_ps;
|
|
|
+ noa.opp_ps = adapter->ops;
|
|
|
+ noa.ctWindow = adapter->ctw;
|
|
|
+ noa.duration = 0;
|
|
|
+ noa.single_noa_duration = 0;
|
|
|
+ noa.interval = 0;
|
|
|
+ noa.count = 0;
|
|
|
+ noa.psSelection = P2P_POWER_SAVE_TYPE_OPPORTUNISTIC;
|
|
|
+ noa.sessionid = adapter->sessionId;
|
|
|
+
|
|
|
+ hdd_debug("P2P_PS_ATTR: oppPS %d ctWindow %d duration %d interval %d count %d single noa duration %d PsSelection %x",
|
|
|
+ noa.opp_ps, noa.ctWindow,
|
|
|
+ noa.duration, noa.interval, noa.count,
|
|
|
+ noa.single_noa_duration,
|
|
|
+ noa.psSelection);
|
|
|
+
|
|
|
+ sme_p2p_set_ps(handle, &noa);
|
|
|
}
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|