mwifiex: separate TxPD processing routine for AP
authorAvinash Patil <patila@marvell.com>
Tue, 11 Sep 2012 01:30:49 +0000 (18:30 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 11 Sep 2012 19:31:58 +0000 (15:31 -0400)
This patch adds separate tx packet descriptor routine for AP
interface. This function fills bss_type, bss_num, wmm packet
delay information etc for TxPD going on AP interface.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/txrx.c
drivers/net/wireless/mwifiex/uap_txrx.c

index bb753903259e6ee059ef20507fccb4132ea37f68..12ceea47b4b447e7986a93f9d672e1ea47d01f4a 100644 (file)
@@ -812,6 +812,7 @@ struct mwifiex_sta_node *
 mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
 void mwifiex_delete_all_station_list(struct mwifiex_private *priv);
 void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
+void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb);
 int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
 int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
                            struct mwifiex_scan_cmd_config *scan_cfg);
index 985073d0df1a17ea9429c82bd0632887182fbec4..2af263992e83a23ff30bb6558f85204105bb4180 100644 (file)
@@ -75,7 +75,11 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
        u8 *head_ptr;
        struct txpd *local_tx_pd = NULL;
 
-       head_ptr = mwifiex_process_sta_txpd(priv, skb);
+       if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
+               head_ptr = mwifiex_process_uap_txpd(priv, skb);
+       else
+               head_ptr = mwifiex_process_sta_txpd(priv, skb);
+
        if (head_ptr) {
                if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
                        local_tx_pd =
index 6d814f0f07f2b4b7d3229e74fc3c3832840c52e9..df17d08715fe58836a4ed349cb4ea54adabaebe1 100644 (file)
@@ -253,3 +253,73 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
 
        return ret;
 }
+
+/*
+ * This function fills the TxPD for AP tx packets.
+ *
+ * The Tx buffer received by this function should already have the
+ * header space allocated for TxPD.
+ *
+ * This function inserts the TxPD in between interface header and actual
+ * data and adjusts the buffer pointers accordingly.
+ *
+ * The following TxPD fields are set by this function, as required -
+ *      - BSS number
+ *      - Tx packet length and offset
+ *      - Priority
+ *      - Packet delay
+ *      - Priority specific Tx control
+ *      - Flags
+ */
+void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
+                              struct sk_buff *skb)
+{
+       struct mwifiex_adapter *adapter = priv->adapter;
+       struct uap_txpd *txpd;
+       struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+       int pad, len;
+
+       if (!skb->len) {
+               dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
+               tx_info->status_code = -1;
+               return skb->data;
+       }
+
+       /* If skb->data is not aligned, add padding */
+       pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
+
+       len = sizeof(*txpd) + pad;
+
+       BUG_ON(skb_headroom(skb) < len + INTF_HEADER_LEN);
+
+       skb_push(skb, len);
+
+       txpd = (struct uap_txpd *)skb->data;
+       memset(txpd, 0, sizeof(*txpd));
+       txpd->bss_num = priv->bss_num;
+       txpd->bss_type = priv->bss_type;
+       txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len));
+
+       txpd->priority = (u8)skb->priority;
+       txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+
+       if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
+               /*
+                * Set the priority specific tx_control field, setting of 0 will
+                * cause the default value to be used later in this function.
+                */
+               txpd->tx_control =
+                   cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
+
+       /* Offset of actual data */
+       txpd->tx_pkt_offset = cpu_to_le16(len);
+
+       /* make space for INTF_HEADER_LEN */
+       skb_push(skb, INTF_HEADER_LEN);
+
+       if (!txpd->tx_control)
+               /* TxCtrl set by user or default */
+               txpd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+
+       return skb->data;
+}