1a1c55580SChristian Lamparter /* 2a1c55580SChristian Lamparter * Copyright (c) 2009 Atheros Communications Inc. 3a1c55580SChristian Lamparter * 4a1c55580SChristian Lamparter * Permission to use, copy, modify, and/or distribute this software for any 5a1c55580SChristian Lamparter * purpose with or without fee is hereby granted, provided that the above 6a1c55580SChristian Lamparter * copyright notice and this permission notice appear in all copies. 7a1c55580SChristian Lamparter * 8a1c55580SChristian Lamparter * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9a1c55580SChristian Lamparter * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10a1c55580SChristian Lamparter * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11a1c55580SChristian Lamparter * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12a1c55580SChristian Lamparter * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13a1c55580SChristian Lamparter * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14a1c55580SChristian Lamparter * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15a1c55580SChristian Lamparter */ 16a1c55580SChristian Lamparter 17516304b0SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18516304b0SJoe Perches 19a1c55580SChristian Lamparter #include <linux/kernel.h> 20a1c55580SChristian Lamparter #include <linux/module.h> 21a1c55580SChristian Lamparter 22d15dd3e5SLuis R. Rodriguez #include "ath.h" 23d15dd3e5SLuis R. Rodriguez 24a1c55580SChristian Lamparter MODULE_AUTHOR("Atheros Communications"); 25a1c55580SChristian Lamparter MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards."); 26a1c55580SChristian Lamparter MODULE_LICENSE("Dual BSD/GPL"); 27d15dd3e5SLuis R. Rodriguez 28d15dd3e5SLuis R. Rodriguez struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 29d15dd3e5SLuis R. Rodriguez u32 len, 30d15dd3e5SLuis R. Rodriguez gfp_t gfp_mask) 31d15dd3e5SLuis R. Rodriguez { 32d15dd3e5SLuis R. Rodriguez struct sk_buff *skb; 33d15dd3e5SLuis R. Rodriguez u32 off; 34d15dd3e5SLuis R. Rodriguez 35d15dd3e5SLuis R. Rodriguez /* 36d15dd3e5SLuis R. Rodriguez * Cache-line-align. This is important (for the 37d15dd3e5SLuis R. Rodriguez * 5210 at least) as not doing so causes bogus data 38d15dd3e5SLuis R. Rodriguez * in rx'd frames. 39d15dd3e5SLuis R. Rodriguez */ 40d15dd3e5SLuis R. Rodriguez 41d15dd3e5SLuis R. Rodriguez /* Note: the kernel can allocate a value greater than 42d15dd3e5SLuis R. Rodriguez * what we ask it to give us. We really only need 4 KB as that 43d15dd3e5SLuis R. Rodriguez * is this hardware supports and in fact we need at least 3849 44d15dd3e5SLuis R. Rodriguez * as that is the MAX AMSDU size this hardware supports. 45d15dd3e5SLuis R. Rodriguez * Unfortunately this means we may get 8 KB here from the 46d15dd3e5SLuis R. Rodriguez * kernel... and that is actually what is observed on some 47d15dd3e5SLuis R. Rodriguez * systems :( */ 48d15dd3e5SLuis R. Rodriguez skb = __dev_alloc_skb(len + common->cachelsz - 1, gfp_mask); 49d15dd3e5SLuis R. Rodriguez if (skb != NULL) { 50d15dd3e5SLuis R. Rodriguez off = ((unsigned long) skb->data) % common->cachelsz; 51d15dd3e5SLuis R. Rodriguez if (off != 0) 52d15dd3e5SLuis R. Rodriguez skb_reserve(skb, common->cachelsz - off); 53d15dd3e5SLuis R. Rodriguez } else { 54516304b0SJoe Perches pr_err("skbuff alloc of size %u failed\n", len); 55d15dd3e5SLuis R. Rodriguez return NULL; 56d15dd3e5SLuis R. Rodriguez } 57d15dd3e5SLuis R. Rodriguez 58d15dd3e5SLuis R. Rodriguez return skb; 59d15dd3e5SLuis R. Rodriguez } 60d15dd3e5SLuis R. Rodriguez EXPORT_SYMBOL(ath_rxbuf_alloc); 6121a99f93SJoe Perches 62f1d267caSOleksij Rempel bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr) 63f1d267caSOleksij Rempel { 64f1d267caSOleksij Rempel return ieee80211_is_beacon(hdr->frame_control) && 65f1d267caSOleksij Rempel !is_zero_ether_addr(common->curbssid) && 66f1d267caSOleksij Rempel ether_addr_equal_64bits(hdr->addr3, common->curbssid); 67f1d267caSOleksij Rempel } 68f1d267caSOleksij Rempel EXPORT_SYMBOL(ath_is_mybeacon); 69f1d267caSOleksij Rempel 7098b36a02SBen Greear void ath_printk(const char *level, const struct ath_common* common, 7198b36a02SBen Greear const char *fmt, ...) 7221a99f93SJoe Perches { 7321a99f93SJoe Perches struct va_format vaf; 7421a99f93SJoe Perches va_list args; 7521a99f93SJoe Perches 7621a99f93SJoe Perches va_start(args, fmt); 7721a99f93SJoe Perches 7821a99f93SJoe Perches vaf.fmt = fmt; 7921a99f93SJoe Perches vaf.va = &args; 8021a99f93SJoe Perches 8198b36a02SBen Greear if (common && common->hw && common->hw->wiphy) 8298b36a02SBen Greear printk("%sath: %s: %pV", 8398b36a02SBen Greear level, wiphy_name(common->hw->wiphy), &vaf); 8498b36a02SBen Greear else 8529e76245SJoe Perches printk("%sath: %pV", level, &vaf); 8621a99f93SJoe Perches 8721a99f93SJoe Perches va_end(args); 8821a99f93SJoe Perches } 8921a99f93SJoe Perches EXPORT_SYMBOL(ath_printk); 90