Start a Conversation

Unsolved

This post is more than 5 years old

D

163424

May 19th, 2015 14:00

Upgrading to 3.19 kernel with Dell factory 14.04 image

In various other threads, myself and other community members have been working out how best to handle the 14.04 issues with the Dell XPS 13 (9343) (Early 2015).  I have tried a number of solutions, but ultimately have arrived to the conclusion that upgrading the 3.13 kernel to 3.19 via the testing LTS kernel repository is the best upgrade path thus far.

Disclaimer: This upgrade process as described in this post will cause wireless to stop working.  I believe this is a Broadcom driver problem.  Hopefully I can get some assistance with installing these drivers back from Dell ProSupport later today.


Update:
To fix the wireless issue, connect your computer to the internet either using a USB to ethernet adapter or use your phone as a mobile hotspot, then run `sudo apt-get update` and `sudo apt-get upgrade`.  This lengthy upgrade will restore wifi functionality.  (See response below)

This guide will fix:

  • Touchpad glitchiness
  • Touchpad two-finger/click commands -- e.g. two figner drag, single finger right click will work.
  • Keyboard repeating keystrokes (I have had repeating keystrokes once thus far, so not totally fixed but they are very few and far between)
  • Graphics lag/choppiness

Steps:

1. Reset to Factory Defaults.

Here is a lsb_release -a and uname -a at factory defaults:

gshulegaard@ronin:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04 LTS
Release: 14.04
Codename: trusty
gshulegaard@ronin:~$ uname -a
Linux ronin 3.13.0-37-generic #64bdw1-Ubuntu SMP Thu Sep 25 14:01:25 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
gshulegaard@ronin:~$

2. Do an apt-get update/upgrade.

$ sudo apt-get update
$ sudo apt-get upgrade

3. There will be depency problems, so do a -f:

$ sudo apt-get -f install

At this point, your lsb_release and uname should have changed:

gshulegaard@ronin:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.2 LTS
Release: 14.04
Codename: trusty
gshulegaard@ronin:~$ uname -a
Linux ronin 3.13.0-37-generic #64bdw1-Ubuntu SMP Thu Sep 25 14:01:25 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
gshulegaard@ronin:~$

4. Add the kernel testing repository and install 3.19:

sudo add-apt-repository ppa:canonical-kernel-team/ppa
sudo apt-get update
sudo apt-get install linux-generic-lts-vivid
sudo reboot
That's it, your lsb_release and uname should now look like:

gshulegaard@ronin:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.2 LTS
Release: 14.04
Codename: trusty
gshulegaard@ronin:~$ uname -a
Linux ronin 3.19.0-17-generic #17~14.04.1-Ubuntu SMP Thu May 7 11:05:22 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
gshulegaard@ronin:~$
The last thing for me to sort out is how to restore wireless functionality and I will update here as soon as that is sorted.



Update: After connecting to ethernet and doing an "apt-get update" and an "apt-get upgrade" I am happy to report that all is well. The machine works smoothly. I haven't had an issue with Suspend/Resume after doing an in place kernel upgrade, but it is the only issue that is outstanding as far as I can tell.

May 25th, 2015 21:00

Sorry for the delayed response, this response got lost in my e-mail box.

I am surprised that you can see those packages in Synaptic without first adding the testing ppa.  It is my understanding that the 3.19 enablement kernel is in testing/beta and is due for official release/support by Canonical (for 14.04.3) sometime in September.

That said, if you can see them, then I don't see any reason why you couldn't use Synaptic package manger to handle the installation rather than my apt-get approach.

9 Posts

May 25th, 2015 22:00

 ⚡ root@flatish  ~/  lsb_release -a
No LSB modules are available.
Distributor ID:    Ubuntu
Description:    Ubuntu 14.04.2 LTS
Release:    14.04
Codename:    trusty
 ⚡ root@flatish  ~/  uname -a
