From: Ivo van Doorn Date: Thu, 24 Jan 2008 09:56:25 +0000 (-0800) Subject: rt2x00: Add skb descriptor X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=08992f7fb139c7dbaf593402312ee5a055352f05;p=openwrt%2Fstaging%2Fblogic.git rt2x00: Add skb descriptor Use the skb->cb field to add a frame description that can be used to transfer information passed each rt2x00 layer. This reduces the required arguments for rt2x00lib_write_tx_desc(). Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville Signed-off-by: David S. Miller --- diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 15ab4b20d067..2a38388a79e1 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1686,8 +1686,8 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct rt2x00_dev *rt2x00dev = hw->priv; struct usb_device *usb_dev = interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); - struct data_ring *ring = - rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); + struct skb_desc *desc; + struct data_ring *ring; struct data_entry *beacon; struct data_entry *guardian; int pipe = usb_sndbulkpipe(usb_dev, 1); @@ -1699,6 +1699,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); /* * Obtain 2 entries, one for the guardian byte, @@ -1709,23 +1710,34 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, beacon = rt2x00_get_data_entry(ring); /* - * First we create the beacon. + * Add the descriptor in front of the skb. */ skb_push(skb, ring->desc_size); memset(skb->data, 0, ring->desc_size); - rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data, - (struct ieee80211_hdr *)(skb->data + - ring->desc_size), - skb->len - ring->desc_size, control); + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = beacon; + + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); + /* + * USB devices cannot blindly pass the skb->len as the + * length of the data to usb_fill_bulk_urb. Pass the skb + * to the driver to determine what the length should be. + */ length = rt2500usb_get_tx_data_len(rt2x00dev, skb); usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, skb->data, length, rt2500usb_beacondone, beacon); - beacon->skb = skb; - /* * Second we need to create the guardian byte. * We only need a single byte, so lets recycle diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b2283cebfab9..31e48c25a692 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -901,9 +901,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, * TX descriptor initializer */ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, - __le32 *txd, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, + struct sk_buff *skb, struct ieee80211_tx_control *control); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e8949785c662..4f32ee8f4cb7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -573,36 +573,26 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); * TX descriptor initializer */ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, - __le32 *txd, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, + struct sk_buff *skb, struct ieee80211_tx_control *control) { struct txdata_entry_desc desc; - struct data_ring *ring; + struct skb_desc *skbdesc = get_skb_desc(skb); + struct ieee80211_hdr *ieee80211hdr = skbdesc->data; + __le32 *txd = skbdesc->desc; int tx_rate; int bitrate; + int length; int duration; int residual; u16 frame_control; u16 seq_ctrl; - /* - * Make sure the descriptor is properly cleared. - */ - memset(&desc, 0x00, sizeof(desc)); + memset(&desc, 0, sizeof(desc)); - /* - * Get ring pointer, if we fail to obtain the - * correct ring, then use the first TX ring. - */ - ring = rt2x00lib_get_ring(rt2x00dev, control->queue); - if (!ring) - ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); - - desc.cw_min = ring->tx_params.cw_min; - desc.cw_max = ring->tx_params.cw_max; - desc.aifs = ring->tx_params.aifs; + desc.cw_min = skbdesc->ring->tx_params.cw_min; + desc.cw_max = skbdesc->ring->tx_params.cw_max; + desc.aifs = skbdesc->ring->tx_params.aifs; /* * Identify queue @@ -683,17 +673,18 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); desc.service = 0x04; + length = skbdesc->data_len + FCS_LEN; if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { - desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f; - desc.length_low = ((length + FCS_LEN) & 0x3f); + desc.length_high = (length >> 6) & 0x3f; + desc.length_low = length & 0x3f; } else { bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); /* * Convert length to microseconds. */ - residual = get_duration_res(length + FCS_LEN, bitrate); - duration = get_duration(length + FCS_LEN, bitrate); + residual = get_duration_res(length, bitrate); + duration = get_duration(length, bitrate); if (residual != 0) { duration++; @@ -716,8 +707,14 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, desc.signal |= 0x08; } - rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, - ieee80211hdr, length, control); + rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, ieee80211hdr, + skbdesc->data_len, control); + + /* + * Update ring entry. + */ + skbdesc->entry->skb = skb; + memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); } EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index cf0bb5d9d847..c1d7c10e58fe 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -38,9 +38,9 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct data_ring *ring = - rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); - struct data_entry *entry = rt2x00_get_data_entry(ring); + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; /* * Just in case mac80211 doesn't set this correctly, @@ -48,14 +48,22 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); /* - * Update the beacon entry. + * Fill in skb descriptor */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len; + desc->desc = entry->priv; + desc->data = skb->data; + desc->ring = ring; + desc->entry = entry; + memcpy(entry->data_addr, skb->data, skb->len); - rt2x00lib_write_tx_desc(rt2x00dev, entry->priv, - (struct ieee80211_hdr *)skb->data, - skb->len, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Enable beacon generation. @@ -73,9 +81,9 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, struct data_ring *ring, struct sk_buff *skb, struct ieee80211_tx_control *control) { - struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; struct data_entry *entry = rt2x00_get_data_entry(ring); __le32 *txd = entry->priv; + struct skb_desc *desc; u32 word; if (rt2x00_ring_full(ring)) { @@ -95,11 +103,19 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, return -EINVAL; } - entry->skb = skb; - memcpy(&entry->tx_status.control, control, sizeof(*control)); + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len; + desc->desc = entry->priv; + desc->data = skb->data; + desc->ring = ring; + desc->entry = entry; + memcpy(entry->data_addr, skb->data, skb->len); - rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr, - skb->len, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); rt2x00_ring_index_inc(ring); @@ -119,6 +135,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) struct data_entry *entry; struct sk_buff *skb; struct ieee80211_hdr *hdr; + struct skb_desc *skbdesc; struct rxdata_entry_desc desc; int header_size; __le32 *rxd; @@ -133,7 +150,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) break; - memset(&desc, 0x00, sizeof(desc)); + memset(&desc, 0, sizeof(desc)); rt2x00dev->ops->lib->fill_rxdone(entry, &desc); hdr = (struct ieee80211_hdr *)entry->data_addr; @@ -157,6 +174,17 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) skb_reserve(skb, align); memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size); + /* + * Fill in skb descriptor + */ + skbdesc = get_skb_desc(skb); + skbdesc->desc_len = desc.size; + skbdesc->data_len = entry->ring->desc_size; + skbdesc->desc = entry->priv; + skbdesc->data = skb->data; + skbdesc->ring = ring; + skbdesc->entry = entry; + /* * Send the frame to rt2x00lib for further processing. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h index 5b871adfa22a..5b32f3ef2a73 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ring.h +++ b/drivers/net/wireless/rt2x00/rt2x00ring.h @@ -26,6 +26,28 @@ #ifndef RT2X00RING_H #define RT2X00RING_H +/* + * skb_desc + * Descriptor information for the skb buffer + */ +struct skb_desc { + unsigned int frame_type; + + unsigned int desc_len; + unsigned int data_len; + + void *desc; + void *data; + + struct data_ring *ring; + struct data_entry *entry; +}; + +static inline struct skb_desc* get_skb_desc(struct sk_buff *skb) +{ + return (struct skb_desc*)&skb->cb[0]; +} + /* * rxdata_entry_desc * Summary of information that has been read from the diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 9b55f7997ca2..fd6b61c97619 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -176,7 +176,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, struct usb_device *usb_dev = interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); struct data_entry *entry = rt2x00_get_data_entry(ring); - int pipe = usb_sndbulkpipe(usb_dev, 1); + struct skb_desc *desc; u32 length; if (rt2x00_ring_full(ring)) { @@ -199,12 +199,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, skb_push(skb, ring->desc_size); memset(skb->data, 0, ring->desc_size); - rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data, - (struct ieee80211_hdr *)(skb->data + - ring->desc_size), - skb->len - ring->desc_size, control); - memcpy(&entry->tx_status.control, control, sizeof(*control)); - entry->skb = skb; + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; + + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * USB devices cannot blindly pass the skb->len as the @@ -217,7 +223,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, * Initialize URB and send the frame to the device. */ __set_bit(ENTRY_OWNER_NIC, &entry->flags); - usb_fill_bulk_urb(entry->priv, usb_dev, pipe, + usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1), skb->data, length, rt2x00usb_interrupt_txdone, entry); usb_submit_urb(entry->priv, GFP_ATOMIC); @@ -240,6 +246,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; struct sk_buff *skb; struct ieee80211_hdr *hdr; + struct skb_desc *skbdesc; struct rxdata_entry_desc desc; int header_size; int frame_size; @@ -256,7 +263,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) if (urb->actual_length < entry->ring->desc_size || urb->status) goto skip_entry; - memset(&desc, 0x00, sizeof(desc)); + memset(&desc, 0, sizeof(desc)); rt2x00dev->ops->lib->fill_rxdone(entry, &desc); /* @@ -296,6 +303,17 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) } skb_trim(entry->skb, desc.size); + /* + * Fill in skb descriptor + */ + skbdesc = get_skb_desc(entry->skb); + skbdesc->desc_len = desc.size; + skbdesc->data_len = entry->ring->desc_size; + skbdesc->desc = entry->skb->data + desc.size; + skbdesc->data = entry->skb->data; + skbdesc->ring = ring; + skbdesc->entry = entry; + /* * Send the frame to rt2x00lib for further processing. */ diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 52622d32ea4c..0693b3920e68 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2408,6 +2408,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; /* * Just in case the ieee80211 doesn't set this, @@ -2415,6 +2418,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); /* * We need to append the descriptor in front of the @@ -2428,15 +2433,23 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, } /* - * First we create the beacon. + * Add the descriptor in front of the skb. + */ + skb_push(skb, ring->desc_size); + memset(skb->data, 0, ring->desc_size); + + /* + * Fill in skb descriptor */ - skb_push(skb, TXD_DESC_SIZE); - memset(skb->data, 0, TXD_DESC_SIZE); + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; - rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data, - (struct ieee80211_hdr *)(skb->data + - TXD_DESC_SIZE), - skb->len - TXD_DESC_SIZE, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Write entire beacon with descriptor to register, diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 49180de321e4..8093a4d49335 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1965,6 +1965,9 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; int timeout; /* @@ -1973,17 +1976,27 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); /* - * First we create the beacon. + * Add the descriptor in front of the skb. */ - skb_push(skb, TXD_DESC_SIZE); - memset(skb->data, 0, TXD_DESC_SIZE); + skb_push(skb, ring->desc_size); + memset(skb->data, 0, ring->desc_size); - rt2x00lib_write_tx_desc(rt2x00dev, (__le32 *)skb->data, - (struct ieee80211_hdr *)(skb->data + - TXD_DESC_SIZE), - skb->len - TXD_DESC_SIZE, control); + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; + + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Write entire beacon with descriptor to register,