提交 63f2dc9f 编写于 作者: C Christian Lamparter 提交者: John W. Linville

p54: refactor p54_alloc_skb

Old firmwares had no problems processing frames which filled eighth of the memory window.
However we have to be a bit more careful with fat frames when we talk to new firmwares.
Apart from that, I confess the old logic was a bit weird and not very sophisticated.
Signed-off-by: NChristian Lamparter <chunkeey@web.de>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 6dd1bf31
...@@ -44,6 +44,8 @@ enum p54_control_frame_types { ...@@ -44,6 +44,8 @@ enum p54_control_frame_types {
P54_CONTROL_TYPE_BT_OPTIONS = 35 P54_CONTROL_TYPE_BT_OPTIONS = 35
}; };
#define P54_MAX_CTRL_FRAME_LEN 0x1000
#define P54_HDR_FLAG_CONTROL BIT(15) #define P54_HDR_FLAG_CONTROL BIT(15)
#define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0)) #define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0))
......
...@@ -1104,25 +1104,29 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1104,25 +1104,29 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0; return 0;
} }
static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags,
u16 hdr_flags, u16 len, u16 type, gfp_t memflags) u16 payload_len, u16 type, gfp_t memflags)
{ {
struct p54_common *priv = dev->priv; struct p54_common *priv = dev->priv;
struct p54_hdr *hdr; struct p54_hdr *hdr;
struct sk_buff *skb; struct sk_buff *skb;
size_t frame_len = sizeof(*hdr) + payload_len;
skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags); if (frame_len > P54_MAX_CTRL_FRAME_LEN)
return NULL;
skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
if (!skb) if (!skb)
return NULL; return NULL;
skb_reserve(skb, priv->tx_hdr_len); skb_reserve(skb, priv->tx_hdr_len);
hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr)); hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
hdr->flags = cpu_to_le16(hdr_flags); hdr->flags = cpu_to_le16(hdr_flags);
hdr->len = cpu_to_le16(len - sizeof(*hdr)); hdr->len = cpu_to_le16(payload_len);
hdr->type = cpu_to_le16(type); hdr->type = cpu_to_le16(type);
hdr->tries = hdr->rts_tries = 0; hdr->tries = hdr->rts_tries = 0;
if (unlikely(p54_assign_address(dev, skb, hdr, len))) { if (p54_assign_address(dev, skb, hdr, frame_len)) {
kfree_skb(skb); kfree_skb(skb);
return NULL; return NULL;
} }
...@@ -1132,7 +1136,6 @@ static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, ...@@ -1132,7 +1136,6 @@ static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
int p54_read_eeprom(struct ieee80211_hw *dev) int p54_read_eeprom(struct ieee80211_hw *dev)
{ {
struct p54_common *priv = dev->priv; struct p54_common *priv = dev->priv;
struct p54_hdr *hdr = NULL;
struct p54_eeprom_lm86 *eeprom_hdr; struct p54_eeprom_lm86 *eeprom_hdr;
struct sk_buff *skb; struct sk_buff *skb;
size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
...@@ -1145,9 +1148,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev) ...@@ -1145,9 +1148,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
else else
maxblocksize -= 0x4; maxblocksize -= 0x4;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) +
sizeof(*eeprom_hdr) + maxblocksize, maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK,
P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL); GFP_KERNEL);
if (!skb) if (!skb)
goto free; goto free;
priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
...@@ -1203,9 +1206,8 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta, ...@@ -1203,9 +1206,8 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
struct sk_buff *skb; struct sk_buff *skb;
struct p54_tim *tim; struct p54_tim *tim;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
sizeof(struct p54_hdr) + sizeof(*tim), P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1222,9 +1224,8 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr) ...@@ -1222,9 +1224,8 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
struct sk_buff *skb; struct sk_buff *skb;
struct p54_sta_unlock *sta; struct p54_sta_unlock *sta;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
sizeof(struct p54_hdr) + sizeof(*sta), P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1264,9 +1265,8 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry) ...@@ -1264,9 +1265,8 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
struct p54_hdr *hdr; struct p54_hdr *hdr;
struct p54_txcancel *cancel; struct p54_txcancel *cancel;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
sizeof(struct p54_hdr) + sizeof(*cancel), P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1548,9 +1548,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev) ...@@ -1548,9 +1548,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
struct p54_setup_mac *setup; struct p54_setup_mac *setup;
u16 mode; u16 mode;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP, P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1628,9 +1627,8 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell) ...@@ -1628,9 +1627,8 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
__le16 freq = cpu_to_le16(dev->conf.channel->center_freq); __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
int band = dev->conf.channel->band; int band = dev->conf.channel->band;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN, P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1710,9 +1708,8 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) ...@@ -1710,9 +1708,8 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
struct sk_buff *skb; struct sk_buff *skb;
struct p54_led *led; struct p54_led *led;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_LED, P54_CONTROL_TYPE_LED, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1739,9 +1736,8 @@ static int p54_set_edcf(struct ieee80211_hw *dev) ...@@ -1739,9 +1736,8 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
struct sk_buff *skb; struct sk_buff *skb;
struct p54_edcf *edcf; struct p54_edcf *edcf;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT, P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -1778,9 +1774,8 @@ static int p54_set_ps(struct ieee80211_hw *dev) ...@@ -1778,9 +1774,8 @@ static int p54_set_ps(struct ieee80211_hw *dev)
else else
mode = P54_PSM_CAM; mode = P54_PSM_CAM;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_PSM, P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -2083,10 +2078,8 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev) ...@@ -2083,10 +2078,8 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev)
struct sk_buff *skb; struct sk_buff *skb;
struct p54_xbow_synth *xbow; struct p54_xbow_synth *xbow;
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
GFP_KERNEL);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -2115,7 +2108,7 @@ static void p54_work(struct work_struct *work) ...@@ -2115,7 +2108,7 @@ static void p54_work(struct work_struct *work)
* 2. cancel stuck frames / reset the device if necessary. * 2. cancel stuck frames / reset the device if necessary.
*/ */
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
sizeof(struct p54_statistics), sizeof(struct p54_statistics),
P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL); P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
if (!skb) if (!skb)
...@@ -2226,9 +2219,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, ...@@ -2226,9 +2219,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
} }
mutex_lock(&priv->conf_mutex); mutex_lock(&priv->conf_mutex);
skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) + skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
sizeof(struct p54_hdr), P54_CONTROL_TYPE_RX_KEYCACHE, P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
GFP_ATOMIC);
if (!skb) { if (!skb) {
mutex_unlock(&priv->conf_mutex); mutex_unlock(&priv->conf_mutex);
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册