summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/mamona/cx3110x-0.8.1/770_performance_improvements.patch307
-rw-r--r--packages/mamona/cx3110x-0.8.1/cx3110x.patch492
-rw-r--r--packages/mamona/cx3110x-0.8.1/fix_cross_makefile.patch11
-rw-r--r--packages/mamona/cx3110x-0.8.1/fix_mem_allign.patch94
-rw-r--r--packages/mamona/cx3110x-0.8.1/fix_mem_corruption.patch53
-rw-r--r--packages/mamona/cx3110x-0.8.1/fix_ssid_data_length.patch13
-rw-r--r--packages/mamona/cx3110x-0.8.1/nokia770/defconfig1380
-rw-r--r--packages/mamona/cx3110x-0.8.1/nokia800/defconfig1312
-rw-r--r--packages/mamona/cx3110x-0.8.1/series6
-rw-r--r--packages/mamona/cx3110x_0.8.1.bb40
10 files changed, 3708 insertions, 0 deletions
diff --git a/packages/mamona/cx3110x-0.8.1/770_performance_improvements.patch b/packages/mamona/cx3110x-0.8.1/770_performance_improvements.patch
new file mode 100644
index 0000000000..be9be86b82
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/770_performance_improvements.patch
@@ -0,0 +1,307 @@
+Index: cx3110x-0.8.1/src/sm_drv_spi.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_spi.c 2008-04-28 18:30:22.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_spi.c 2008-04-28 18:30:25.000000000 -0300
+@@ -99,10 +99,10 @@
+ struct net_local *lp = dev->priv;
+ uint32_t host_ints, host_ints_ack, target_ints;
+ unsigned long timeout;
+- int result;
++ int result, pass = 1;
+
+ DEBUG(DBG_BH, "w\n");
+-
++again:
+ /* Here we wake the target up */
+ target_ints = SPI_TARGET_INT_WAKEUP;
+ sm_spi_write(dev, SPI_ADRS_ARM_INTERRUPTS,
+@@ -117,6 +117,11 @@
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_WARNING "We haven't got a READY interrupt"
+ " from WAKEUP. (firmware crashed?)\n");
++ if (pass == 1) {
++ printk(KERN_WARNING "Try again...\n");
++ pass = 2;
++ goto again;
++ }
+ lp->device_state = DEVSTATE_DEAD;
+ result = -1;
+ goto exit;
+@@ -131,7 +136,10 @@
+ (unsigned char *)&host_ints_ack, sizeof(host_ints_ack));
+
+ result = 0;
+-
++
++ if (pass == 2) {
++ printk(KERN_WARNING "succeeded!!!\n");
++ }
+ exit:
+ DEBUG(DBG_BH, "W\n");
+ return result;
+@@ -150,49 +158,84 @@
+ return 0;
+ }
+
+-static int sm_drv_spi_rx(struct net_device *dev)
++static int sm_drv_spi_is_rx_frame_available(struct net_device *dev)
++{
++ uint32_t host_ints, host_ints_ack;
++ sm_spi_read(dev, SPI_ADRS_HOST_INTERRUPTS, (unsigned char *)&host_ints, sizeof(host_ints));
++ if ((host_ints & SPI_HOST_INT_UPDATE) || (host_ints & SPI_HOST_INT_SW_UPDATE)) {
++ host_ints_ack = SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE;
++ sm_spi_write(dev, SPI_ADRS_HOST_INT_ACK, (unsigned char *)&host_ints_ack, sizeof(host_ints_ack));
++ return 1;
++ }
++ return 0;
++}
++
++static struct s_ic_msg * sm_drv_spi_alloc_frame_and_start_rx_transfer(struct net_device *dev)
+ {
+ struct net_local *lp = dev->priv;
+- struct spi_hif_local_data *hif_lp = HIF_LP(lp);
+ struct s_sm_frame *frame;
++ unsigned short length;
+ struct s_ic_msg *ic_msg;
++
++ frame = frame_skb_alloc(dev, lp->sm_descr.mtu + lp->sm_descr.rxoffset, 0);
++ if (frame == NULL) return NULL;
++
++ /* dummy read to flush SPI DMA controller bug */
++ sm_spi_read(dev, SPI_ADRS_GEN_PURP_1, (unsigned char *)&length, sizeof(length));
++
++ sm_spi_read(dev, SPI_ADRS_DMA_DATA, (unsigned char *)&length, sizeof(length));
++ DEBUG(DBG_BH, "%s: received frame len=%d\n", DRIVER_NAME, length);
++
++ if (length > SPI_MAX_PACKET_SIZE)
++ length = SPI_MAX_PACKET_SIZE;
++
++ sm_spi_dma_read_start(dev, SPI_ADRS_DMA_DATA, (unsigned char *) frame->data, length);
++
++ ic_msg = FRAME_ICMSG(frame);
++ ic_msg->frame = frame;
++ ic_msg->channel = 0;
++ ic_msg->flags = 0;
++ ic_msg->length = length;
++ ic_msg->address = 0;
++ ic_msg->data = frame->data;
++
++ return ic_msg;
++}
++
++static int sm_drv_spi_rx(struct net_device *dev)
++{
++ struct net_local *lp = dev->priv;
++ struct spi_hif_local_data *hif_lp = HIF_LP(lp);
++ struct s_ic_msg *ic_msg, *ic_msg_next;
+ int result, err;
+- unsigned short length;
+ int32_t callb_mask = 0;
+-
++
+ err = sm_drv_spi_wakeup(dev);
+ if (err < 0) {
+ result = -1;
+ goto exit;
+ }
+
+- frame = frame_skb_alloc(dev, lp->sm_descr.mtu + lp->sm_descr.rxoffset,
+- 0);
+- if (frame != NULL) {
+- ic_msg = FRAME_ICMSG(frame);
+- ic_msg->frame = frame;
+-
+- /* dummy read to flush SPI DMA controller bug */
+- sm_spi_read(dev, SPI_ADRS_GEN_PURP_1, (unsigned char *)&length,
+- sizeof(length));
+-
+- sm_spi_read(dev, SPI_ADRS_DMA_DATA, (unsigned char *)&length,
+- sizeof(length));
+-
+- DEBUG(DBG_BH, "%s: received frame len=%d\n", DRIVER_NAME,
+- length);
+-
+- if (length > SPI_MAX_PACKET_SIZE)
+- length = SPI_MAX_PACKET_SIZE;
++ ic_msg_next = sm_drv_spi_alloc_frame_and_start_rx_transfer(dev);
++ if (ic_msg_next == NULL) {
++ printk("Couldn't allocate RX frame\n");
++ result = -1;
++ goto exit;
++ }
+
+- sm_spi_dma_read(dev, SPI_ADRS_DMA_DATA,
+- (unsigned char *) frame->data, length);
+-
+- ic_msg->channel = 0;
+- ic_msg->flags = 0;
+- ic_msg->length = length;
+- ic_msg->address = 0;
+- ic_msg->data = frame->data;
++ while (ic_msg_next) {
++ sm_spi_dma_read_wait_for_completion();
++ ic_msg = ic_msg_next;
++ ic_msg_next = NULL;
++
++ if (sm_drv_spi_is_rx_frame_available(dev)) {
++ ic_msg_next = sm_drv_spi_alloc_frame_and_start_rx_transfer(dev);
++ if (ic_msg_next == NULL) {
++ printk("Couldn't allocate RX frame\n");
++ result = -1;
++ goto exit;
++ }
++ }
+
+ hif_lp->spi_packets++;
+ spin_lock_bh(&lp->sm_lock);
+@@ -207,13 +250,14 @@
+
+ DEBUG(DBG_IC,"Callback mask: %d\n", callb_mask);
+
+- if(callb_mask < 0)
++ if (callb_mask < 0) {
+ printk(KERN_WARNING "prism_interconnect_message_handle"
+ "returned error %d\n", callb_mask);
+- } else
+- printk("Couldn't allocate RX frame\n");
+-
+- handle_sm_callback(dev, callb_mask);
++ result = -1;
++ goto exit;
++ }
++ handle_sm_callback(dev, callb_mask);
++ }
+
+ result = 0;
+
+Index: cx3110x-0.8.1/src/sm_drv_spi_io.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.c 2008-04-28 18:30:25.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_spi_io.c 2008-04-28 18:35:59.000000000 -0300
+@@ -120,7 +120,7 @@
+ }
+
+
+-int cx3110x_spi_dma_read(struct net_device *dev, unsigned long address, void * buffer, unsigned int length)
++int cx3110x_spi_dma_read_start(struct net_device *dev, unsigned long address, void * buffer, unsigned int length)
+ {
+ SPI_CS_ON();
+
+@@ -170,13 +170,22 @@
+ omap_start_dma(spi_dma.dma_rx_ch);
+ omap_start_dma(spi_dma.dma_tx_ch);
+
+- /* Wait for reading to complete */
+- while(!spi_dma.dma_rx_done) {
+- udelay(5);
++ return 0;
++}
++
++int cx3110x_spi_dma_read_wait_for_completion()
++{
++ int wait_limit = 15000 * 5;
++ int wait_cycles = 0;
++
++ /* Wait for DMA reading to complete */
++ while ((!spi_dma.dma_rx_done || !spi_dma.dma_tx_done) && wait_cycles < wait_limit) {
++ wait_cycles++;
++ udelay(1);
+ }
+
+- while(!spi_dma.dma_tx_done) {
+- udelay(5);
++ if (wait_cycles >= wait_limit) {
++ printk("McBSP read DMA timeout, spi_dma.dma_rx_done=%d, spi_dma.dma_tx_done=%d\n", spi_dma.dma_rx_done, spi_dma.dma_tx_done);
+ }
+
+ spi_dma.dma_rx_done = 0;
+@@ -184,11 +193,14 @@
+
+ SPI_CS_OFF();
+
+- return 0;
++ return wait_cycles;
+ }
+
+ int cx3110x_spi_dma_write(struct net_device *dev, unsigned long address, void * buffer, unsigned int length)
+ {
++ int wait_limit = 15000 * 5;
++ int wait_cycles = 0;
++
+ SPI_CS_ON();
+
+ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, address << 8);
+@@ -239,16 +251,20 @@
+ omap_start_dma(spi_dma.dma_rx_ch);
+ omap_start_dma(spi_dma.dma_tx_ch);
+
+- /* We don't want to turn CS off before transfer is done */
+-
+- while(!spi_dma.dma_rx_done) {
+- udelay(5);
++ /* Wait for DMA writing to complete */
++ while ((!spi_dma.dma_rx_done || !spi_dma.dma_tx_done) && wait_cycles < wait_limit) {
++ wait_cycles++;
++ udelay(1);
+ }
+
+ while(!spi_dma.dma_tx_done) {
+ udelay(5);
+ }
+
++ if (wait_cycles >= wait_limit) {
++ printk("McBSP write DMA timeout, spi_dma.dma_rx_done=%d, spi_dma.dma_tx_done=%d\n", spi_dma.dma_rx_done, spi_dma.dma_tx_done);
++ }
++
+ spi_dma.dma_rx_done = 0;
+ spi_dma.dma_tx_done = 0;
+
+@@ -320,7 +336,7 @@
+ int cx3110x_spi_start(struct net_device *dev)
+ {
+ struct omap_mcbsp_spi_cfg spi_cfg;
+- int r, div = 1, rate_mhz, max_mhz = 14;
++ int r, div = 1, rate_mhz, max_mhz = 16;
+ struct net_local * lp;
+ struct spi_hif_local_data * spi_lp;
+
+@@ -368,11 +384,11 @@
+
+ cx3110x_hw_reset();
+
+- while(rate_mhz/div >= max_mhz)
++ while(rate_mhz/(div+1) >= max_mhz)
+ div++;
+
+- printk("McBSP2: freq_limit=%dMHz, base_freq=%dMHz, divisor=%d (%d.%dMHz)\n",
+- max_mhz, rate_mhz, div, rate_mhz / div, (rate_mhz * 10 / div) % 10);
++ printk("McBSP2: freq_limit=%dMHz, base_freq=%dMHz, div=%d (%d.%dMHz)\n",
++ max_mhz, rate_mhz, div, rate_mhz / (div+1), (rate_mhz * 10 / (div+1)) % 10);
+
+ spi_dma.dma_tx_done = 0;
+ spi_dma.dma_rx_done = 0;
+Index: cx3110x-0.8.1/src/sm_drv_spi_io.h
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.h 2008-04-28 18:30:22.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_spi_io.h 2008-04-28 18:30:25.000000000 -0300
+@@ -27,15 +27,17 @@
+
+ int cx3110x_spi_read(struct net_device * dev, unsigned long address, unsigned char * buffer, unsigned int length);
+ int cx3110x_spi_write(struct net_device * dev, unsigned long address, unsigned char * buffer, unsigned int length);
+-int cx3110x_spi_dma_read(struct net_device *dev, unsigned long address, void * buffer, unsigned int length);
++int cx3110x_spi_dma_read_start(struct net_device *dev, unsigned long address, void * buffer, unsigned int length);
++int cx3110x_spi_dma_read_wait_for_completion(void);
+ int cx3110x_spi_dma_write(struct net_device *dev, unsigned long address, void * buffer, unsigned int length);
+
+ void cx3110x_dump_register(struct net_device * dev);
+
+-#define sm_spi_read(dev, addr, data, len) cx3110x_spi_read(dev, (addr), (data), (len))
++#define sm_spi_read(dev, addr, data, len) cx3110x_spi_read(dev, (addr), (data), (len))
+ #define sm_spi_write(dev, addr, data, len) cx3110x_spi_write(dev, (addr), (data), (len))
+
+-#define sm_spi_dma_read(dev, addr, data, len) cx3110x_spi_dma_read(dev, (addr), (data), (len))
++#define sm_spi_dma_read_start(dev, addr, data, len) cx3110x_spi_dma_read_start(dev, (addr), (data), (len))
++#define sm_spi_dma_read_wait_for_completion() cx3110x_spi_dma_read_wait_for_completion()
+ #define sm_spi_dma_write(dev, addr, data, len) cx3110x_spi_dma_write(dev, (addr), (data), (len))
+
+ #endif
diff --git a/packages/mamona/cx3110x-0.8.1/cx3110x.patch b/packages/mamona/cx3110x-0.8.1/cx3110x.patch
new file mode 100644
index 0000000000..06340581d1
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/cx3110x.patch
@@ -0,0 +1,492 @@
+Index: cx3110x-0.8.1/src/sm_drv_ioctl_umac.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_ioctl_umac.c 2007-10-15 08:56:20.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_ioctl_umac.c 2008-04-22 15:50:45.000000000 -0300
+@@ -76,7 +76,7 @@
+ kfree(wrqu.data.pointer);
+ }
+
+-void send_wpa_ie_event(struct net_device *dev, char * bss_addr, char * wpa_ie, size_t wpa_ie_len, uint32_t event)
++void send_wpa_ie_event(struct net_device *dev, char * wpa_ie, size_t wpa_ie_len, uint32_t event)
+ {
+ union iwreq_data wrqu;
+ uint32_t we_event;
+@@ -97,15 +97,12 @@
+ return;
+ }
+
+- wrqu.data.pointer = kzalloc(ETH_ALEN + 1 + wpa_ie_len, GFP_ATOMIC);
++ wrqu.data.pointer = kzalloc(wpa_ie_len, GFP_ATOMIC);
+ if (!wrqu.data.pointer)
+ return;
+
+- memcpy(wrqu.data.pointer, bss_addr, ETH_ALEN);
+- *((char *)(wrqu.data.pointer + ETH_ALEN)) = ':';
+- memcpy(wrqu.data.pointer + ETH_ALEN + 1, wpa_ie, wpa_ie_len);
+-
+- wrqu.data.length = ETH_ALEN + 1 + wpa_ie_len;
++ memcpy(wrqu.data.pointer, wpa_ie, wpa_ie_len);
++ wrqu.data.length = wpa_ie_len;
+
+ wireless_send_event(dev, we_event, &wrqu, wrqu.data.pointer);
+ kfree(wrqu.data.pointer);
+@@ -495,7 +492,7 @@
+ /* We send the event after parsing the association frame */
+ if ((lp->link_state == DOT11_STATE_ASSOCING || lp->link_state == DOT11_STATE_ASSOC)
+ && event)
+- send_wpa_ie_event(dev, bssid, wpa_ie, wpa_ie_len, event);
++ send_wpa_ie_event(dev, wpa_ie, wpa_ie_len, event);
+
+ /* try to use existing entry */
+ list_for_each_entry_safe(bss, safe, &lp->bss_wpa_list, list) {
+@@ -1782,6 +1779,435 @@
+ return sm_drv_oid_set(dev, DOT11_OID_STAKEY, (void *)&key, sizeof(struct obj_stakey));
+ }
+
++static int sm_drv_set_auth(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct net_local *priv = netdev_priv(dev);
++ struct iw_param *param = &wrqu->param;
++ u32 authen = 0, dot1x = 0;
++ u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
++ u32 old_wpa;
++ int ret = 0;
++
++ DEBUG(DBG_IOCTL, "SET AUTH\n");
++
++ /* first get the flags */
++ down(&priv->wpa_sem);
++ wpa = old_wpa = priv->wpa;
++ up(&priv->wpa_sem);
++ ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
++ (void *)&authen, sizeof(uint32_t));
++ ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
++ (void *)&privinvoked, sizeof(uint32_t));
++ ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
++ (void *)&exunencrypt, sizeof(uint32_t));
++ ret |= sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
++ (void *)&dot1x, sizeof(uint32_t));
++
++ if (ret < 0)
++ goto out;
++
++ switch (param->flags & IW_AUTH_INDEX) {
++ case IW_AUTH_CIPHER_PAIRWISE:
++ case IW_AUTH_CIPHER_GROUP:
++ case IW_AUTH_KEY_MGMT:
++ break;
++
++ case IW_AUTH_WPA_ENABLED:
++ /* Do the same thing as IW_AUTH_WPA_VERSION */
++ if (param->value) {
++ wpa = DOT11_PRIV_INV_TKIP;
++ privinvoked = 1; /* For privacy invoked */
++ exunencrypt = 1; /* Filter out all unencrypted frames */
++ dot1x = 0x01; /* To enable eap filter */
++ authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
++ } else {
++ wpa = DOT11_PRIV_INV_NONE;
++ privinvoked = 0;
++ exunencrypt = 0; /* Do not filter un-encrypted data */
++ dot1x = 0;
++ }
++ break;
++
++ case IW_AUTH_WPA_VERSION:
++ if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
++ wpa = DOT11_PRIV_INV_NONE;
++ privinvoked = 0;
++ exunencrypt = 0; /* Do not filter un-encrypted data */
++ dot1x = 0;
++ } else {
++ if (param->value & IW_AUTH_WPA_VERSION_WPA)
++ wpa = DOT11_PRIV_INV_TKIP;
++ else if (param->value & IW_AUTH_WPA_VERSION_WPA2)
++ wpa = DOT11_PRIV_INV_AES_CCMP;
++ privinvoked = 1; /* For privacy invoked */
++ exunencrypt = 1; /* Filter out all unencrypted frames */
++ dot1x = 0x01; /* To enable eap filter */
++ authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
++ }
++ break;
++
++ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
++ /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
++ * turn off dot1x when allowing receipt of unencrypted EAPOL
++ * frames, turn on dot1x when receipt should be disallowed
++ */
++ dot1x = param->value ? 0 : 0x01;
++ break;
++
++ case IW_AUTH_PRIVACY_INVOKED:
++ privinvoked = param->value ? 1 : 0;
++ break;
++
++ case IW_AUTH_DROP_UNENCRYPTED:
++ exunencrypt = param->value ? 1 : 0;
++ break;
++
++ case IW_AUTH_80211_AUTH_ALG:
++ if (param->value & IW_AUTH_ALG_SHARED_KEY) {
++ /* Only WEP uses _SK and _BOTH */
++ if (wpa > 0) {
++ ret = -EINVAL;
++ goto out;
++ }
++ authen = DOT11_AUTH_SK;
++ } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
++ authen = DOT11_AUTH_OS;
++ } else {
++ ret = -EINVAL;
++ goto out;
++ }
++ break;
++
++ default:
++ return -EOPNOTSUPP;
++ }
++
++ /* Set all the values */
++ down(&priv->wpa_sem);
++ priv->wpa = wpa;
++ up(&priv->wpa_sem);
++
++ sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
++ (void *)&authen, sizeof(uint32_t));
++ sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
++ (void *)&privinvoked, sizeof(uint32_t));
++ sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
++ (void *)&exunencrypt, sizeof(uint32_t));
++ sm_drv_oid_set(dev, DOT11_OID_DOT1XENABLE,
++ (void *)&dot1x, sizeof(uint32_t));
++
++ out:
++ return ret;
++}
++
++static int sm_drv_get_auth(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu, char *extra)
++{
++ struct net_local *priv = netdev_priv(dev);
++ struct iw_param *param = &wrqu->param;
++ u32 authen = 0, dot1x = 0;
++ u32 exunencrypt = 0, privinvoked = 0, wpa = 0;
++ int ret = 0;
++
++ DEBUG(DBG_IOCTL, "GET AUTH\n");
++
++ /* first get the flags */
++ down(&priv->wpa_sem);
++ wpa = priv->wpa;
++ up(&priv->wpa_sem);
++
++ switch (param->flags & IW_AUTH_INDEX) {
++ case IW_AUTH_CIPHER_PAIRWISE:
++ case IW_AUTH_CIPHER_GROUP:
++ case IW_AUTH_KEY_MGMT:
++ /*
++ * wpa_supplicant will control these internally
++ */
++ ret = -EOPNOTSUPP;
++ break;
++
++ case IW_AUTH_WPA_VERSION:
++ switch (wpa) {
++ case DOT11_PRIV_INV_TKIP:
++ param->value = IW_AUTH_WPA_VERSION_WPA;
++ break;
++ case DOT11_PRIV_INV_AES_CCMP:
++ param->value = IW_AUTH_WPA_VERSION_WPA2;
++ break;
++ default:
++ param->value = IW_AUTH_WPA_VERSION_DISABLED;
++ break;
++ }
++ break;
++
++ case IW_AUTH_DROP_UNENCRYPTED:
++ ret = sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
++ (void *)&exunencrypt, sizeof(uint32_t));
++ if (ret >= 0)
++ param->value = exunencrypt > 0 ? 1 : 0;
++ break;
++
++ case IW_AUTH_80211_AUTH_ALG:
++ ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
++ (void *)&authen, sizeof(uint32_t));
++ if (ret >= 0) {
++ switch (authen) {
++ case DOT11_AUTH_OS:
++ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
++ break;
++ case DOT11_AUTH_BOTH:
++ case DOT11_AUTH_SK:
++ param->value = IW_AUTH_ALG_SHARED_KEY;
++ case DOT11_AUTH_NONE:
++ default:
++ param->value = 0;
++ break;
++ }
++ }
++ break;
++
++ case IW_AUTH_WPA_ENABLED:
++ param->value = wpa > 0 ? 1 : 0;
++ break;
++
++ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
++ ret = sm_drv_oid_get(dev, DOT11_OID_DOT1XENABLE,
++ (void *)&dot1x, sizeof(uint32_t));
++ if (ret >= 0)
++ param->value = dot1x > 0 ? 1 : 0;
++ break;
++
++ case IW_AUTH_PRIVACY_INVOKED:
++ ret = sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
++ (void *)&privinvoked, sizeof(uint32_t));
++ if (ret >= 0)
++ param->value = privinvoked > 0 ? 1 : 0;
++ break;
++
++ default:
++ return -EOPNOTSUPP;
++ }
++ return ret;
++}
++
++#define KEY_SIZE_WEP104 13 /* 104/128-bit WEP keys */
++#define KEY_SIZE_WEP40 5 /* 40/64-bit WEP keys */
++#define KEY_SIZE_TKIP 32 /* TKIP keys */
++
++static int sm_drv_set_encodeext(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu,
++ char *extra)
++{
++ struct iw_point *encoding = &wrqu->encoding;
++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
++ int idx, alg = ext->alg, set_key = 1;
++ int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
++ int ret = 0;
++
++ DEBUG(DBG_IOCTL, "SET ENCODEEXT\n");
++
++ /* Determine and validate the key index */
++ idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
++ if (idx) {
++ if (idx < 0 || idx > 3)
++ return -EINVAL;
++ } else {
++ ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
++ (void *)&idx, sizeof(uint32_t));
++ if (ret < 0)
++ goto out;
++ }
++
++ if (encoding->flags & IW_ENCODE_DISABLED)
++ alg = IW_ENCODE_ALG_NONE;
++
++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
++ /* Only set transmit key index here, actual
++ * key is set below if needed.
++ */
++ ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID,
++ (void *)&idx, sizeof(uint32_t));
++ set_key = ext->key_len > 0 ? 1 : 0;
++ }
++
++ if (set_key) {
++ switch (alg) {
++ case IW_ENCODE_ALG_NONE:
++ break;
++ case IW_ENCODE_ALG_WEP: {
++ struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
++ memset(key.key, 0, sizeof(key.key));
++ if (ext->key_len > KEY_SIZE_WEP104) {
++ ret = -EINVAL;
++ goto out;
++ }
++ if (ext->key_len > KEY_SIZE_WEP40)
++ key.length = KEY_SIZE_WEP104;
++ else
++ key.length = KEY_SIZE_WEP40;
++ memcpy(key.key, ext->key, ext->key_len);
++ ret = sm_drv_oid_set(dev, DOT11_OID_DEFKEYID + idx + 1,
++ (void *)&key,
++ sizeof(struct obj_key));
++ break;
++ }
++ case IW_ENCODE_ALG_TKIP:
++ case IW_ENCODE_ALG_CCMP: {
++ struct obj_stakey key;
++ memset(key.key, 0, sizeof(key.key));
++ if (alg == IW_ENCODE_ALG_TKIP)
++ key.type = DOT11_PRIV_TKIP;
++ else
++ key.type = DOT11_PRIV_AES_CCMP;
++ memcpy(key.address, ext->addr.sa_data, ETH_ALEN);
++ key.length = ext->key_len;
++ key.keyid = idx;
++ key.ext = 0;
++ memcpy(key.key, ext->key, ext->key_len);
++ ret = sm_drv_oid_set(dev, DOT11_OID_STAKEY,
++ (void *)&key,
++ sizeof(struct obj_stakey));
++ break;
++ }
++ default:
++ return -EINVAL;
++ }
++
++ if (ret < 0)
++ goto out;
++
++ }
++
++ /* Read the flags */
++ if (encoding->flags & IW_ENCODE_DISABLED) {
++ /* Encoding disabled,
++ * authen = DOT11_AUTH_OS;
++ * invoke = 0;
++ * exunencrypt = 0; */
++ }
++ if (encoding->flags & IW_ENCODE_OPEN) {
++ /* Encode but accept non-encoded packets. No auth */
++ invoke = 1;
++ }
++ if (encoding->flags & IW_ENCODE_RESTRICTED) {
++ /* Refuse non-encoded packets. Auth */
++ authen = DOT11_AUTH_BOTH;
++ invoke = 1;
++ exunencrypt = 1;
++ }
++
++ /* do the change if requested */
++ if (encoding->flags & IW_ENCODE_MODE) {
++ sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE,
++ (void *)&authen, sizeof(uint32_t));
++ sm_drv_oid_set(dev, DOT11_OID_PRIVACYINVOKED,
++ (void *)&invoke, sizeof(uint32_t));
++ sm_drv_oid_set(dev, DOT11_OID_EXUNENCRYPTED,
++ (void *)&exunencrypt, sizeof(uint32_t));
++ }
++
++ out:
++ return ret;
++}
++
++
++static int sm_drv_get_encodeext(struct net_device *dev,
++ struct iw_request_info *info,
++ union iwreq_data *wrqu,
++ char *extra)
++{
++ struct net_local *priv = netdev_priv(dev);
++ struct iw_point *encoding = &wrqu->encoding;
++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
++ int idx, max_key_len;
++ int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0, wpa = 0;
++ int ret = 0;
++
++ DEBUG(DBG_IOCTL, "GET ENCODEEXT\n");
++
++ /* first get the flags */
++ ret = sm_drv_oid_get(dev, DOT11_OID_AUTHENABLE,
++ (void *)&authen, sizeof(uint32_t));
++ ret |= sm_drv_oid_get(dev, DOT11_OID_PRIVACYINVOKED,
++ (void *)&invoke, sizeof(uint32_t));
++ ret |= sm_drv_oid_get(dev, DOT11_OID_EXUNENCRYPTED,
++ (void *)&exunencrypt, sizeof(uint32_t));
++ if (ret < 0)
++ goto out;
++
++ max_key_len = encoding->length - sizeof(*ext);
++ if (max_key_len < 0)
++ return -EINVAL;
++
++ idx = (encoding->flags & IW_ENCODE_INDEX) - 1;
++ if (idx) {
++ if (idx < 0 || idx > 3)
++ return -EINVAL;
++ } else {
++ ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID,
++ (void *)&idx, sizeof(uint32_t));
++ if (ret < 0)
++ goto out;
++ }
++
++ encoding->flags = idx + 1;
++ memset(ext, 0, sizeof(*ext));
++
++ switch (authen) {
++ case DOT11_AUTH_BOTH:
++ case DOT11_AUTH_SK:
++ wrqu->encoding.flags |= IW_ENCODE_RESTRICTED;
++ case DOT11_AUTH_OS:
++ default:
++ wrqu->encoding.flags |= IW_ENCODE_OPEN;
++ break;
++ }
++
++ down(&priv->wpa_sem);
++ wpa = priv->wpa;
++ up(&priv->wpa_sem);
++
++ if (authen == DOT11_AUTH_OS && !exunencrypt && !invoke && !wpa) {
++ /* No encryption */
++ ext->alg = IW_ENCODE_ALG_NONE;
++ ext->key_len = 0;
++ wrqu->encoding.flags |= IW_ENCODE_DISABLED;
++ } else {
++ struct obj_key *key;
++
++ ret = sm_drv_oid_get(dev, DOT11_OID_DEFKEYID + idx + 1,
++ (void *)&key, sizeof(struct obj_key));
++ if (ret < 0)
++ goto out;
++ if (max_key_len < key->length) {
++ ret = -E2BIG;
++ goto out;
++ }
++ memcpy(ext->key, key->key, key->length);
++ ext->key_len = key->length;
++
++ switch (key->type) {
++ case DOT11_PRIV_TKIP:
++ ext->alg = IW_ENCODE_ALG_TKIP;
++ break;
++ case DOT11_PRIV_AES_CCMP:
++ ext->alg = IW_ENCODE_ALG_CCMP;
++ break;
++ default:
++ case DOT11_PRIV_WEP:
++ ext->alg = IW_ENCODE_ALG_WEP;
++ break;
++ }
++ wrqu->encoding.flags |= IW_ENCODE_ENABLED;
++ }
++
++ out:
++ return ret;
++}
+
+ /* Private handlers */
+
+@@ -2155,10 +2581,10 @@
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) sm_drv_set_genie, /* SIOCSIWGENIE*/
+ (iw_handler) NULL, /* SIOCGIWGENIE */
+- (iw_handler) NULL, /* SIOCSIWAUTH */
+- (iw_handler) NULL, /* SIOCGIWAUTH */
+- (iw_handler) NULL, /* SIOCSIWENCODEEXT */
+- (iw_handler) NULL, /* SIOCGIWENCODEEXT */
++ (iw_handler) sm_drv_set_auth, /* SIOCSIWAUTH */
++ (iw_handler) sm_drv_get_auth, /* SIOCGIWAUTH */
++ (iw_handler) sm_drv_set_encodeext, /* SIOCSIWENCODEEXT */
++ (iw_handler) sm_drv_get_encodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) sm_drv_set_pmk, /* SIOCSIWPMKSA */
+ };
+
diff --git a/packages/mamona/cx3110x-0.8.1/fix_cross_makefile.patch b/packages/mamona/cx3110x-0.8.1/fix_cross_makefile.patch
new file mode 100644
index 0000000000..1f75f094b8
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/fix_cross_makefile.patch
@@ -0,0 +1,11 @@
+Index: cx3110x-0.8.1/src/Makefile
+===================================================================
+--- cx3110x-0.8.1.orig/src/Makefile 2008-04-28 15:58:24.000000000 -0300
++++ cx3110x-0.8.1/src/Makefile 2008-04-28 15:58:28.000000000 -0300
+@@ -1,5 +1,5 @@
+ ifeq ($(KERNELRELEASE),)
+-STRIP = arm-linux-strip
++STRIP = $(CROSS_COMPILE)strip
+ PWD := $(shell pwd)
+
+ .PHONY: modules clean
diff --git a/packages/mamona/cx3110x-0.8.1/fix_mem_allign.patch b/packages/mamona/cx3110x-0.8.1/fix_mem_allign.patch
new file mode 100644
index 0000000000..6c452196aa
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/fix_mem_allign.patch
@@ -0,0 +1,94 @@
+Index: cx3110x-0.8.1/src/sm_drv_spi_io.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.c 2008-04-22 14:54:42.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_spi_io.c 2008-04-22 15:00:07.000000000 -0300
+@@ -240,18 +240,21 @@
+ omap_start_dma(spi_dma.dma_tx_ch);
+
+ /* We don't want to turn CS off before transfer is done */
+-
++
++ while(!spi_dma.dma_rx_done) {
++ udelay(5);
++ }
++
+ while(!spi_dma.dma_tx_done) {
+ udelay(5);
+ }
+
++ spi_dma.dma_rx_done = 0;
+ spi_dma.dma_tx_done = 0;
+
+ /* UMAC may send us odd number of bytes long frames */
+ if (length % 2) {
+- u16 last_word;
+-
+- last_word = *(uint16_t *)(buffer + length - 1);
++ u16 last_word = *((uint8_t *)buffer + length - 1);
+ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, last_word);
+ }
+
+@@ -264,7 +267,6 @@
+ int cx3110x_spi_read(struct net_device *dev, unsigned long address, unsigned char * buffer, unsigned int length)
+ {
+ int i;
+- u16 * short_buffer = (u16 *) buffer;
+ unsigned int r_length = length >> 1;
+
+ DEBUG(DBG_SPI_IO, "omap_wlan_spi_read\n");
+@@ -274,8 +276,13 @@
+ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2,
+ (address << 8) | ADDR_READ_BIT_15);
+
+- for (i = 0 ; i < r_length ; i++)
+- omap_mcbsp_spi_master_recv_word_poll(OMAP_MCBSP2, (u32*)(short_buffer + i));
++ for (i = 0 ; i < r_length ; i++) {
++ u32 tmp;
++ omap_mcbsp_spi_master_recv_word_poll(OMAP_MCBSP2, &tmp);
++ /* Assume little endian byte order */
++ buffer[i * 2 + 0] = tmp & 0xFF;
++ buffer[i * 2 + 1] = (tmp >> 8) & 0xFF;
++ }
+
+ SPI_CS_OFF();
+ return 0;
+@@ -285,24 +292,22 @@
+ int cx3110x_spi_write(struct net_device *dev, unsigned long address, unsigned char * buffer, unsigned int length)
+ {
+ int i;
+- u16 * short_buffer = (u16 *) buffer;
+ unsigned int w_length = length >> 1;
+
+-
+ DEBUG(DBG_SPI_IO, "omap_wlan_spi_write (%d bytes @ 0x%lx)\n", length, address << 8);
+
+ SPI_CS_ON();
+
+ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, address << 8);
+
+- for (i = 0 ; i < w_length ; i++)
+- omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, short_buffer[i]);
++ for (i = 0 ; i < w_length ; i++) {
++ /* Assume little endian byte order */
++ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, (u32)buffer[i * 2] | ((u32)buffer[i * 2 + 1] << 8));
++ }
+
+ /* UMAC may send us odd number of bytes long frames */
+ if (length % 2) {
+- u16 last_word;
+-
+- last_word = buffer[length - 1];
++ u16 last_word = buffer[length - 1];
+ omap_mcbsp_spi_master_xmit_word_poll(OMAP_MCBSP2, last_word);
+ }
+
+@@ -366,6 +371,9 @@
+ while(rate_mhz/div >= max_mhz)
+ div++;
+
++ printk("McBSP2: freq_limit=%dMHz, base_freq=%dMHz, divisor=%d (%d.%dMHz)\n",
++ max_mhz, rate_mhz, div, rate_mhz / div, (rate_mhz * 10 / div) % 10);
++
+ spi_dma.dma_tx_done = 0;
+ spi_dma.dma_rx_done = 0;
+
diff --git a/packages/mamona/cx3110x-0.8.1/fix_mem_corruption.patch b/packages/mamona/cx3110x-0.8.1/fix_mem_corruption.patch
new file mode 100644
index 0000000000..ae3e87f427
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/fix_mem_corruption.patch
@@ -0,0 +1,53 @@
+Index: cx3110x-0.8.1/src/sm_drv_spi_io.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_spi_io.c 2007-10-15 08:56:20.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_spi_io.c 2008-04-22 14:53:49.000000000 -0300
+@@ -91,7 +91,7 @@
+ int dma_tx_done;
+ int dma_rx_done;
+
+- uint16_t recv_buffer;
++ uint16_t *recv_buffer;
+ };
+
+ static struct omap_wlan_spi_dma spi_dma;
+@@ -142,7 +142,7 @@
+ omap_set_dma_src_params(spi_dma.dma_tx_ch,
+ OMAP_DMA_PORT_EMIFF,
+ OMAP_DMA_AMODE_CONSTANT,
+- virt_to_phys(&spi_dma.recv_buffer),
++ virt_to_phys(spi_dma.recv_buffer),
+ 0, 0);
+
+ /* Prepare for reading */
+@@ -208,7 +208,7 @@
+ omap_set_dma_dest_params(spi_dma.dma_rx_ch,
+ OMAP_DMA_PORT_EMIFF,
+ OMAP_DMA_AMODE_CONSTANT,
+- virt_to_phys(&spi_dma.recv_buffer),
++ virt_to_phys(spi_dma.recv_buffer),
+ 0, 0);
+
+
+@@ -319,6 +319,12 @@
+ struct net_local * lp;
+ struct spi_hif_local_data * spi_lp;
+
++ spi_dma.recv_buffer = kmalloc(sizeof(*spi_dma.recv_buffer), GFP_ATOMIC);
++ if (!spi_dma.recv_buffer) {
++ printk("spi_dma.recv_buffer allocation failed\n");
++ return -1;
++ }
++
+ lp = dev->priv;
+ spi_lp = HIF_LP(lp);
+
+@@ -411,6 +417,8 @@
+ omap_free_gpio(wlan_config->irq_gpio);
+ omap_free_dma(spi_dma.dma_tx_ch);
+ omap_free_dma(spi_dma.dma_rx_ch);
++
++ kfree(spi_dma.recv_buffer);
+ }
+
+
diff --git a/packages/mamona/cx3110x-0.8.1/fix_ssid_data_length.patch b/packages/mamona/cx3110x-0.8.1/fix_ssid_data_length.patch
new file mode 100644
index 0000000000..a9e36ce6dd
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/fix_ssid_data_length.patch
@@ -0,0 +1,13 @@
+Index: cx3110x-0.8.1/src/sm_drv_ioctl_umac.c
+===================================================================
+--- cx3110x-0.8.1.orig/src/sm_drv_ioctl_umac.c 2008-04-28 15:59:37.000000000 -0300
++++ cx3110x-0.8.1/src/sm_drv_ioctl_umac.c 2008-04-28 15:59:57.000000000 -0300
+@@ -171,7 +171,7 @@
+ /* The following entries will be displayed in the same order we give them */
+
+ /* The ESSID. */
+- iwe.u.data.length = strlen(bss->ssid);
++ iwe.u.data.length = strlen(bss->ssid + 1);
+ iwe.u.data.flags = 1;
+ iwe.cmd = SIOCGIWESSID;
+ current_ev = iwe_stream_add_point(current_ev, end_buf,
diff --git a/packages/mamona/cx3110x-0.8.1/nokia770/defconfig b/packages/mamona/cx3110x-0.8.1/nokia770/defconfig
new file mode 100644
index 0000000000..7119b50f34
--- /dev/null
+++ b/packages/mamona/cx3110x-0.8.1/nokia770/defconfig
@@ -0,0 +1,1380 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16.27-omap1
+# Fri Apr 18 16:19:13 2008
+#
+CONFIG_ARM=y
+CONFIG_MMU=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set