#include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM #define WLAN_STATIC_SCAN_BUF0 5 #define WLAN_STATIC_SCAN_BUF1 6 #define PREALLOC_WLAN_SEC_NUM 4 #define PREALLOC_WLAN_BUF_NUM 160 #define PREALLOC_WLAN_SECTION_HEADER 24 #define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128) #define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128) #define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512) #define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024) #define DHD_SKB_HDRSIZE 336 #define DHD_SKB_1PAGE_BUFSIZE ((PAGE_SIZE*1)-DHD_SKB_HDRSIZE) #define DHD_SKB_2PAGE_BUFSIZE ((PAGE_SIZE*2)-DHD_SKB_HDRSIZE) #define DHD_SKB_4PAGE_BUFSIZE ((PAGE_SIZE*4)-DHD_SKB_HDRSIZE) #define WLAN_SKB_BUF_NUM 17 static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; struct wlan_mem_prealloc { void *mem_ptr; unsigned long size; }; static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = { {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)}, {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)}, {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)}, {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)} }; void *wlan_static_scan_buf0; void *wlan_static_scan_buf1; static void *brcm_wlan_mem_prealloc(int section, unsigned long size) { if (section == PREALLOC_WLAN_SEC_NUM) return wlan_static_skb; if (section == WLAN_STATIC_SCAN_BUF0) return wlan_static_scan_buf0; if (section == WLAN_STATIC_SCAN_BUF1) return wlan_static_scan_buf1; if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) return NULL; if (wlan_mem_array[section].size < size) return NULL; return wlan_mem_array[section].mem_ptr; } static int brcm_init_wlan_mem(void) { int i; int j; for (i = 0; i < 8; i++) { wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE); if (!wlan_static_skb[i]) goto err_skb_alloc; } for (; i < 16; i++) { wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE); if (!wlan_static_skb[i]) goto err_skb_alloc; } wlan_static_skb[i] = dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE); if (!wlan_static_skb[i]) goto err_skb_alloc; for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) { wlan_mem_array[i].mem_ptr = kmalloc(wlan_mem_array[i].size, GFP_KERNEL); if (!wlan_mem_array[i].mem_ptr) goto err_mem_alloc; } wlan_static_scan_buf0 = kmalloc (65536, GFP_KERNEL); if(!wlan_static_scan_buf0) goto err_mem_alloc; wlan_static_scan_buf1 = kmalloc (65536, GFP_KERNEL); if(!wlan_static_scan_buf1) goto err_mem_alloc; printk("%s: WIFI MEM Allocated\n", __FUNCTION__); return 0; err_mem_alloc: pr_err("Failed to mem_alloc for WLAN\n"); for (j = 0 ; j < i ; j++) kfree(wlan_mem_array[j].mem_ptr); i = WLAN_SKB_BUF_NUM; err_skb_alloc: pr_err("Failed to skb_alloc for WLAN\n"); for (j = 0 ; j < i ; j++) dev_kfree_skb(wlan_static_skb[j]); return -ENOMEM; } #endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */ static unsigned int wlan_on_gpio_table[][4] = { {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_HIGH, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_HOST_WAKE, GPIO_WLAN_HOST_WAKE_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN}, }; static unsigned int wlan_off_gpio_table[][4] = { {GPIO_WLAN_EN , GPIO_WLAN_EN_AF, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_HOST_WAKE, 0 , GPIO_LEVEL_NONE, S3C_GPIO_PULL_DOWN}, }; static unsigned int wlan_sdio_on_table[][4] = { {GPIO_WLAN_SDIO_CLK, GPIO_WLAN_SDIO_CLK_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_CMD, GPIO_WLAN_SDIO_CMD_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D0, GPIO_WLAN_SDIO_D0_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D1, GPIO_WLAN_SDIO_D1_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D2, GPIO_WLAN_SDIO_D2_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D3, GPIO_WLAN_SDIO_D3_AF, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, }; static unsigned int wlan_sdio_off_table[][4] = { {GPIO_WLAN_SDIO_CLK, 1, GPIO_LEVEL_LOW, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_CMD, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D0, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D1, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D2, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, {GPIO_WLAN_SDIO_D3, 0, GPIO_LEVEL_NONE, S3C_GPIO_PULL_NONE}, }; static void s3c_config_gpio_alive_table(int array_size, unsigned int (*gpio_table)[4]) { u32 i, gpio; printk("gpio_table = [%d] \r\n" , array_size); for (i = 0; i < array_size; i++) { gpio = gpio_table[i][0]; s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(gpio_table[i][1])); s3c_gpio_setpull(gpio, gpio_table[i][3]); if (gpio_table[i][2] != GPIO_LEVEL_NONE) gpio_set_value(gpio, gpio_table[i][2]); } } static int brcm_wlan_power(int onoff) { printk("------------------------------------------------"); printk("------------------------------------------------\n"); printk("%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off"); pr_info("111%s Enter: power %s\n", __FUNCTION__, onoff ? "on" : "off"); if (onoff) { s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_on_gpio_table), wlan_on_gpio_table); udelay(200); gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_HIGH); printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN)); } else { gpio_set_value(GPIO_WLAN_EN, GPIO_LEVEL_LOW); s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_off_gpio_table), wlan_off_gpio_table); printk(KERN_DEBUG "WLAN: GPIO_WLAN_EN = %d \n", gpio_get_value(GPIO_WLAN_EN)); } return 0; } static int brcm_wlan_reset(int onoff) { gpio_set_value(GPIO_WLAN_EN, onoff ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW); return 0; } static int brcm_wlan_set_carddetect(int onoff) { if (onoff) s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_on_table), wlan_sdio_on_table); else s3c_config_gpio_alive_table(ARRAY_SIZE(wlan_sdio_off_table), wlan_sdio_off_table); udelay(200); mmc_force_presence_change(&s3c_device_hsmmc3); /* msleep(500); wait for carddetect */ return 0; } /* Customized Locale table : OPTIONAL feature */ #define WLC_CNTRY_BUF_SZ 4 typedef struct cntry_locales_custom { char iso_abbrev[WLC_CNTRY_BUF_SZ]; char custom_locale[WLC_CNTRY_BUF_SZ]; int custom_locale_rev; } cntry_locales_custom_t; static cntry_locales_custom_t brcm_wlan_translate_custom_table[] = { /* Table should be filled out based on custom platform regulatory requirement */ {"", "XZ", 11}, /* Universal if Country code is unknown or empty */ {"AE", "AE", 1}, {"AR", "AR", 1}, {"AT", "AT", 1}, {"AU", "AU", 2}, {"BE", "BE", 1}, {"BG", "BG", 1}, {"BN", "BN", 1}, {"CA", "CA", 2}, {"CH", "CH", 1}, {"CY", "CY", 1}, {"CZ", "CZ", 1}, {"DE", "DE", 3}, {"DK", "DK", 1}, {"EE", "EE", 1}, {"ES", "ES", 1}, {"FI", "FI", 1}, {"FR", "FR", 1}, {"GB", "GB", 1}, {"GR", "GR", 1}, {"HR", "HR", 1}, {"HU", "HU", 1}, {"IE", "IE", 1}, {"IS", "IS", 1}, {"IT", "IT", 1}, {"JP", "JP", 3}, {"KR", "KR", 24}, {"KW", "KW", 1}, {"LI", "LI", 1}, {"LT", "LT", 1}, {"LU", "LU", 1}, {"LV", "LV", 1}, {"MA", "MA", 1}, {"MT", "MT", 1}, {"MX", "MX", 1}, {"NL", "NL", 1}, {"NO", "NO", 1}, {"PL", "PL", 1}, {"PT", "PT", 1}, {"PY", "PY", 1}, {"RO", "RO", 1}, {"RU", "RU", 5}, {"SE", "SE", 1}, {"SG", "SG", 4}, {"SI", "SI", 1}, {"SK", "SK", 1}, {"TR", "TR", 7}, {"TW", "TW", 2}, {"US", "US", 46} }; static void *brcm_wlan_get_country_code(char *ccode) { int size = ARRAY_SIZE(brcm_wlan_translate_custom_table); int i; if (!ccode) return NULL; for (i = 0; i < size; i++) if (strcmp(ccode, brcm_wlan_translate_custom_table[i].iso_abbrev) == 0) return &brcm_wlan_translate_custom_table[i]; return &brcm_wlan_translate_custom_table[0]; } static struct resource brcm_wlan_resources[] = { [0] = { .name = "bcmdhd_wlan_irq", .start = IRQ_EINT(21), .end = IRQ_EINT(21), //chanyun 12.21 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE, }, }; static struct wifi_platform_data brcm_wlan_control = { .set_power = brcm_wlan_power, .set_reset = brcm_wlan_reset, .set_carddetect = brcm_wlan_set_carddetect, #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM .mem_prealloc = brcm_wlan_mem_prealloc, #endif .get_country_code = brcm_wlan_get_country_code, }; static struct platform_device brcm_device_wlan = { .name = "bcmdhd_wlan", .id = 1, .num_resources = ARRAY_SIZE(brcm_wlan_resources), .resource = brcm_wlan_resources, .dev = { .platform_data = &brcm_wlan_control, }, }; int __init brcm_wlan_init(void) { int ret; printk("%s: start\n", __FUNCTION__); #ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM brcm_init_wlan_mem(); #endif ret = platform_device_register(&brcm_device_wlan); printk("-----------------------------------------------------\n"); printk("-----------------------------------------------------\n"); printk("-----------------------------------------------------\n"); printk("regist ret:%d\n", ret); return ret; // return platform_device_register(&brcm_device_wlan); }