008-fix_virtual_interfaces.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. --- a/driver/wl_linux.c
  2. +++ b/driver/wl_linux.c
  3. @@ -354,6 +354,7 @@ static int wl_read_proc(char *buffer, ch
  4. static int wl_dump(wl_info_t *wl, struct bcmstrbuf *b);
  5. #endif /* BCMDBG */
  6. struct wl_if *wl_alloc_if(wl_info_t *wl, int iftype, uint unit, struct wlc_if* wlc_if);
  7. +static void wl_link_if(wl_info_t *wl, wl_if_t *wlif);
  8. static void wl_free_if(wl_info_t *wl, wl_if_t *wlif);
  9. @@ -566,6 +567,9 @@ wl_attach(uint16 vendor, uint16 device,
  10. wl->dev = dev;
  11. wl_if_setup(dev);
  12. + /* add the interface to the interface linked list */
  13. + wl_link_if(wl, wlif);
  14. +
  15. /* map chip registers (47xx: and sprom) */
  16. dev->base_addr = regs;
  17. @@ -1106,10 +1110,14 @@ wl_free(wl_info_t *wl)
  18. free_irq(wl->dev->irq, wl);
  19. }
  20. - if (wl->dev) {
  21. - wl_free_if(wl, WL_DEV_IF(wl->dev));
  22. - wl->dev = NULL;
  23. + /* free all interfaces */
  24. + while (wl->if_list) {
  25. + if ((wl->if_list->dev != wl->dev) || wl->if_list->next == NULL)
  26. + wl_free_if(wl, wl->if_list);
  27. + else
  28. + wl_free_if(wl, wl->if_list->next);
  29. }
  30. + wl->dev = NULL;
  31. #ifdef TOE
  32. wl_toe_detach(wl->toei);
  33. @@ -1355,10 +1363,12 @@ wl_txflowcontrol(wl_info_t *wl, bool sta
  34. ASSERT(prio == ALLPRIO);
  35. for (wlif = wl->if_list; wlif != NULL; wlif = wlif->next) {
  36. - if (state == ON)
  37. - netif_stop_queue(wlif->dev);
  38. - else
  39. - netif_wake_queue(wlif->dev);
  40. + if (wlif->dev_registed) {
  41. + if (state == ON)
  42. + netif_stop_queue(wlif->dev);
  43. + else
  44. + netif_wake_queue(wlif->dev);
  45. + }
  46. }
  47. }
  48. @@ -1398,7 +1408,6 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
  49. {
  50. struct net_device *dev;
  51. wl_if_t *wlif;
  52. - wl_if_t *p;
  53. dev = alloc_etherdev(sizeof(wl_if_t));
  54. wlif = netdev_priv(dev);
  55. @@ -1411,9 +1420,13 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
  56. wlif->wlcif = wlcif;
  57. wlif->subunit = subunit;
  58. - /* match current flow control state */
  59. - if (iftype != WL_IFTYPE_MON && wl->dev && netif_queue_stopped(wl->dev))
  60. - netif_stop_queue(dev);
  61. + return wlif;
  62. +}
  63. +
  64. +static void
  65. +wl_link_if(wl_info_t *wl, wl_if_t *wlif)
  66. +{
  67. + wl_if_t *p;
  68. /* add the interface to the interface linked list */
  69. if (wl->if_list == NULL)
  70. @@ -1424,7 +1437,6 @@ wl_alloc_if(wl_info_t *wl, int iftype, u
  71. p = p->next;
  72. p->next = wlif;
  73. }
  74. - return wlif;
  75. }
  76. static void
  77. @@ -1504,6 +1516,9 @@ _wl_add_if(wl_task_t *task)
  78. wl_info_t *wl = wlif->wl;
  79. struct net_device *dev = wlif->dev;
  80. + /* add the interface to the interface linked list */
  81. + wl_link_if(wl, wlif);
  82. +
  83. if (wlif->type == WL_IFTYPE_WDS)
  84. dev->netdev_ops = &wl_wds_ops;
  85. @@ -1516,6 +1531,14 @@ _wl_add_if(wl_task_t *task)
  86. }
  87. wlif->dev_registed = TRUE;
  88. + /* match current flow control state */
  89. + if (wl->dev) {
  90. + if (netif_queue_stopped(wl->dev))
  91. + netif_stop_queue(dev);
  92. + else
  93. + netif_wake_queue(dev);
  94. + }
  95. +
  96. done:
  97. MFREE(wl->osh, task, sizeof(wl_task_t));
  98. atomic_dec(&wl->callbacks);
  99. @@ -1545,6 +1568,8 @@ wl_add_if(wl_info_t *wl, struct wlc_if*
  100. return NULL;
  101. }
  102. + wl_if_setup(wlif->dev);
  103. +
  104. sprintf(wlif->dev->name, "%s%d.%d", devname, wl->pub->unit, wlif->subunit);
  105. if (remote)
  106. bcopy(remote, &wlif->remote, ETHER_ADDR_LEN);
  107. @@ -2778,6 +2803,9 @@ wl_add_monitor(wl_task_t *task)
  108. dev = wlif->dev;
  109. wl->monitor = dev;
  110. + /* add the interface to the interface linked list */
  111. + wl_link_if(wl, wlif);
  112. +
  113. /* override some fields */
  114. sprintf(dev->name, "prism%d", wl->pub->unit);
  115. bcopy(wl->dev->dev_addr, dev->dev_addr, ETHER_ADDR_LEN);