Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd3b7a96 authored by Madan Mohan Koyyalamudi's avatar Madan Mohan Koyyalamudi
Browse files

wlan: Place DHCP packets in VOICE queue on low resource condition.

The DHCP packets are transmitted in best effort access category
queues. When the queue is full, the dhcp renewel packets are
dropped resulting connection failure.
To avoid this, the DHCP packets are placed in VOICE queue if
best effort access category queue hits the low resource condition.

Change-Id: I093aa57e4f51cb29055bfc5453df8c8cd06f85d2
CRs-fixed: 534950
parent 1c2d123f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -622,6 +622,9 @@ typedef struct {
   /**Track whether OS TX queue has been disabled.*/
   v_BOOL_t txSuspended[NUM_TX_QUEUES];

   /**Track whether 3/4th of resources are used */
   v_BOOL_t vosLowResource;

   /** Track QoS status of station */
   v_BOOL_t isQosEnabled;

@@ -844,6 +847,9 @@ struct hdd_adapter_s
   /**Track whether VOS is in a low resource state*/
   v_BOOL_t isVosOutOfResource;

   /**Track whether 3/4th of resources are used */
   v_BOOL_t isVosLowResource;
  
   /**Track whether OS TX queue has been disabled.*/
   v_BOOL_t isTxSuspended[NUM_TX_QUEUES];

+18 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ static VOS_STATUS hdd_softap_flush_tx_queues( hdd_adapter_t *pAdapter )
         pAdapter->aStaInfo[STAId].txSuspended[i] = VOS_FALSE;
         spin_unlock_bh(&pAdapter->aStaInfo[STAId].wmm_tx_queue[i].lock);
      }
      pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
   }

   spin_unlock_bh( &pAdapter->staInfo_lock );
@@ -309,6 +310,22 @@ int hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
       netif_stop_subqueue(dev, skb_get_queue_mapping(skb));
       txSuspended = VOS_TRUE;
    }

    /* If 3/4th of the max queue size is used then enable the flag.
     * This flag indicates to place the DHCP packets in VOICE AC queue.*/
   if (WLANTL_AC_BE == ac)
   {
      if (pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
      {
          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                     "%s: TX queue for Best Effort AC is 3/4th full", __func__);
          pAdapter->aStaInfo[STAId].vosLowResource = VOS_TRUE;
      }
      else
      {
          pAdapter->aStaInfo[STAId].vosLowResource = VOS_FALSE;
      }
   }
   spin_unlock(&pAdapter->aStaInfo[STAId].wmm_tx_queue[ac].lock);

   if (VOS_TRUE == txSuspended)
@@ -564,6 +581,7 @@ VOS_STATUS hdd_softap_init_tx_rx( hdd_adapter_t *pAdapter )
   hdd_context_t *pHddCtx = NULL;

   pAdapter->isVosOutOfResource = VOS_FALSE;
   pAdapter->isVosLowResource = VOS_FALSE;

   vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));

+19 −0
Original line number Diff line number Diff line
@@ -181,6 +181,8 @@ static VOS_STATUS hdd_flush_tx_queues( hdd_adapter_t *pAdapter )
   skb_list_node_t *pktNode = NULL;
   struct sk_buff *skb = NULL;

   pAdapter->isVosLowResource = VOS_FALSE;

   while (++i != NUM_TX_QUEUES) 
   {
      //Free up any packets in the Tx queue
@@ -630,6 +632,22 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
      txSuspended = VOS_TRUE;
   }

   /* If 3/4th of the max queue size is used then enable the flag.
    * This flag indicates to place the DHCP packets in VOICE AC queue.*/
   if (WLANTL_AC_BE == ac)
   {
      if (pAdapter->wmm_tx_queue[ac].count >= HDD_TX_QUEUE_LOW_WATER_MARK)
      {
          VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
                     "%s: Best Effort AC Tx queue is 3/4th full", __func__);
          pAdapter->isVosLowResource = VOS_TRUE;
      }
      else
      {
          pAdapter->isVosLowResource = VOS_FALSE;
      }
   }

   spin_unlock(&pAdapter->wmm_tx_queue[ac].lock);
   if (VOS_TRUE == txSuspended)
   {
@@ -784,6 +802,7 @@ VOS_STATUS hdd_init_tx_rx( hdd_adapter_t *pAdapter )
   v_SINT_t i = -1;

   pAdapter->isVosOutOfResource = VOS_FALSE;
   pAdapter->isVosLowResource = VOS_FALSE;

   //vos_mem_zero(&pAdapter->stats, sizeof(struct net_device_stats));
   //Will be zeroed out during alloc
+37 −0
Original line number Diff line number Diff line
@@ -102,6 +102,10 @@

#define WLAN_HDD_MAX_DSCP 0x3f

// DHCP Port number
#define DHCP_SOURCE_PORT 0x4400
#define DHCP_DESTINATION_PORT 0x4300

static sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1];

const v_U8_t hddWmmUpToAcMap[] = {
@@ -1586,6 +1590,23 @@ VOS_STATUS hdd_wmm_adapter_close ( hdd_adapter_t* pAdapter )
   return VOS_STATUS_SUCCESS;
}

/**============================================================================
  @brief is_dhcp_packet() - Function which will check OS packet for
  DHCP packet

  @param skb      : [in]  pointer to OS packet (sk_buff)
  @return         : VOS_TRUE if the OS packet is DHCP packet
                  : otherwise VOS_FALSE
  ===========================================================================*/
v_BOOL_t is_dhcp_packet(struct sk_buff *skb)
{
   if (*((u16*)((u8*)skb->data+34)) == DHCP_SOURCE_PORT ||
       *((u16*)((u8*)skb->data+34)) == DHCP_DESTINATION_PORT)
      return VOS_TRUE;

   return VOS_FALSE;
}

/**============================================================================
  @brief hdd_wmm_classify_pkt() - Function which will classify an OS packet
  into a WMM AC based on either 802.1Q or DSCP
@@ -1816,6 +1837,14 @@ v_U16_t hdd_hostapd_select_queue(struct net_device * dev, struct sk_buff *skb)
   {
      /* Get the user priority from IP header & corresponding AC */
      hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
      //If 3/4th of Tx queue is used then place the DHCP packet in VOICE AC queue
      if (pAdapter->aStaInfo[STAId].vosLowResource && is_dhcp_packet(skb))
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                    "%s: Making priority of DHCP packet as VOICE", __func__);
         up = SME_QOS_WMM_UP_VO;
         ac = hddWmmUpToAcMap[up];
      }
   }
   *pSTAId = STAId;

@@ -1868,6 +1897,14 @@ v_U16_t hdd_wmm_select_queue(struct net_device * dev, struct sk_buff *skb)
   if( hdd_wmm_is_active(pAdapter) ) {
      /* Get the user priority from IP header & corresponding AC */
      hdd_wmm_classify_pkt (pAdapter, skb, &ac, &up);
      //If 3/4th of BE AC Tx queue is full, then place the DHCP packet in VOICE AC queue
      if (pAdapter->isVosLowResource && is_dhcp_packet(skb))
      {
         VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_WARN,
                   "%s: Making priority of DHCP packet as VOICE", __func__);
         up = SME_QOS_WMM_UP_VO;
         ac = hddWmmUpToAcMap[up];
      }
   }
done:
   skb->priority = up;