Linux flatish 4.1.0-040100rc5-generic #201505250235 SMP Mon May 25 02:37:02 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Working amazing so far. Only hiccup was the a few lines of code in the broadcom driver which was pretty easy to fix up.

22 Posts

May 26th, 2015 00:00

Thanks - nice to know.

I can find the files on both my Linux Pc's, so I pretty sure I haven't added the testing ppa.

Gert

Now I have updated to kernel 3.19 by using Synaptic and every thing is working just fine - even the Wifi functioned right away. By this update the XPS13 DE is really a fine PC. 

May 26th, 2015 16:00

Another thing to do would be to upgrade your BIOS to A04, which will resolve the keyboard key repeat issues (at least it did for me).

The last outstanding issue that I know about is kernel panic (blinking CAPS LOCK) and/or sluggish performance when resuming from Suspend.  I have read elsewhere that this may be an Intel chipset problem though as it has been affecting other machines with the new Intel Broadwell chips.  Although, I have yet to see a kernel panic since I upgraded my BIOS to A04, so here is to keeping my fingers crossed that the new BIOS fixed this problem.

But I agree, the XPS 13 DE (9343) is really beautiful now that everything is working smoothly.  The battery life and 4K screen really make this machine for me.

80 Posts

May 26th, 2015 16:00

<< Only hiccup was the a few lines of code in the broadcom driver which was pretty easy to fix up. >>

What exactly do you mean by this?

I get occasional system panics when switching WiFi. I wonder if whatever you did would fix that.

For the broadcom, to get Bluetooth working properly I had to pull down the Windows driver and extract firmware from the CAB. Is that what you did?

9 Posts

May 26th, 2015 17:00

Here is the patch file I added to dkms for the bcmwl driver

 ⚡ root@flatish  /usr/src/bcmwl-6.30.223.248+bdcom/patches  cat 0016-add-support-for-Linux-4.patch
--- a/src/wl/sys/wl_cfg80211_hybrid.c    2014-06-26 10:42:08.000000000 +0000
+++ b/src/wl/sys/wl_cfg80211_hybrid.c    2014-12-30 17:02:13.602127370 +0000
@@ -63,8 +63,13 @@
 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
            struct cfg80211_ibss_params *params);
 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
            struct net_device *dev, u8 *mac, struct station_info *sinfo);
+#else
+static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
+           struct net_device *dev, const u8 *mac, struct station_info *sinfo);
+#endif
 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
            struct net_device *dev, bool enabled, s32 timeout);
 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
@@ -1387,7 +1392,7 @@
     key_endian_to_host(&key);
 
     params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
-    memcpy(params.key, key.data, params.key_len);
+    memcpy((char *)params.key, key.data, params.key_len);
 
     if ((err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
         return err;
@@ -1421,9 +1426,15 @@
     return err;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
 static s32
 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
                         u8 *mac, struct station_info *sinfo)
+#else
+static s32
+wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+                        const u8 *mac, struct station_info *sinfo)
+#endif
 {
     struct wl_cfg80211_priv *wl = wiphy_to_wl(wiphy);
     scb_val_t scb_val;
@@ -2629,7 +2665,15 @@
 
 void wl_cfg80211_detach(struct net_device *ndev)
 {
-    struct wl_cfg80211_priv *wl = ndev_to_wl(ndev);
+    struct wl_cfg80211_priv *wl;
+    struct wireless_dev *wdev;
+    
+    wdev = ndev->ieee80211_ptr;
+    if (wdev == NULL) {
+                printk(KERN_ERR "[%s()] in ndev=%p: IEEE80211ptr=%p\n", __FUNCTION__, ndev, wdev);
+                return;
+        }
+    wl = ndev_to_wl(ndev);
 
     wl_deinit_cfg80211_priv(wl);
     wl_free_wdev(wl);
--- a/src/wl/sys/wl_cfg80211_hybrid.c    2015-03-16 14:39:29.899350026 +0100
+++ b/src/wl/sys/wl_cfg80211_hybrid.c    2015-03-16 14:39:06.732682365 +0100
@@ -1452,7 +1452,11 @@
         WL_DBG(("Could not get rate (%d)\n", err));
     } else {
         rate = dtoh32(rate);
+        #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+        sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
+        #else
         sinfo->filled |= STATION_INFO_TX_BITRATE;
+        #endif
         sinfo->txrate.legacy = rate * 5;
         WL_DBG(("Rate %d Mbps\n", (rate / 2)));
     }
@@ -1465,7 +1469,11 @@
             return err;
         }
         rssi = dtoh32(scb_val.val);
