Browse Source

qcacld-3.0: Fix DHCP indication to FW feature for broadcast exchange

Use "client mac address" in bootp protocol to get
station id to handle scenarion when
DHCP exchanges(discover/offer/request/ack) happens
with broadcast address as destination address.

Change-Id: Ie233b2ffed1533f0a45fded199bb09649e48b4dd
CRs-Fixed: 2506023
Nirav Shah 5 years ago
parent
commit
a7fa192dbd

+ 7 - 11
core/hdd/inc/wlan_hdd_softap_tx_rx.h

@@ -244,18 +244,16 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
 		      uint8_t sta_id, uint16_t type);
 
 /**
- * hdd_inspect_dhcp_packet() -  Inspect DHCP packet
+ * hdd_softap_inspect_dhcp_packet() -  Inspect DHCP packet
  * @adapter: pointer to hdd adapter
- * @sta_id: peer station ID
  * @skb: pointer to OS packet (sk_buff)
  * @dir: direction
  *
  * Return: error number
  */
-int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
-			    uint8_t sta_id,
-			    struct sk_buff *skb,
-			    enum qdf_proto_dir dir);
+int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
+				   struct sk_buff *skb,
+				   enum qdf_proto_dir dir);
 #else
 static inline
 int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
@@ -265,14 +263,12 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
 }
 
 static inline
-int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
-			    uint8_t sta_id,
-			    struct sk_buff *skb,
-			    enum qdf_proto_dir dir)
+int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
+				   struct sk_buff *skb,
+				   enum qdf_proto_dir dir)
 {
 	return 0;
 }
-
 #endif
 
 #endif /* end #if !defined(WLAN_HDD_SOFTAP_TX_RX_H) */

+ 1 - 7
core/hdd/src/wlan_hdd_ipa.c

@@ -406,7 +406,6 @@ void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t nbuf, qdf_netdev_t dev)
 	struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
 	int result;
 	unsigned int cpu_index;
-	uint8_t sta_id;
 	uint32_t enabled;
 
 	if (hdd_validate_adapter(adapter)) {
@@ -422,12 +421,7 @@ void hdd_ipa_send_nbuf_to_network(qdf_nbuf_t nbuf, qdf_netdev_t dev)
 	if ((adapter->device_mode == QDF_SAP_MODE) &&
 	    (qdf_nbuf_is_ipv4_dhcp_pkt(nbuf) == true)) {
 		/* Send DHCP Indication to FW */
-		struct qdf_mac_addr *src_mac =
-			(struct qdf_mac_addr *)(nbuf->data +
-			QDF_NBUF_SRC_MAC_OFFSET);
-		if (QDF_STATUS_SUCCESS ==
-			hdd_softap_get_sta_id(adapter, src_mac, &sta_id))
-			hdd_inspect_dhcp_packet(adapter, sta_id, nbuf, QDF_RX);
+		hdd_softap_inspect_dhcp_packet(adapter, nbuf, QDF_RX);
 	}
 
 	qdf_dp_trace_set_track(nbuf, QDF_RX);

+ 28 - 29
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -280,6 +280,8 @@ int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
 	return 0;
 }
 
+#define DHCP_CLIENT_MAC_ADDR_OFFSET 0x46
+
 /**
  * hdd_softap_notify_dhcp_ind() - Notify SAP for DHCP indication for tx desc
  * @context: pointer to HDD context
@@ -303,32 +305,24 @@ static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
 		return;
 	}
 
-	dest_mac_addr = (struct qdf_mac_addr *)netbuf->data;
+	dest_mac_addr = (struct qdf_mac_addr *)(netbuf->data +
+						DHCP_CLIENT_MAC_ADDR_OFFSET);
 
-	if (QDF_NBUF_CB_GET_IS_BCAST(netbuf) ||
-	    QDF_NBUF_CB_GET_IS_MCAST(netbuf)) {
-		/* The BC/MC station ID is assigned during BSS
-		 * starting phase.  SAP will return the station ID
-		 * used for BC/MC traffic.
-		 */
-		sta_id = hdd_ap_ctx->broadcast_sta_id;
-	} else {
-		if (QDF_STATUS_SUCCESS !=
+	if (QDF_STATUS_SUCCESS !=
 		    hdd_softap_get_sta_id(adapter,
 					  dest_mac_addr, &sta_id)) {
-			QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
-				  QDF_TRACE_LEVEL_INFO_HIGH,
-				  "%s: Failed to find right station", __func__);
-			return;
-		}
+		QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
+			  QDF_TRACE_LEVEL_INFO_HIGH,
+			  "%s: Failed to find right station", __func__);
+		return;
 	}
+
 	hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND);
 }
 
 /**
- * hdd_inspect_dhcp_packet() - Inspect DHCP packet
+ * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
  * @adapter: pointer to hdd adapter
- * @sta_id: peer station ID
  * @skb: pointer to OS packet (sk_buff)
  * @dir: direction
  *
@@ -353,19 +347,17 @@ static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
  *
  * Return: error number
  */
-int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
-			    uint8_t sta_id,
-			    struct sk_buff *skb,
-			    enum qdf_proto_dir dir)
+int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
+				   struct sk_buff *skb,
+				   enum qdf_proto_dir dir)
 {
 	enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
 	struct hdd_station_info *hdd_sta_info;
+	uint8_t sta_id;
 	int errno = 0;
+	struct qdf_mac_addr *src_mac;
+	QDF_STATUS status;
 
-	if (sta_id >= WLAN_MAX_STA_COUNT) {
-		hdd_err("Invalid sta id: %d", sta_id);
-		return -EINVAL;
-	}
 
 	if (((adapter->device_mode == QDF_SAP_MODE) ||
 	     (adapter->device_mode == QDF_P2P_GO_MODE)) &&
@@ -373,6 +365,14 @@ int hdd_inspect_dhcp_packet(struct hdd_adapter *adapter,
 				QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
 	     (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) {
 
+		src_mac = (struct qdf_mac_addr *)(skb->data +
+						  DHCP_CLIENT_MAC_ADDR_OFFSET);
+		status = hdd_softap_get_sta_id(adapter, src_mac, &sta_id);
+		if (status != QDF_STATUS_SUCCESS) {
+			hdd_err("invalid station id");
+			return -EINVAL;
+		}
+
 		subtype = qdf_nbuf_get_dhcp_subtype(skb);
 		hdd_sta_info = &adapter->sta_info[sta_id];
 
@@ -613,8 +613,7 @@ static void __hdd_softap_hard_start_xmit(struct sk_buff *skb,
 
 	QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0;
 
-	if (sta_id != ap_ctx->broadcast_sta_id)
-		hdd_inspect_dhcp_packet(adapter, sta_id, skb, QDF_TX);
+	hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_TX);
 
 	hdd_event_eapol_log(skb, QDF_TX);
 	QDF_NBUF_CB_TX_PACKET_TRACK(skb) = QDF_NBUF_TX_PKT_DATA_TRACK;
@@ -951,8 +950,8 @@ QDF_STATUS hdd_softap_rx_packet_cbk(void *adapter_context, qdf_nbuf_t rx_buf)
 				adapter->sta_info[sta_id].rx_bytes += skb->len;
 				adapter->sta_info[sta_id].last_tx_rx_ts =
 					qdf_system_ticks();
-				hdd_inspect_dhcp_packet(adapter, sta_id,
-							skb, QDF_RX);
+				hdd_softap_inspect_dhcp_packet(adapter, skb,
+							       QDF_RX);
 			}
 		}