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