+        #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+        sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
+        #else
         sinfo->filled |= STATION_INFO_SIGNAL;
+        #endif
         sinfo->signal = rssi;
         WL_DBG(("RSSI %d dBm\n", rssi));
     }
--- a/src/wl/sys/wl_dbg.h    2014-06-26 10:42:08.000000000 +0000
+++ b/src/wl/sys/wl_dbg.h    2014-12-30 17:02:03.840957429 +0000
@@ -55,10 +55,12 @@
 
 #define WL_NONE(args)
 
+#define FORCE_TRACE_LEVEL(fmt, ...) do { printk(KERN_ERR fmt, ## __VA_ARGS__); } while (0) /* ## is GCC specific syntax to remove comma when single arg */
+
 #ifdef BCMDBG_ERR
 #define    WL_ERROR(args)        WL_PRINT(args)
 #else
-#define    WL_ERROR(args)
+#define    WL_ERROR(args)        FORCE_TRACE_LEVEL args
 #endif
 #define    WL_TRACE(args)
 #define WL_APSTA_UPDN(args)
--- a/src/wl/sys/wl_linux.c    2014-06-26 10:42:08.000000000 +0000
+++ b/src/wl/sys/wl_linux.c    2014-12-30 17:02:03.841957446 +0000
@@ -878,7 +878,7 @@ wl_remove(struct pci_dev *pdev)
 static SIMPLE_DEV_PM_OPS(wl_pm_ops, wl_suspend, wl_resume);
 #endif
 
-static struct pci_driver wl_pci_driver = {
+static struct pci_driver wl_pci_driver __refdata = {
     .name =        "wl",
     .probe =    wl_pci_probe,
     .remove =    __devexit_p(wl_remove),
@@ -1270,6 +1270,7 @@ wl_free_if(wl_info_t *wl, wl_if_t *wlif)
         MFREE(wl->osh, wlif->dev, sizeof(struct net_device));
 #else
         free_netdev(wlif->dev);
+        wlif->dev = NULL;
 #endif
     }
 
@@ -1651,11 +1657,7 @@ wl_ioctl(struct net_device *dev, struct
     }
 
     WL_LOCK(wl);
-    if (!capable(CAP_NET_ADMIN)) {
-        bcmerror = BCME_EPERM;
-    } else {
-        bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
-    }
+    bcmerror = wlc_ioctl(wl->wlc, ioc.cmd, buf, ioc.len, wlif->wlcif);
     WL_UNLOCK(wl);
 
 done1:
@@ -2157,8 +2159,8 @@ wl_start(struct sk_buff *skb, struct net
     wlif = WL_DEV_IF(dev);
     wl = WL_INFO(dev);
 
+    skb->prev = NULL;
     if (WL_ALL_PASSIVE_ENAB(wl) || (WL_RTR() && WL_CONFIG_SMP())) {
-        skb->prev = NULL;
 
         TXQ_LOCK(wl);
 
@@ -2455,8 +2457,10 @@ wl_monitor(wl_info_t *wl, wl_rxsts_t *rx
         p80211msg_t *phdr;
 
         len = sizeof(p80211msg_t) + oskb->len - D11_PHY_HDR_LEN;
-        if ((skb = dev_alloc_skb(len)) == NULL)
+        if ((skb = dev_alloc_skb(len)) == NULL) {
+            WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
             return;
+        }
 
         skb_put(skb, len);
         phdr = (p80211msg_t*)skb->data;
@@ -2535,8 +2539,10 @@ wl_monitor(wl_info_t *wl, wl_rxsts_t *rx
             rtap_len = sizeof(wl_radiotap_ht_brcm_2_t);
 
         len = rtap_len + (oskb->len - D11_PHY_HDR_LEN);
-        if ((skb = dev_alloc_skb(len)) == NULL)
+        if ((skb = dev_alloc_skb(len)) == NULL) {
+            WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
             return;
+        }
 
         skb_put(skb, len);
 
@@ -2664,8 +2670,10 @@ wl_monitor(wl_info_t *wl, wl_rxsts_t *rx
             len += amsdu_len;
         }
 
-        if ((skb = dev_alloc_skb(len)) == NULL)
+        if ((skb = dev_alloc_skb(len)) == NULL) {
+            WL_ERROR(("in %s:%d [%s()] dev_alloc_skb() failure!", __FILE__, __LINE__, __FUNCTION__));
             return;
+        }
 
         skb_put(skb, len);
 
@@ -2990,7 +2998,7 @@ _wl_del_monitor(wl_task_t *task)
 }
 
 void
-wl_set_monitor(wl_info_t *wl, int val)
+wl_set_monitor(wl_info_t *wl, int val) /* public => is called by wlc_hybrid.o_shipped */
 {
     const char *devname;
     wl_if_t *wlif;
@@ -3224,42 +3232,75 @@ wl_linux_watchdog(void *ctx)
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 static int
 wl_proc_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+{
+    wl_info_t * wl = (wl_info_t *)data;
 #else
 static ssize_t
-wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *data)
-#endif
+wl_proc_read(struct file *filp, char __user *buffer, size_t length, loff_t *offp)
 {
-    wl_info_t * wl = (wl_info_t *)data;
-    int to_user;
-    int len;
+    wl_info_t * wl = PDE_DATA(file_inode(filp));
+#endif
+    int bcmerror, len;
+    int to_user = 0;
+    char tmp:emotion-29:;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
     if (offset > 0) {
         *eof = 1;
         return 0;
     }
+#else
+    if (*offp > 0) { /* for example, stop: cat /proc/brcm_monitor0 */
+        return 0; /* 0 <=> EOF */
+    }
 #endif
 
-    if (!length) {
-        WL_ERROR(("%s: Not enough return buf space\n", __FUNCTION__));
-        return 0;
-    }
     WL_LOCK(wl);
-    wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
-    len = sprintf(buffer, "%d\n", to_user);
-    WL_UNLOCK(wl);
-    return len;
+    bcmerror = wlc_ioctl(wl->wlc, WLC_GET_MONITOR, &to_user, sizeof(int), NULL);
+     WL_UNLOCK(wl);
+
+    if (bcmerror != BCME_OK) {
+        WL_ERROR(("%s: GET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
+        return -EIO;
+    }
+
+     len = snprintf(tmp, ARRAY_SIZE(tmp), "%d\n", to_user);
+    tmp[ARRAY_SIZE(tmp) - 1] = '\0';
+    if (len >= ARRAY_SIZE(tmp)) {
+        printk(KERN_ERR "%s:%d [%s()] output would be truncated (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
+        return -ERANGE;
+    }
+    else if (len < 0) {
+        printk(KERN_ERR "%s:%d [%s()] unable to convert value (ret=%d)!", __FILE__, __LINE__, __FUNCTION__, len);
+        return len;
+    }
+    if (length < len) {
+        printk(KERN_ERR "%s:%d [%s()] user buffer is too small (at least=%d ; user=%d)!", __FILE__, __LINE__, __FUNCTION__, len, (int)length);
+        return -EMSGSIZE;
+    }
+    if (copy_to_user(buffer, tmp, len) != 0) {
+        printk(KERN_ERR "%s:%d [%s()] unable to copy data!", __FILE__, __LINE__, __FUNCTION__);
+        return -EFAULT;
+    }
+    
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+    *offp += len;
+#endif
+
+     return len;
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
 static int
 wl_proc_write(struct file *filp, const char *buff, unsigned long length, void *data)
+{
+    wl_info_t * wl = (wl_info_t *)data;
 #else
 static ssize_t
-wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *data)
-#endif
+wl_proc_write(struct file *filp, const char __user *buff, size_t length, loff_t *offp)
 {
-    wl_info_t * wl = (wl_info_t *)data;
+    wl_info_t * wl = PDE_DATA(file_inode(filp));
+#endif
     int from_user = 0;
     int bcmerror;
 
@@ -3270,7 +3311,11 @@ wl_proc_write(struct file *filp, const c
     }
     if (copy_from_user(&from_user, buff, 1)) {
         WL_ERROR(("%s: copy from user failed\n", __FUNCTION__));
-        return -EIO;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
+         return -EIO;
+#else
+        return -EFAULT;
+#endif
     }
 
     if (from_user >= 0x30)
@@ -3280,10 +3325,15 @@ wl_proc_write(struct file *filp, const c
     bcmerror = wlc_ioctl(wl->wlc, WLC_SET_MONITOR, &from_user, sizeof(int), NULL);
     WL_UNLOCK(wl);
 
-    if (bcmerror < 0) {
+    if (bcmerror != BCME_OK) {
         WL_ERROR(("%s: SET_MONITOR failed with %d\n", __FUNCTION__, bcmerror));
         return -EIO;
     }
+    
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && 0 /* no need to update offset because this file should only trigger action... */
+    *offp += length;
+#endif
+
     return length;
 }
 
@@ -3304,8 +3354,8 @@ wl_reg_proc_entry(wl_info_t *wl)
     if ((wl->proc_entry = create_proc_entry(tmp, 0644, NULL)) == NULL) {
         WL_ERROR(("%s: create_proc_entry %s failed\n", __FUNCTION__, tmp));
 #else
-    if ((wl->proc_entry = proc_create(tmp, 0644, NULL, &wl_fops)) == NULL) {
-        WL_ERROR(("%s: proc_create %s failed\n", __FUNCTION__, tmp));
+    if ((wl->proc_entry = proc_create_data(tmp, 0644, NULL, &wl_fops, wl)) == NULL) {
+        WL_ERROR(("%s: proc_create_data %s failed\n", __FUNCTION__, tmp));
 #endif
         ASSERT(0);
         return -1;

80 Posts

May 26th, 2015 20:00

OK, but what does this do?

22 Posts

May 27th, 2015 00:00

You are right. I upgraded my BIOS to A04 before the kernel update.

17 Posts

May 27th, 2015 11:00

The vivid kernel has made it into the trusty-updates repository. No need to add the PPA, just:

$sudo apt-get install linux-generic-lts-vivid

A note to M3800 owners:

  • this kernel enables the Thunderbolt 2 port (I needed to change the BIOS Thunderbolt security setting to No Security in order to fully use a OWC Thunderbolt dock).
  • It also requires a newer Nvidia driver than nvidia-331 (I got nvidia-352 from the xorg-edgers PPA, resulting in worsening performance).
  • If you also use VMWare workstation, there is a known bug in the vmnet module, which requires a patch to be applied, as described here: https://wiki.archlinux.org/index.php/VMware#3.19_kernels_and_up

Final note - I had problems (including kernel 3.19) with Realtek-based USB 3.0 Gigabit Ethernet adapters (the one Dell sends with the power supply uses that chipset). The solution is to upgrade the driver from Realtek's web site: http://www.realtek.com/downloads/downloadsView.aspx?Langid=1&PNid=13&PFid=56&Level=5&Conn=4&DownTypeID=3&GetDown=false#2

22 Posts

May 27th, 2015 12:00

Yesterday I found every thing was working well and it's still better with kernel 3.19 but I have lost audio on hdmi and can't figure out how to get it back. Hope I will get some help from you.

No Events found!

Top