diff options
Diffstat (limited to 'drivers/net')
296 files changed, 11857 insertions, 6749 deletions
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index dd5e04813b76..545c09ed9079 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c | |||
@@ -936,7 +936,7 @@ static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
936 | { | 936 | { |
937 | struct cops_local *lp = netdev_priv(dev); | 937 | struct cops_local *lp = netdev_priv(dev); |
938 | struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; | 938 | struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr; |
939 | struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr; | 939 | struct atalk_addr *aa = &lp->node_addr; |
940 | 940 | ||
941 | switch(cmd) | 941 | switch(cmd) |
942 | { | 942 | { |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 3463b469e657..3031e0413114 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2460,18 +2460,21 @@ out: | |||
2460 | return NETDEV_TX_OK; | 2460 | return NETDEV_TX_OK; |
2461 | } | 2461 | } |
2462 | 2462 | ||
2463 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, | 2463 | int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, |
2464 | struct slave *slave) | 2464 | struct slave *slave) |
2465 | { | 2465 | { |
2466 | int ret = RX_HANDLER_ANOTHER; | 2466 | int ret = RX_HANDLER_ANOTHER; |
2467 | struct lacpdu *lacpdu, _lacpdu; | ||
2468 | |||
2467 | if (skb->protocol != PKT_TYPE_LACPDU) | 2469 | if (skb->protocol != PKT_TYPE_LACPDU) |
2468 | return ret; | 2470 | return ret; |
2469 | 2471 | ||
2470 | if (!pskb_may_pull(skb, sizeof(struct lacpdu))) | 2472 | lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu); |
2473 | if (!lacpdu) | ||
2471 | return ret; | 2474 | return ret; |
2472 | 2475 | ||
2473 | read_lock(&bond->lock); | 2476 | read_lock(&bond->lock); |
2474 | ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); | 2477 | ret = bond_3ad_rx_indication(lacpdu, slave, skb->len); |
2475 | read_unlock(&bond->lock); | 2478 | read_unlock(&bond->lock); |
2476 | return ret; | 2479 | return ret; |
2477 | } | 2480 | } |
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 5ee7e3c45db7..0cfaa4afdece 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -274,8 +274,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave); | |||
274 | void bond_3ad_handle_link_change(struct slave *slave, char link); | 274 | void bond_3ad_handle_link_change(struct slave *slave, char link); |
275 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); | 275 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); |
276 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); | 276 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); |
277 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond, | 277 | int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, |
278 | struct slave *slave); | 278 | struct slave *slave); |
279 | int bond_3ad_set_carrier(struct bonding *bond); | 279 | int bond_3ad_set_carrier(struct bonding *bond); |
280 | void bond_3ad_update_lacp_rate(struct bonding *bond); | 280 | void bond_3ad_update_lacp_rate(struct bonding *bond); |
281 | #endif //__BOND_3AD_H__ | 281 | #endif //__BOND_3AD_H__ |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 0f59c1564e53..ef3791a09ad8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
342 | _unlock_rx_hashtbl_bh(bond); | 342 | _unlock_rx_hashtbl_bh(bond); |
343 | } | 343 | } |
344 | 344 | ||
345 | static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, | 345 | static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond, |
346 | struct slave *slave) | 346 | struct slave *slave) |
347 | { | 347 | { |
348 | struct arp_pkt *arp; | 348 | struct arp_pkt *arp, _arp; |
349 | 349 | ||
350 | if (skb->protocol != cpu_to_be16(ETH_P_ARP)) | 350 | if (skb->protocol != cpu_to_be16(ETH_P_ARP)) |
351 | goto out; | 351 | goto out; |
352 | 352 | ||
353 | arp = (struct arp_pkt *) skb->data; | 353 | arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp); |
354 | if (!arp) { | 354 | if (!arp) |
355 | pr_debug("Packet has no ARP data\n"); | ||
356 | goto out; | 355 | goto out; |
357 | } | ||
358 | |||
359 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) | ||
360 | goto out; | ||
361 | |||
362 | if (skb->len < sizeof(struct arp_pkt)) { | ||
363 | pr_debug("Packet is too small to be an ARP\n"); | ||
364 | goto out; | ||
365 | } | ||
366 | 356 | ||
367 | if (arp->op_code == htons(ARPOP_REPLY)) { | 357 | if (arp->op_code == htons(ARPOP_REPLY)) { |
368 | /* update rx hash table for this ARP */ | 358 | /* update rx hash table for this ARP */ |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b9c2ae62166d..af506321500b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1445,8 +1445,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1445 | struct sk_buff *skb = *pskb; | 1445 | struct sk_buff *skb = *pskb; |
1446 | struct slave *slave; | 1446 | struct slave *slave; |
1447 | struct bonding *bond; | 1447 | struct bonding *bond; |
1448 | int (*recv_probe)(struct sk_buff *, struct bonding *, | 1448 | int (*recv_probe)(const struct sk_buff *, struct bonding *, |
1449 | struct slave *); | 1449 | struct slave *); |
1450 | int ret = RX_HANDLER_ANOTHER; | 1450 | int ret = RX_HANDLER_ANOTHER; |
1451 | 1451 | ||
1452 | skb = skb_share_check(skb, GFP_ATOMIC); | 1452 | skb = skb_share_check(skb, GFP_ATOMIC); |
@@ -1463,15 +1463,10 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1463 | 1463 | ||
1464 | recv_probe = ACCESS_ONCE(bond->recv_probe); | 1464 | recv_probe = ACCESS_ONCE(bond->recv_probe); |
1465 | if (recv_probe) { | 1465 | if (recv_probe) { |
1466 | struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); | 1466 | ret = recv_probe(skb, bond, slave); |
1467 | 1467 | if (ret == RX_HANDLER_CONSUMED) { | |
1468 | if (likely(nskb)) { | 1468 | consume_skb(skb); |
1469 | ret = recv_probe(nskb, bond, slave); | 1469 | return ret; |
1470 | dev_kfree_skb(nskb); | ||
1471 | if (ret == RX_HANDLER_CONSUMED) { | ||
1472 | consume_skb(skb); | ||
1473 | return ret; | ||
1474 | } | ||
1475 | } | 1470 | } |
1476 | } | 1471 | } |
1477 | 1472 | ||
@@ -2738,25 +2733,31 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 | |||
2738 | } | 2733 | } |
2739 | } | 2734 | } |
2740 | 2735 | ||
2741 | static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, | 2736 | static int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond, |
2742 | struct slave *slave) | 2737 | struct slave *slave) |
2743 | { | 2738 | { |
2744 | struct arphdr *arp; | 2739 | struct arphdr *arp = (struct arphdr *)skb->data; |
2745 | unsigned char *arp_ptr; | 2740 | unsigned char *arp_ptr; |
2746 | __be32 sip, tip; | 2741 | __be32 sip, tip; |
2742 | int alen; | ||
2747 | 2743 | ||
2748 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) | 2744 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) |
2749 | return RX_HANDLER_ANOTHER; | 2745 | return RX_HANDLER_ANOTHER; |
2750 | 2746 | ||
2751 | read_lock(&bond->lock); | 2747 | read_lock(&bond->lock); |
2748 | alen = arp_hdr_len(bond->dev); | ||
2752 | 2749 | ||
2753 | pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", | 2750 | pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", |
2754 | bond->dev->name, skb->dev->name); | 2751 | bond->dev->name, skb->dev->name); |
2755 | 2752 | ||
2756 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) | 2753 | if (alen > skb_headlen(skb)) { |
2757 | goto out_unlock; | 2754 | arp = kmalloc(alen, GFP_ATOMIC); |
2755 | if (!arp) | ||
2756 | goto out_unlock; | ||
2757 | if (skb_copy_bits(skb, 0, arp, alen) < 0) | ||
2758 | goto out_unlock; | ||
2759 | } | ||
2758 | 2760 | ||
2759 | arp = arp_hdr(skb); | ||
2760 | if (arp->ar_hln != bond->dev->addr_len || | 2761 | if (arp->ar_hln != bond->dev->addr_len || |
2761 | skb->pkt_type == PACKET_OTHERHOST || | 2762 | skb->pkt_type == PACKET_OTHERHOST || |
2762 | skb->pkt_type == PACKET_LOOPBACK || | 2763 | skb->pkt_type == PACKET_LOOPBACK || |
@@ -2791,6 +2792,8 @@ static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, | |||
2791 | 2792 | ||
2792 | out_unlock: | 2793 | out_unlock: |
2793 | read_unlock(&bond->lock); | 2794 | read_unlock(&bond->lock); |
2795 | if (arp != (struct arphdr *)skb->data) | ||
2796 | kfree(arp); | ||
2794 | return RX_HANDLER_ANOTHER; | 2797 | return RX_HANDLER_ANOTHER; |
2795 | } | 2798 | } |
2796 | 2799 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4581aa5ccaba..f8af2fcd3d16 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -218,8 +218,8 @@ struct bonding { | |||
218 | struct slave *primary_slave; | 218 | struct slave *primary_slave; |
219 | bool force_primary; | 219 | bool force_primary; |
220 | s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ | 220 | s32 slave_cnt; /* never change this value outside the attach/detach wrappers */ |
221 | int (*recv_probe)(struct sk_buff *, struct bonding *, | 221 | int (*recv_probe)(const struct sk_buff *, struct bonding *, |
222 | struct slave *); | 222 | struct slave *); |
223 | rwlock_t lock; | 223 | rwlock_t lock; |
224 | rwlock_t curr_slave_lock; | 224 | rwlock_t curr_slave_lock; |
225 | u8 send_peer_notif; | 225 | u8 send_peer_notif; |
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 3f88473423e9..ea3143895e6d 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c | |||
@@ -597,7 +597,7 @@ static int __devinit bfin_can_probe(struct platform_device *pdev) | |||
597 | dev_info(&pdev->dev, | 597 | dev_info(&pdev->dev, |
598 | "%s device registered" | 598 | "%s device registered" |
599 | "(®_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n", | 599 | "(®_base=%p, rx_irq=%d, tx_irq=%d, err_irq=%d, sclk=%d)\n", |
600 | DRV_NAME, (void *)priv->membase, priv->rx_irq, | 600 | DRV_NAME, priv->membase, priv->rx_irq, |
601 | priv->tx_irq, priv->err_irq, priv->can.clock.freq); | 601 | priv->tx_irq, priv->err_irq, priv->can.clock.freq); |
602 | return 0; | 602 | return 0; |
603 | 603 | ||
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig index ffb9773d102d..25d371cf98dd 100644 --- a/drivers/net/can/c_can/Kconfig +++ b/drivers/net/can/c_can/Kconfig | |||
@@ -1,15 +1,16 @@ | |||
1 | menuconfig CAN_C_CAN | 1 | menuconfig CAN_C_CAN |
2 | tristate "Bosch C_CAN devices" | 2 | tristate "Bosch C_CAN/D_CAN devices" |
3 | depends on CAN_DEV && HAS_IOMEM | 3 | depends on CAN_DEV && HAS_IOMEM |
4 | 4 | ||
5 | if CAN_C_CAN | 5 | if CAN_C_CAN |
6 | 6 | ||
7 | config CAN_C_CAN_PLATFORM | 7 | config CAN_C_CAN_PLATFORM |
8 | tristate "Generic Platform Bus based C_CAN driver" | 8 | tristate "Generic Platform Bus based C_CAN/D_CAN driver" |
9 | ---help--- | 9 | ---help--- |
10 | This driver adds support for the C_CAN chips connected to | 10 | This driver adds support for the C_CAN/D_CAN chips connected |
11 | the "platform bus" (Linux abstraction for directly to the | 11 | to the "platform bus" (Linux abstraction for directly to the |
12 | processor attached devices) which can be found on various | 12 | processor attached devices) which can be found on various |
13 | boards from ST Microelectronics (http://www.st.com) | 13 | boards from ST Microelectronics (http://www.st.com) like the |
14 | like the SPEAr1310 and SPEAr320 evaluation boards. | 14 | SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com) |
15 | boards like am335x, dm814x, dm813x and dm811x. | ||
15 | endif | 16 | endif |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8dc84d66eea1..e2ce508c2753 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -41,6 +41,10 @@ | |||
41 | 41 | ||
42 | #include "c_can.h" | 42 | #include "c_can.h" |
43 | 43 | ||
44 | /* Number of interface registers */ | ||
45 | #define IF_ENUM_REG_LEN 11 | ||
46 | #define C_CAN_IFACE(reg, iface) (C_CAN_IF1_##reg + (iface) * IF_ENUM_REG_LEN) | ||
47 | |||
44 | /* control register */ | 48 | /* control register */ |
45 | #define CONTROL_TEST BIT(7) | 49 | #define CONTROL_TEST BIT(7) |
46 | #define CONTROL_CCE BIT(6) | 50 | #define CONTROL_CCE BIT(6) |
@@ -209,10 +213,10 @@ static inline int get_tx_echo_msg_obj(const struct c_can_priv *priv) | |||
209 | C_CAN_MSG_OBJ_TX_FIRST; | 213 | C_CAN_MSG_OBJ_TX_FIRST; |
210 | } | 214 | } |
211 | 215 | ||
212 | static u32 c_can_read_reg32(struct c_can_priv *priv, void *reg) | 216 | static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) |
213 | { | 217 | { |
214 | u32 val = priv->read_reg(priv, reg); | 218 | u32 val = priv->read_reg(priv, index); |
215 | val |= ((u32) priv->read_reg(priv, reg + 2)) << 16; | 219 | val |= ((u32) priv->read_reg(priv, index + 1)) << 16; |
216 | return val; | 220 | return val; |
217 | } | 221 | } |
218 | 222 | ||
@@ -220,14 +224,14 @@ static void c_can_enable_all_interrupts(struct c_can_priv *priv, | |||
220 | int enable) | 224 | int enable) |
221 | { | 225 | { |
222 | unsigned int cntrl_save = priv->read_reg(priv, | 226 | unsigned int cntrl_save = priv->read_reg(priv, |
223 | &priv->regs->control); | 227 | C_CAN_CTRL_REG); |
224 | 228 | ||
225 | if (enable) | 229 | if (enable) |
226 | cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); | 230 | cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); |
227 | else | 231 | else |
228 | cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); | 232 | cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); |
229 | 233 | ||
230 | priv->write_reg(priv, &priv->regs->control, cntrl_save); | 234 | priv->write_reg(priv, C_CAN_CTRL_REG, cntrl_save); |
231 | } | 235 | } |
232 | 236 | ||
233 | static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) | 237 | static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) |
@@ -235,7 +239,7 @@ static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) | |||
235 | int count = MIN_TIMEOUT_VALUE; | 239 | int count = MIN_TIMEOUT_VALUE; |
236 | 240 | ||
237 | while (count && priv->read_reg(priv, | 241 | while (count && priv->read_reg(priv, |
238 | &priv->regs->ifregs[iface].com_req) & | 242 | C_CAN_IFACE(COMREQ_REG, iface)) & |
239 | IF_COMR_BUSY) { | 243 | IF_COMR_BUSY) { |
240 | count--; | 244 | count--; |
241 | udelay(1); | 245 | udelay(1); |
@@ -258,9 +262,9 @@ static inline void c_can_object_get(struct net_device *dev, | |||
258 | * register and message RAM must be complete in 6 CAN-CLK | 262 | * register and message RAM must be complete in 6 CAN-CLK |
259 | * period. | 263 | * period. |
260 | */ | 264 | */ |
261 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | 265 | priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), |
262 | IFX_WRITE_LOW_16BIT(mask)); | 266 | IFX_WRITE_LOW_16BIT(mask)); |
263 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | 267 | priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), |
264 | IFX_WRITE_LOW_16BIT(objno)); | 268 | IFX_WRITE_LOW_16BIT(objno)); |
265 | 269 | ||
266 | if (c_can_msg_obj_is_busy(priv, iface)) | 270 | if (c_can_msg_obj_is_busy(priv, iface)) |
@@ -278,9 +282,9 @@ static inline void c_can_object_put(struct net_device *dev, | |||
278 | * register and message RAM must be complete in 6 CAN-CLK | 282 | * register and message RAM must be complete in 6 CAN-CLK |
279 | * period. | 283 | * period. |
280 | */ | 284 | */ |
281 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_mask, | 285 | priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), |
282 | (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); | 286 | (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); |
283 | priv->write_reg(priv, &priv->regs->ifregs[iface].com_req, | 287 | priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), |
284 | IFX_WRITE_LOW_16BIT(objno)); | 288 | IFX_WRITE_LOW_16BIT(objno)); |
285 | 289 | ||
286 | if (c_can_msg_obj_is_busy(priv, iface)) | 290 | if (c_can_msg_obj_is_busy(priv, iface)) |
@@ -306,18 +310,18 @@ static void c_can_write_msg_object(struct net_device *dev, | |||
306 | 310 | ||
307 | flags |= IF_ARB_MSGVAL; | 311 | flags |= IF_ARB_MSGVAL; |
308 | 312 | ||
309 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | 313 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), |
310 | IFX_WRITE_LOW_16BIT(id)); | 314 | IFX_WRITE_LOW_16BIT(id)); |
311 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, flags | | 315 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags | |
312 | IFX_WRITE_HIGH_16BIT(id)); | 316 | IFX_WRITE_HIGH_16BIT(id)); |
313 | 317 | ||
314 | for (i = 0; i < frame->can_dlc; i += 2) { | 318 | for (i = 0; i < frame->can_dlc; i += 2) { |
315 | priv->write_reg(priv, &priv->regs->ifregs[iface].data[i / 2], | 319 | priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, |
316 | frame->data[i] | (frame->data[i + 1] << 8)); | 320 | frame->data[i] | (frame->data[i + 1] << 8)); |
317 | } | 321 | } |
318 | 322 | ||
319 | /* enable interrupt for this message object */ | 323 | /* enable interrupt for this message object */ |
320 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | 324 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
321 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | | 325 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | |
322 | frame->can_dlc); | 326 | frame->can_dlc); |
323 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | 327 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); |
@@ -329,7 +333,7 @@ static inline void c_can_mark_rx_msg_obj(struct net_device *dev, | |||
329 | { | 333 | { |
330 | struct c_can_priv *priv = netdev_priv(dev); | 334 | struct c_can_priv *priv = netdev_priv(dev); |
331 | 335 | ||
332 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | 336 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
333 | ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); | 337 | ctrl_mask & ~(IF_MCONT_MSGLST | IF_MCONT_INTPND)); |
334 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | 338 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); |
335 | 339 | ||
@@ -343,7 +347,7 @@ static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | |||
343 | struct c_can_priv *priv = netdev_priv(dev); | 347 | struct c_can_priv *priv = netdev_priv(dev); |
344 | 348 | ||
345 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { | 349 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { |
346 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | 350 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
347 | ctrl_mask & ~(IF_MCONT_MSGLST | | 351 | ctrl_mask & ~(IF_MCONT_MSGLST | |
348 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | 352 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); |
349 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); | 353 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); |
@@ -356,7 +360,7 @@ static inline void c_can_activate_rx_msg_obj(struct net_device *dev, | |||
356 | { | 360 | { |
357 | struct c_can_priv *priv = netdev_priv(dev); | 361 | struct c_can_priv *priv = netdev_priv(dev); |
358 | 362 | ||
359 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | 363 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
360 | ctrl_mask & ~(IF_MCONT_MSGLST | | 364 | ctrl_mask & ~(IF_MCONT_MSGLST | |
361 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); | 365 | IF_MCONT_INTPND | IF_MCONT_NEWDAT)); |
362 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); | 366 | c_can_object_put(dev, iface, obj, IF_COMM_CONTROL); |
@@ -374,7 +378,7 @@ static void c_can_handle_lost_msg_obj(struct net_device *dev, | |||
374 | 378 | ||
375 | c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | 379 | c_can_object_get(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); |
376 | 380 | ||
377 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, | 381 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), |
378 | IF_MCONT_CLR_MSGLST); | 382 | IF_MCONT_CLR_MSGLST); |
379 | 383 | ||
380 | c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); | 384 | c_can_object_put(dev, 0, objno, IF_COMM_CONTROL); |
@@ -410,8 +414,8 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | |||
410 | 414 | ||
411 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); | 415 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); |
412 | 416 | ||
413 | flags = priv->read_reg(priv, &priv->regs->ifregs[iface].arb2); | 417 | flags = priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)); |
414 | val = priv->read_reg(priv, &priv->regs->ifregs[iface].arb1) | | 418 | val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) | |
415 | (flags << 16); | 419 | (flags << 16); |
416 | 420 | ||
417 | if (flags & IF_ARB_MSGXTD) | 421 | if (flags & IF_ARB_MSGXTD) |
@@ -424,7 +428,7 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | |||
424 | else { | 428 | else { |
425 | for (i = 0; i < frame->can_dlc; i += 2) { | 429 | for (i = 0; i < frame->can_dlc; i += 2) { |
426 | data = priv->read_reg(priv, | 430 | data = priv->read_reg(priv, |
427 | &priv->regs->ifregs[iface].data[i / 2]); | 431 | C_CAN_IFACE(DATA1_REG, iface) + i / 2); |
428 | frame->data[i] = data; | 432 | frame->data[i] = data; |
429 | frame->data[i + 1] = data >> 8; | 433 | frame->data[i + 1] = data >> 8; |
430 | } | 434 | } |
@@ -444,40 +448,40 @@ static void c_can_setup_receive_object(struct net_device *dev, int iface, | |||
444 | { | 448 | { |
445 | struct c_can_priv *priv = netdev_priv(dev); | 449 | struct c_can_priv *priv = netdev_priv(dev); |
446 | 450 | ||
447 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask1, | 451 | priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), |
448 | IFX_WRITE_LOW_16BIT(mask)); | 452 | IFX_WRITE_LOW_16BIT(mask)); |
449 | priv->write_reg(priv, &priv->regs->ifregs[iface].mask2, | 453 | priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), |
450 | IFX_WRITE_HIGH_16BIT(mask)); | 454 | IFX_WRITE_HIGH_16BIT(mask)); |
451 | 455 | ||
452 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, | 456 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), |
453 | IFX_WRITE_LOW_16BIT(id)); | 457 | IFX_WRITE_LOW_16BIT(id)); |
454 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, | 458 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), |
455 | (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); | 459 | (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); |
456 | 460 | ||
457 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, mcont); | 461 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont); |
458 | c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | 462 | c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); |
459 | 463 | ||
460 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | 464 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, |
461 | c_can_read_reg32(priv, &priv->regs->msgval1)); | 465 | c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); |
462 | } | 466 | } |
463 | 467 | ||
464 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) | 468 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) |
465 | { | 469 | { |
466 | struct c_can_priv *priv = netdev_priv(dev); | 470 | struct c_can_priv *priv = netdev_priv(dev); |
467 | 471 | ||
468 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb1, 0); | 472 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); |
469 | priv->write_reg(priv, &priv->regs->ifregs[iface].arb2, 0); | 473 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); |
470 | priv->write_reg(priv, &priv->regs->ifregs[iface].msg_cntrl, 0); | 474 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); |
471 | 475 | ||
472 | c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); | 476 | c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); |
473 | 477 | ||
474 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | 478 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, |
475 | c_can_read_reg32(priv, &priv->regs->msgval1)); | 479 | c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); |
476 | } | 480 | } |
477 | 481 | ||
478 | static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) | 482 | static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) |
479 | { | 483 | { |
480 | int val = c_can_read_reg32(priv, &priv->regs->txrqst1); | 484 | int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); |
481 | 485 | ||
482 | /* | 486 | /* |
483 | * as transmission request register's bit n-1 corresponds to | 487 | * as transmission request register's bit n-1 corresponds to |
@@ -540,12 +544,12 @@ static int c_can_set_bittiming(struct net_device *dev) | |||
540 | netdev_info(dev, | 544 | netdev_info(dev, |
541 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); | 545 | "setting BTR=%04x BRPE=%04x\n", reg_btr, reg_brpe); |
542 | 546 | ||
543 | ctrl_save = priv->read_reg(priv, &priv->regs->control); | 547 | ctrl_save = priv->read_reg(priv, C_CAN_CTRL_REG); |
544 | priv->write_reg(priv, &priv->regs->control, | 548 | priv->write_reg(priv, C_CAN_CTRL_REG, |
545 | ctrl_save | CONTROL_CCE | CONTROL_INIT); | 549 | ctrl_save | CONTROL_CCE | CONTROL_INIT); |
546 | priv->write_reg(priv, &priv->regs->btr, reg_btr); | 550 | priv->write_reg(priv, C_CAN_BTR_REG, reg_btr); |
547 | priv->write_reg(priv, &priv->regs->brp_ext, reg_brpe); | 551 | priv->write_reg(priv, C_CAN_BRPEXT_REG, reg_brpe); |
548 | priv->write_reg(priv, &priv->regs->control, ctrl_save); | 552 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl_save); |
549 | 553 | ||
550 | return 0; | 554 | return 0; |
551 | } | 555 | } |
@@ -587,36 +591,36 @@ static void c_can_chip_config(struct net_device *dev) | |||
587 | struct c_can_priv *priv = netdev_priv(dev); | 591 | struct c_can_priv *priv = netdev_priv(dev); |
588 | 592 | ||
589 | /* enable automatic retransmission */ | 593 | /* enable automatic retransmission */ |
590 | priv->write_reg(priv, &priv->regs->control, | 594 | priv->write_reg(priv, C_CAN_CTRL_REG, |
591 | CONTROL_ENABLE_AR); | 595 | CONTROL_ENABLE_AR); |
592 | 596 | ||
593 | if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & | 597 | if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & |
594 | CAN_CTRLMODE_LOOPBACK)) { | 598 | CAN_CTRLMODE_LOOPBACK)) { |
595 | /* loopback + silent mode : useful for hot self-test */ | 599 | /* loopback + silent mode : useful for hot self-test */ |
596 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | 600 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | |
597 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | 601 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); |
598 | priv->write_reg(priv, &priv->regs->test, | 602 | priv->write_reg(priv, C_CAN_TEST_REG, |
599 | TEST_LBACK | TEST_SILENT); | 603 | TEST_LBACK | TEST_SILENT); |
600 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { | 604 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { |
601 | /* loopback mode : useful for self-test function */ | 605 | /* loopback mode : useful for self-test function */ |
602 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | 606 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | |
603 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | 607 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); |
604 | priv->write_reg(priv, &priv->regs->test, TEST_LBACK); | 608 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK); |
605 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { | 609 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { |
606 | /* silent mode : bus-monitoring mode */ | 610 | /* silent mode : bus-monitoring mode */ |
607 | priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | | 611 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | |
608 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | 612 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); |
609 | priv->write_reg(priv, &priv->regs->test, TEST_SILENT); | 613 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT); |
610 | } else | 614 | } else |
611 | /* normal mode*/ | 615 | /* normal mode*/ |
612 | priv->write_reg(priv, &priv->regs->control, | 616 | priv->write_reg(priv, C_CAN_CTRL_REG, |
613 | CONTROL_EIE | CONTROL_SIE | CONTROL_IE); | 617 | CONTROL_EIE | CONTROL_SIE | CONTROL_IE); |
614 | 618 | ||
615 | /* configure message objects */ | 619 | /* configure message objects */ |
616 | c_can_configure_msg_objects(dev); | 620 | c_can_configure_msg_objects(dev); |
617 | 621 | ||
618 | /* set a `lec` value so that we can check for updates later */ | 622 | /* set a `lec` value so that we can check for updates later */ |
619 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | 623 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); |
620 | 624 | ||
621 | /* set bittiming params */ | 625 | /* set bittiming params */ |
622 | c_can_set_bittiming(dev); | 626 | c_can_set_bittiming(dev); |
@@ -669,7 +673,7 @@ static int c_can_get_berr_counter(const struct net_device *dev, | |||
669 | unsigned int reg_err_counter; | 673 | unsigned int reg_err_counter; |
670 | struct c_can_priv *priv = netdev_priv(dev); | 674 | struct c_can_priv *priv = netdev_priv(dev); |
671 | 675 | ||
672 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | 676 | reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); |
673 | bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> | 677 | bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >> |
674 | ERR_CNT_REC_SHIFT; | 678 | ERR_CNT_REC_SHIFT; |
675 | bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; | 679 | bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK; |
@@ -697,12 +701,12 @@ static void c_can_do_tx(struct net_device *dev) | |||
697 | 701 | ||
698 | for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | 702 | for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { |
699 | msg_obj_no = get_tx_echo_msg_obj(priv); | 703 | msg_obj_no = get_tx_echo_msg_obj(priv); |
700 | val = c_can_read_reg32(priv, &priv->regs->txrqst1); | 704 | val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); |
701 | if (!(val & (1 << (msg_obj_no - 1)))) { | 705 | if (!(val & (1 << (msg_obj_no - 1)))) { |
702 | can_get_echo_skb(dev, | 706 | can_get_echo_skb(dev, |
703 | msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | 707 | msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); |
704 | stats->tx_bytes += priv->read_reg(priv, | 708 | stats->tx_bytes += priv->read_reg(priv, |
705 | &priv->regs->ifregs[0].msg_cntrl) | 709 | C_CAN_IFACE(MSGCTRL_REG, 0)) |
706 | & IF_MCONT_DLC_MASK; | 710 | & IF_MCONT_DLC_MASK; |
707 | stats->tx_packets++; | 711 | stats->tx_packets++; |
708 | c_can_inval_msg_object(dev, 0, msg_obj_no); | 712 | c_can_inval_msg_object(dev, 0, msg_obj_no); |
@@ -744,11 +748,11 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) | |||
744 | u32 num_rx_pkts = 0; | 748 | u32 num_rx_pkts = 0; |
745 | unsigned int msg_obj, msg_ctrl_save; | 749 | unsigned int msg_obj, msg_ctrl_save; |
746 | struct c_can_priv *priv = netdev_priv(dev); | 750 | struct c_can_priv *priv = netdev_priv(dev); |
747 | u32 val = c_can_read_reg32(priv, &priv->regs->intpnd1); | 751 | u32 val = c_can_read_reg32(priv, C_CAN_INTPND1_REG); |
748 | 752 | ||
749 | for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; | 753 | for (msg_obj = C_CAN_MSG_OBJ_RX_FIRST; |
750 | msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; | 754 | msg_obj <= C_CAN_MSG_OBJ_RX_LAST && quota > 0; |
751 | val = c_can_read_reg32(priv, &priv->regs->intpnd1), | 755 | val = c_can_read_reg32(priv, C_CAN_INTPND1_REG), |
752 | msg_obj++) { | 756 | msg_obj++) { |
753 | /* | 757 | /* |
754 | * as interrupt pending register's bit n-1 corresponds to | 758 | * as interrupt pending register's bit n-1 corresponds to |
@@ -758,7 +762,7 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) | |||
758 | c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & | 762 | c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL & |
759 | ~IF_COMM_TXRQST); | 763 | ~IF_COMM_TXRQST); |
760 | msg_ctrl_save = priv->read_reg(priv, | 764 | msg_ctrl_save = priv->read_reg(priv, |
761 | &priv->regs->ifregs[0].msg_cntrl); | 765 | C_CAN_IFACE(MSGCTRL_REG, 0)); |
762 | 766 | ||
763 | if (msg_ctrl_save & IF_MCONT_EOB) | 767 | if (msg_ctrl_save & IF_MCONT_EOB) |
764 | return num_rx_pkts; | 768 | return num_rx_pkts; |
@@ -819,7 +823,7 @@ static int c_can_handle_state_change(struct net_device *dev, | |||
819 | return 0; | 823 | return 0; |
820 | 824 | ||
821 | c_can_get_berr_counter(dev, &bec); | 825 | c_can_get_berr_counter(dev, &bec); |
822 | reg_err_counter = priv->read_reg(priv, &priv->regs->err_cnt); | 826 | reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG); |
823 | rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> | 827 | rx_err_passive = (reg_err_counter & ERR_CNT_RP_MASK) >> |
824 | ERR_CNT_RP_SHIFT; | 828 | ERR_CNT_RP_SHIFT; |
825 | 829 | ||
@@ -935,7 +939,7 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
935 | } | 939 | } |
936 | 940 | ||
937 | /* set a `lec` value so that we can check for updates later */ | 941 | /* set a `lec` value so that we can check for updates later */ |
938 | priv->write_reg(priv, &priv->regs->status, LEC_UNUSED); | 942 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); |
939 | 943 | ||
940 | netif_receive_skb(skb); | 944 | netif_receive_skb(skb); |
941 | stats->rx_packets++; | 945 | stats->rx_packets++; |
@@ -959,15 +963,15 @@ static int c_can_poll(struct napi_struct *napi, int quota) | |||
959 | /* status events have the highest priority */ | 963 | /* status events have the highest priority */ |
960 | if (irqstatus == STATUS_INTERRUPT) { | 964 | if (irqstatus == STATUS_INTERRUPT) { |
961 | priv->current_status = priv->read_reg(priv, | 965 | priv->current_status = priv->read_reg(priv, |
962 | &priv->regs->status); | 966 | C_CAN_STS_REG); |
963 | 967 | ||
964 | /* handle Tx/Rx events */ | 968 | /* handle Tx/Rx events */ |
965 | if (priv->current_status & STATUS_TXOK) | 969 | if (priv->current_status & STATUS_TXOK) |
966 | priv->write_reg(priv, &priv->regs->status, | 970 | priv->write_reg(priv, C_CAN_STS_REG, |
967 | priv->current_status & ~STATUS_TXOK); | 971 | priv->current_status & ~STATUS_TXOK); |
968 | 972 | ||
969 | if (priv->current_status & STATUS_RXOK) | 973 | if (priv->current_status & STATUS_RXOK) |
970 | priv->write_reg(priv, &priv->regs->status, | 974 | priv->write_reg(priv, C_CAN_STS_REG, |
971 | priv->current_status & ~STATUS_RXOK); | 975 | priv->current_status & ~STATUS_RXOK); |
972 | 976 | ||
973 | /* handle state changes */ | 977 | /* handle state changes */ |
@@ -1033,7 +1037,7 @@ static irqreturn_t c_can_isr(int irq, void *dev_id) | |||
1033 | struct net_device *dev = (struct net_device *)dev_id; | 1037 | struct net_device *dev = (struct net_device *)dev_id; |
1034 | struct c_can_priv *priv = netdev_priv(dev); | 1038 | struct c_can_priv *priv = netdev_priv(dev); |
1035 | 1039 | ||
1036 | priv->irqstatus = priv->read_reg(priv, &priv->regs->interrupt); | 1040 | priv->irqstatus = priv->read_reg(priv, C_CAN_INT_REG); |
1037 | if (!priv->irqstatus) | 1041 | if (!priv->irqstatus) |
1038 | return IRQ_NONE; | 1042 | return IRQ_NONE; |
1039 | 1043 | ||
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index 5f32d34af507..01a7049ab990 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h | |||
@@ -22,43 +22,129 @@ | |||
22 | #ifndef C_CAN_H | 22 | #ifndef C_CAN_H |
23 | #define C_CAN_H | 23 | #define C_CAN_H |
24 | 24 | ||
25 | /* c_can IF registers */ | 25 | enum reg { |
26 | struct c_can_if_regs { | 26 | C_CAN_CTRL_REG = 0, |
27 | u16 com_req; | 27 | C_CAN_STS_REG, |
28 | u16 com_mask; | 28 | C_CAN_ERR_CNT_REG, |
29 | u16 mask1; | 29 | C_CAN_BTR_REG, |
30 | u16 mask2; | 30 | C_CAN_INT_REG, |
31 | u16 arb1; | 31 | C_CAN_TEST_REG, |
32 | u16 arb2; | 32 | C_CAN_BRPEXT_REG, |
33 | u16 msg_cntrl; | 33 | C_CAN_IF1_COMREQ_REG, |
34 | u16 data[4]; | 34 | C_CAN_IF1_COMMSK_REG, |
35 | u16 _reserved[13]; | 35 | C_CAN_IF1_MASK1_REG, |
36 | C_CAN_IF1_MASK2_REG, | ||
37 | C_CAN_IF1_ARB1_REG, | ||
38 | C_CAN_IF1_ARB2_REG, | ||
39 | C_CAN_IF1_MSGCTRL_REG, | ||
40 | C_CAN_IF1_DATA1_REG, | ||
41 | C_CAN_IF1_DATA2_REG, | ||
42 | C_CAN_IF1_DATA3_REG, | ||
43 | C_CAN_IF1_DATA4_REG, | ||
44 | C_CAN_IF2_COMREQ_REG, | ||
45 | C_CAN_IF2_COMMSK_REG, | ||
46 | C_CAN_IF2_MASK1_REG, | ||
47 | C_CAN_IF2_MASK2_REG, | ||
48 | C_CAN_IF2_ARB1_REG, | ||
49 | C_CAN_IF2_ARB2_REG, | ||
50 | C_CAN_IF2_MSGCTRL_REG, | ||
51 | C_CAN_IF2_DATA1_REG, | ||
52 | C_CAN_IF2_DATA2_REG, | ||
53 | C_CAN_IF2_DATA3_REG, | ||
54 | C_CAN_IF2_DATA4_REG, | ||
55 | C_CAN_TXRQST1_REG, | ||
56 | C_CAN_TXRQST2_REG, | ||
57 | C_CAN_NEWDAT1_REG, | ||
58 | C_CAN_NEWDAT2_REG, | ||
59 | C_CAN_INTPND1_REG, | ||
60 | C_CAN_INTPND2_REG, | ||
61 | C_CAN_MSGVAL1_REG, | ||
62 | C_CAN_MSGVAL2_REG, | ||
36 | }; | 63 | }; |
37 | 64 | ||
38 | /* c_can hardware registers */ | 65 | static const u16 reg_map_c_can[] = { |
39 | struct c_can_regs { | 66 | [C_CAN_CTRL_REG] = 0x00, |
40 | u16 control; | 67 | [C_CAN_STS_REG] = 0x02, |
41 | u16 status; | 68 | [C_CAN_ERR_CNT_REG] = 0x04, |
42 | u16 err_cnt; | 69 | [C_CAN_BTR_REG] = 0x06, |
43 | u16 btr; | 70 | [C_CAN_INT_REG] = 0x08, |
44 | u16 interrupt; | 71 | [C_CAN_TEST_REG] = 0x0A, |
45 | u16 test; | 72 | [C_CAN_BRPEXT_REG] = 0x0C, |
46 | u16 brp_ext; | 73 | [C_CAN_IF1_COMREQ_REG] = 0x10, |
47 | u16 _reserved1; | 74 | [C_CAN_IF1_COMMSK_REG] = 0x12, |
48 | struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */ | 75 | [C_CAN_IF1_MASK1_REG] = 0x14, |
49 | u16 _reserved2[8]; | 76 | [C_CAN_IF1_MASK2_REG] = 0x16, |
50 | u16 txrqst1; | 77 | [C_CAN_IF1_ARB1_REG] = 0x18, |
51 | u16 txrqst2; | 78 | [C_CAN_IF1_ARB2_REG] = 0x1A, |
52 | u16 _reserved3[6]; | 79 | [C_CAN_IF1_MSGCTRL_REG] = 0x1C, |
53 | u16 newdat1; | 80 | [C_CAN_IF1_DATA1_REG] = 0x1E, |
54 | u16 newdat2; | 81 | [C_CAN_IF1_DATA2_REG] = 0x20, |
55 | u16 _reserved4[6]; | 82 | [C_CAN_IF1_DATA3_REG] = 0x22, |
56 | u16 intpnd1; | 83 | [C_CAN_IF1_DATA4_REG] = 0x24, |
57 | u16 intpnd2; | 84 | [C_CAN_IF2_COMREQ_REG] = 0x40, |
58 | u16 _reserved5[6]; | 85 | [C_CAN_IF2_COMMSK_REG] = 0x42, |
59 | u16 msgval1; | 86 | [C_CAN_IF2_MASK1_REG] = 0x44, |
60 | u16 msgval2; | 87 | [C_CAN_IF2_MASK2_REG] = 0x46, |
61 | u16 _reserved6[6]; | 88 | [C_CAN_IF2_ARB1_REG] = 0x48, |
89 | [C_CAN_IF2_ARB2_REG] = 0x4A, | ||
90 | [C_CAN_IF2_MSGCTRL_REG] = 0x4C, | ||
91 | [C_CAN_IF2_DATA1_REG] = 0x4E, | ||
92 | [C_CAN_IF2_DATA2_REG] = 0x50, | ||
93 | [C_CAN_IF2_DATA3_REG] = 0x52, | ||
94 | [C_CAN_IF2_DATA4_REG] = 0x54, | ||
95 | [C_CAN_TXRQST1_REG] = 0x80, | ||
96 | [C_CAN_TXRQST2_REG] = 0x82, | ||
97 | [C_CAN_NEWDAT1_REG] = 0x90, | ||
98 | [C_CAN_NEWDAT2_REG] = 0x92, | ||
99 | [C_CAN_INTPND1_REG] = 0xA0, | ||
100 | [C_CAN_INTPND2_REG] = 0xA2, | ||
101 | [C_CAN_MSGVAL1_REG] = 0xB0, | ||
102 | [C_CAN_MSGVAL2_REG] = 0xB2, | ||
103 | }; | ||
104 | |||
105 | static const u16 reg_map_d_can[] = { | ||
106 | [C_CAN_CTRL_REG] = 0x00, | ||
107 | [C_CAN_STS_REG] = 0x04, | ||
108 | [C_CAN_ERR_CNT_REG] = 0x08, | ||
109 | [C_CAN_BTR_REG] = 0x0C, | ||
110 | [C_CAN_BRPEXT_REG] = 0x0E, | ||
111 | [C_CAN_INT_REG] = 0x10, | ||
112 | [C_CAN_TEST_REG] = 0x14, | ||
113 | [C_CAN_TXRQST1_REG] = 0x88, | ||
114 | [C_CAN_TXRQST2_REG] = 0x8A, | ||
115 | [C_CAN_NEWDAT1_REG] = 0x9C, | ||
116 | [C_CAN_NEWDAT2_REG] = 0x9E, | ||
117 | [C_CAN_INTPND1_REG] = 0xB0, | ||
118 | [C_CAN_INTPND2_REG] = 0xB2, | ||
119 | [C_CAN_MSGVAL1_REG] = 0xC4, | ||
120 | [C_CAN_MSGVAL2_REG] = 0xC6, | ||
121 | [C_CAN_IF1_COMREQ_REG] = 0x100, | ||
122 | [C_CAN_IF1_COMMSK_REG] = 0x102, | ||
123 | [C_CAN_IF1_MASK1_REG] = 0x104, | ||
124 | [C_CAN_IF1_MASK2_REG] = 0x106, | ||
125 | [C_CAN_IF1_ARB1_REG] = 0x108, | ||
126 | [C_CAN_IF1_ARB2_REG] = 0x10A, | ||
127 | [C_CAN_IF1_MSGCTRL_REG] = 0x10C, | ||
128 | [C_CAN_IF1_DATA1_REG] = 0x110, | ||
129 | [C_CAN_IF1_DATA2_REG] = 0x112, | ||
130 | [C_CAN_IF1_DATA3_REG] = 0x114, | ||
131 | [C_CAN_IF1_DATA4_REG] = 0x116, | ||
132 | [C_CAN_IF2_COMREQ_REG] = 0x120, | ||
133 | [C_CAN_IF2_COMMSK_REG] = 0x122, | ||
134 | [C_CAN_IF2_MASK1_REG] = 0x124, | ||
135 | [C_CAN_IF2_MASK2_REG] = 0x126, | ||
136 | [C_CAN_IF2_ARB1_REG] = 0x128, | ||
137 | [C_CAN_IF2_ARB2_REG] = 0x12A, | ||
138 | [C_CAN_IF2_MSGCTRL_REG] = 0x12C, | ||
139 | [C_CAN_IF2_DATA1_REG] = 0x130, | ||
140 | [C_CAN_IF2_DATA2_REG] = 0x132, | ||
141 | [C_CAN_IF2_DATA3_REG] = 0x134, | ||
142 | [C_CAN_IF2_DATA4_REG] = 0x136, | ||
143 | }; | ||
144 | |||
145 | enum c_can_dev_id { | ||
146 | C_CAN_DEVTYPE, | ||
147 | D_CAN_DEVTYPE, | ||
62 | }; | 148 | }; |
63 | 149 | ||
64 | /* c_can private data structure */ | 150 | /* c_can private data structure */ |
@@ -69,9 +155,10 @@ struct c_can_priv { | |||
69 | int tx_object; | 155 | int tx_object; |
70 | int current_status; | 156 | int current_status; |
71 | int last_status; | 157 | int last_status; |
72 | u16 (*read_reg) (struct c_can_priv *priv, void *reg); | 158 | u16 (*read_reg) (struct c_can_priv *priv, enum reg index); |
73 | void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val); | 159 | void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val); |
74 | struct c_can_regs __iomem *regs; | 160 | void __iomem *base; |
161 | const u16 *regs; | ||
75 | unsigned long irq_flags; /* for request_irq() */ | 162 | unsigned long irq_flags; /* for request_irq() */ |
76 | unsigned int tx_next; | 163 | unsigned int tx_next; |
77 | unsigned int tx_echo; | 164 | unsigned int tx_echo; |
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 5e1a5ff6476e..f0921d16f0a9 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -42,27 +42,27 @@ | |||
42 | * Handle the same by providing a common read/write interface. | 42 | * Handle the same by providing a common read/write interface. |
43 | */ | 43 | */ |
44 | static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, | 44 | static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv, |
45 | void *reg) | 45 | enum reg index) |
46 | { | 46 | { |
47 | return readw(reg); | 47 | return readw(priv->base + priv->regs[index]); |
48 | } | 48 | } |
49 | 49 | ||
50 | static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, | 50 | static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv, |
51 | void *reg, u16 val) | 51 | enum reg index, u16 val) |
52 | { | 52 | { |
53 | writew(val, reg); | 53 | writew(val, priv->base + priv->regs[index]); |
54 | } | 54 | } |
55 | 55 | ||
56 | static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, | 56 | static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv, |
57 | void *reg) | 57 | enum reg index) |
58 | { | 58 | { |
59 | return readw(reg + (long)reg - (long)priv->regs); | 59 | return readw(priv->base + 2 * priv->regs[index]); |
60 | } | 60 | } |
61 | 61 | ||
62 | static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, | 62 | static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv, |
63 | void *reg, u16 val) | 63 | enum reg index, u16 val) |
64 | { | 64 | { |
65 | writew(val, reg + (long)reg - (long)priv->regs); | 65 | writew(val, priv->base + 2 * priv->regs[index]); |
66 | } | 66 | } |
67 | 67 | ||
68 | static int __devinit c_can_plat_probe(struct platform_device *pdev) | 68 | static int __devinit c_can_plat_probe(struct platform_device *pdev) |
@@ -71,6 +71,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) | |||
71 | void __iomem *addr; | 71 | void __iomem *addr; |
72 | struct net_device *dev; | 72 | struct net_device *dev; |
73 | struct c_can_priv *priv; | 73 | struct c_can_priv *priv; |
74 | const struct platform_device_id *id; | ||
74 | struct resource *mem; | 75 | struct resource *mem; |
75 | int irq; | 76 | int irq; |
76 | #ifdef CONFIG_HAVE_CLK | 77 | #ifdef CONFIG_HAVE_CLK |
@@ -115,26 +116,40 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) | |||
115 | } | 116 | } |
116 | 117 | ||
117 | priv = netdev_priv(dev); | 118 | priv = netdev_priv(dev); |
119 | id = platform_get_device_id(pdev); | ||
120 | switch (id->driver_data) { | ||
121 | case C_CAN_DEVTYPE: | ||
122 | priv->regs = reg_map_c_can; | ||
123 | switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { | ||
124 | case IORESOURCE_MEM_32BIT: | ||
125 | priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; | ||
126 | priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; | ||
127 | break; | ||
128 | case IORESOURCE_MEM_16BIT: | ||
129 | default: | ||
130 | priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; | ||
131 | priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; | ||
132 | break; | ||
133 | } | ||
134 | break; | ||
135 | case D_CAN_DEVTYPE: | ||
136 | priv->regs = reg_map_d_can; | ||
137 | priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; | ||
138 | priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; | ||
139 | priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; | ||
140 | break; | ||
141 | default: | ||
142 | ret = -EINVAL; | ||
143 | goto exit_free_device; | ||
144 | } | ||
118 | 145 | ||
119 | dev->irq = irq; | 146 | dev->irq = irq; |
120 | priv->regs = addr; | 147 | priv->base = addr; |
121 | #ifdef CONFIG_HAVE_CLK | 148 | #ifdef CONFIG_HAVE_CLK |
122 | priv->can.clock.freq = clk_get_rate(clk); | 149 | priv->can.clock.freq = clk_get_rate(clk); |
123 | priv->priv = clk; | 150 | priv->priv = clk; |
124 | #endif | 151 | #endif |
125 | 152 | ||
126 | switch (mem->flags & IORESOURCE_MEM_TYPE_MASK) { | ||
127 | case IORESOURCE_MEM_32BIT: | ||
128 | priv->read_reg = c_can_plat_read_reg_aligned_to_32bit; | ||
129 | priv->write_reg = c_can_plat_write_reg_aligned_to_32bit; | ||
130 | break; | ||
131 | case IORESOURCE_MEM_16BIT: | ||
132 | default: | ||
133 | priv->read_reg = c_can_plat_read_reg_aligned_to_16bit; | ||
134 | priv->write_reg = c_can_plat_write_reg_aligned_to_16bit; | ||
135 | break; | ||
136 | } | ||
137 | |||
138 | platform_set_drvdata(pdev, dev); | 153 | platform_set_drvdata(pdev, dev); |
139 | SET_NETDEV_DEV(dev, &pdev->dev); | 154 | SET_NETDEV_DEV(dev, &pdev->dev); |
140 | 155 | ||
@@ -146,7 +161,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev) | |||
146 | } | 161 | } |
147 | 162 | ||
148 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", | 163 | dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", |
149 | KBUILD_MODNAME, priv->regs, dev->irq); | 164 | KBUILD_MODNAME, priv->base, dev->irq); |
150 | return 0; | 165 | return 0; |
151 | 166 | ||
152 | exit_free_device: | 167 | exit_free_device: |
@@ -176,7 +191,7 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev) | |||
176 | platform_set_drvdata(pdev, NULL); | 191 | platform_set_drvdata(pdev, NULL); |
177 | 192 | ||
178 | free_c_can_dev(dev); | 193 | free_c_can_dev(dev); |
179 | iounmap(priv->regs); | 194 | iounmap(priv->base); |
180 | 195 | ||
181 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 196 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
182 | release_mem_region(mem->start, resource_size(mem)); | 197 | release_mem_region(mem->start, resource_size(mem)); |
@@ -188,6 +203,20 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev) | |||
188 | return 0; | 203 | return 0; |
189 | } | 204 | } |
190 | 205 | ||
206 | static const struct platform_device_id c_can_id_table[] = { | ||
207 | { | ||
208 | .name = KBUILD_MODNAME, | ||
209 | .driver_data = C_CAN_DEVTYPE, | ||
210 | }, { | ||
211 | .name = "c_can", | ||
212 | .driver_data = C_CAN_DEVTYPE, | ||
213 | }, { | ||
214 | .name = "d_can", | ||
215 | .driver_data = D_CAN_DEVTYPE, | ||
216 | }, { | ||
217 | } | ||
218 | }; | ||
219 | |||
191 | static struct platform_driver c_can_plat_driver = { | 220 | static struct platform_driver c_can_plat_driver = { |
192 | .driver = { | 221 | .driver = { |
193 | .name = KBUILD_MODNAME, | 222 | .name = KBUILD_MODNAME, |
@@ -195,6 +224,7 @@ static struct platform_driver c_can_plat_driver = { | |||
195 | }, | 224 | }, |
196 | .probe = c_can_plat_probe, | 225 | .probe = c_can_plat_probe, |
197 | .remove = __devexit_p(c_can_plat_remove), | 226 | .remove = __devexit_p(c_can_plat_remove), |
227 | .id_table = c_can_id_table, | ||
198 | }; | 228 | }; |
199 | 229 | ||
200 | module_platform_driver(c_can_plat_driver); | 230 | module_platform_driver(c_can_plat_driver); |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 38c0690df5c8..d465fd4546f0 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -1056,6 +1056,42 @@ static struct of_device_id flexcan_of_match[] = { | |||
1056 | {}, | 1056 | {}, |
1057 | }; | 1057 | }; |
1058 | 1058 | ||
1059 | #ifdef CONFIG_PM | ||
1060 | static int flexcan_suspend(struct platform_device *pdev, pm_message_t state) | ||
1061 | { | ||
1062 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1063 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1064 | |||
1065 | flexcan_chip_disable(priv); | ||
1066 | |||
1067 | if (netif_running(dev)) { | ||
1068 | netif_stop_queue(dev); | ||
1069 | netif_device_detach(dev); | ||
1070 | } | ||
1071 | priv->can.state = CAN_STATE_SLEEPING; | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | static int flexcan_resume(struct platform_device *pdev) | ||
1077 | { | ||
1078 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1079 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1080 | |||
1081 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | ||
1082 | if (netif_running(dev)) { | ||
1083 | netif_device_attach(dev); | ||
1084 | netif_start_queue(dev); | ||
1085 | } | ||
1086 | flexcan_chip_enable(priv); | ||
1087 | |||
1088 | return 0; | ||
1089 | } | ||
1090 | #else | ||
1091 | #define flexcan_suspend NULL | ||
1092 | #define flexcan_resume NULL | ||
1093 | #endif | ||
1094 | |||
1059 | static struct platform_driver flexcan_driver = { | 1095 | static struct platform_driver flexcan_driver = { |
1060 | .driver = { | 1096 | .driver = { |
1061 | .name = DRV_NAME, | 1097 | .name = DRV_NAME, |
@@ -1064,6 +1100,8 @@ static struct platform_driver flexcan_driver = { | |||
1064 | }, | 1100 | }, |
1065 | .probe = flexcan_probe, | 1101 | .probe = flexcan_probe, |
1066 | .remove = __devexit_p(flexcan_remove), | 1102 | .remove = __devexit_p(flexcan_remove), |
1103 | .suspend = flexcan_suspend, | ||
1104 | .resume = flexcan_resume, | ||
1067 | }; | 1105 | }; |
1068 | 1106 | ||
1069 | module_platform_driver(flexcan_driver); | 1107 | module_platform_driver(flexcan_driver); |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 346785c56a25..9120a36ec702 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -1020,8 +1020,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) | |||
1020 | GFP_DMA); | 1020 | GFP_DMA); |
1021 | 1021 | ||
1022 | if (priv->spi_tx_buf) { | 1022 | if (priv->spi_tx_buf) { |
1023 | priv->spi_rx_buf = (u8 *)(priv->spi_tx_buf + | 1023 | priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2)); |
1024 | (PAGE_SIZE / 2)); | ||
1025 | priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma + | 1024 | priv->spi_rx_dma = (dma_addr_t)(priv->spi_tx_dma + |
1026 | (PAGE_SIZE / 2)); | 1025 | (PAGE_SIZE / 2)); |
1027 | } else { | 1026 | } else { |
diff --git a/drivers/net/ethernet/8390/apne.c b/drivers/net/ethernet/8390/apne.c index 923959275a82..912ed7a5f33a 100644 --- a/drivers/net/ethernet/8390/apne.c +++ b/drivers/net/ethernet/8390/apne.c | |||
@@ -454,7 +454,7 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin | |||
454 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | 454 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); |
455 | } | 455 | } |
456 | } else { | 456 | } else { |
457 | ptrc = (char*)buf; | 457 | ptrc = buf; |
458 | for (cnt = 0; cnt < count; cnt++) | 458 | for (cnt = 0; cnt < count; cnt++) |
459 | *ptrc++ = inb(NE_BASE + NE_DATAPORT); | 459 | *ptrc++ = inb(NE_BASE + NE_DATAPORT); |
460 | } | 460 | } |
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 348501178089..9c77c736f171 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c | |||
@@ -1014,7 +1014,7 @@ static int greth_set_mac_add(struct net_device *dev, void *p) | |||
1014 | struct greth_regs *regs; | 1014 | struct greth_regs *regs; |
1015 | 1015 | ||
1016 | greth = netdev_priv(dev); | 1016 | greth = netdev_priv(dev); |
1017 | regs = (struct greth_regs *) greth->regs; | 1017 | regs = greth->regs; |
1018 | 1018 | ||
1019 | if (!is_valid_ether_addr(addr->sa_data)) | 1019 | if (!is_valid_ether_addr(addr->sa_data)) |
1020 | return -EADDRNOTAVAIL; | 1020 | return -EADDRNOTAVAIL; |
@@ -1036,7 +1036,7 @@ static void greth_set_hash_filter(struct net_device *dev) | |||
1036 | { | 1036 | { |
1037 | struct netdev_hw_addr *ha; | 1037 | struct netdev_hw_addr *ha; |
1038 | struct greth_private *greth = netdev_priv(dev); | 1038 | struct greth_private *greth = netdev_priv(dev); |
1039 | struct greth_regs *regs = (struct greth_regs *) greth->regs; | 1039 | struct greth_regs *regs = greth->regs; |
1040 | u32 mc_filter[2]; | 1040 | u32 mc_filter[2]; |
1041 | unsigned int bitnr; | 1041 | unsigned int bitnr; |
1042 | 1042 | ||
@@ -1055,7 +1055,7 @@ static void greth_set_multicast_list(struct net_device *dev) | |||
1055 | { | 1055 | { |
1056 | int cfg; | 1056 | int cfg; |
1057 | struct greth_private *greth = netdev_priv(dev); | 1057 | struct greth_private *greth = netdev_priv(dev); |
1058 | struct greth_regs *regs = (struct greth_regs *) greth->regs; | 1058 | struct greth_regs *regs = greth->regs; |
1059 | 1059 | ||
1060 | cfg = GRETH_REGLOAD(regs->control); | 1060 | cfg = GRETH_REGLOAD(regs->control); |
1061 | if (dev->flags & IFF_PROMISC) | 1061 | if (dev->flags & IFF_PROMISC) |
@@ -1414,7 +1414,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev) | |||
1414 | goto error1; | 1414 | goto error1; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | regs = (struct greth_regs *) greth->regs; | 1417 | regs = greth->regs; |
1418 | greth->irq = ofdev->archdata.irqs[0]; | 1418 | greth->irq = ofdev->archdata.irqs[0]; |
1419 | 1419 | ||
1420 | dev_set_drvdata(greth->dev, dev); | 1420 | dev_set_drvdata(greth->dev, dev); |
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index 75299f500ee5..7203b522f234 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c | |||
@@ -623,7 +623,7 @@ static int lance_rx(struct net_device *dev) | |||
623 | skb_put(skb, len); /* make room */ | 623 | skb_put(skb, len); /* make room */ |
624 | 624 | ||
625 | cp_from_buf(lp->type, skb->data, | 625 | cp_from_buf(lp->type, skb->data, |
626 | (char *)lp->rx_buf_ptr_cpu[entry], len); | 626 | lp->rx_buf_ptr_cpu[entry], len); |
627 | 627 | ||
628 | skb->protocol = eth_type_trans(skb, dev); | 628 | skb->protocol = eth_type_trans(skb, dev); |
629 | netif_rx(skb); | 629 | netif_rx(skb); |
@@ -919,7 +919,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
919 | *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); | 919 | *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len); |
920 | *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; | 920 | *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0; |
921 | 921 | ||
922 | cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, len); | 922 | cp_to_buf(lp->type, lp->tx_buf_ptr_cpu[entry], skb->data, len); |
923 | 923 | ||
924 | /* Now, give the packet to the lance */ | 924 | /* Now, give the packet to the lance */ |
925 | *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) = | 925 | *lib_ptr(ib, btx_ring[entry].tmd1, lp->type) = |
diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c index ab7ff8645ab1..a92ddee7f665 100644 --- a/drivers/net/ethernet/apple/macmace.c +++ b/drivers/net/ethernet/apple/macmace.c | |||
@@ -228,7 +228,7 @@ static int __devinit mace_probe(struct platform_device *pdev) | |||
228 | * bits are reversed. | 228 | * bits are reversed. |
229 | */ | 229 | */ |
230 | 230 | ||
231 | addr = (void *)MACE_PROM; | 231 | addr = MACE_PROM; |
232 | 232 | ||
233 | for (j = 0; j < 6; ++j) { | 233 | for (j = 0; j < 6; ++j) { |
234 | u8 v = bitrev8(addr[j<<4]); | 234 | u8 v = bitrev8(addr[j<<4]); |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c index ff9c73859d45..801f0126512d 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c | |||
@@ -602,7 +602,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw) | |||
602 | 602 | ||
603 | int atl1c_phy_init(struct atl1c_hw *hw) | 603 | int atl1c_phy_init(struct atl1c_hw *hw) |
604 | { | 604 | { |
605 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | 605 | struct atl1c_adapter *adapter = hw->adapter; |
606 | struct pci_dev *pdev = adapter->pdev; | 606 | struct pci_dev *pdev = adapter->pdev; |
607 | int ret_val; | 607 | int ret_val; |
608 | u16 mii_bmcr_data = BMCR_RESET; | 608 | u16 mii_bmcr_data = BMCR_RESET; |
@@ -696,7 +696,7 @@ int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex) | |||
696 | /* select one link mode to get lower power consumption */ | 696 | /* select one link mode to get lower power consumption */ |
697 | int atl1c_phy_to_ps_link(struct atl1c_hw *hw) | 697 | int atl1c_phy_to_ps_link(struct atl1c_hw *hw) |
698 | { | 698 | { |
699 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | 699 | struct atl1c_adapter *adapter = hw->adapter; |
700 | struct pci_dev *pdev = adapter->pdev; | 700 | struct pci_dev *pdev = adapter->pdev; |
701 | int ret = 0; | 701 | int ret = 0; |
702 | u16 autoneg_advertised = ADVERTISED_10baseT_Half; | 702 | u16 autoneg_advertised = ADVERTISED_10baseT_Half; |
@@ -768,7 +768,7 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw) | |||
768 | 768 | ||
769 | int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc) | 769 | int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc) |
770 | { | 770 | { |
771 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | 771 | struct atl1c_adapter *adapter = hw->adapter; |
772 | struct pci_dev *pdev = adapter->pdev; | 772 | struct pci_dev *pdev = adapter->pdev; |
773 | u32 master_ctrl, mac_ctrl, phy_ctrl; | 773 | u32 master_ctrl, mac_ctrl, phy_ctrl; |
774 | u32 wol_ctrl, speed; | 774 | u32 wol_ctrl, speed; |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 9cc15701101b..85717cb306d1 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c | |||
@@ -989,12 +989,12 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter) | |||
989 | } | 989 | } |
990 | for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { | 990 | for (i = 0; i < AT_MAX_TRANSMIT_QUEUE; i++) { |
991 | tpd_ring[i].buffer_info = | 991 | tpd_ring[i].buffer_info = |
992 | (struct atl1c_buffer *) (tpd_ring->buffer_info + count); | 992 | (tpd_ring->buffer_info + count); |
993 | count += tpd_ring[i].count; | 993 | count += tpd_ring[i].count; |
994 | } | 994 | } |
995 | 995 | ||
996 | rfd_ring->buffer_info = | 996 | rfd_ring->buffer_info = |
997 | (struct atl1c_buffer *) (tpd_ring->buffer_info + count); | 997 | (tpd_ring->buffer_info + count); |
998 | count += rfd_ring->count; | 998 | count += rfd_ring->count; |
999 | rx_desc_count += rfd_ring->count; | 999 | rx_desc_count += rfd_ring->count; |
1000 | 1000 | ||
@@ -1227,7 +1227,7 @@ static void atl1c_start_mac(struct atl1c_adapter *adapter) | |||
1227 | */ | 1227 | */ |
1228 | static int atl1c_reset_mac(struct atl1c_hw *hw) | 1228 | static int atl1c_reset_mac(struct atl1c_hw *hw) |
1229 | { | 1229 | { |
1230 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | 1230 | struct atl1c_adapter *adapter = hw->adapter; |
1231 | struct pci_dev *pdev = adapter->pdev; | 1231 | struct pci_dev *pdev = adapter->pdev; |
1232 | u32 ctrl_data = 0; | 1232 | u32 ctrl_data = 0; |
1233 | 1233 | ||
@@ -1531,8 +1531,7 @@ static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) | |||
1531 | static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, | 1531 | static bool atl1c_clean_tx_irq(struct atl1c_adapter *adapter, |
1532 | enum atl1c_trans_queue type) | 1532 | enum atl1c_trans_queue type) |
1533 | { | 1533 | { |
1534 | struct atl1c_tpd_ring *tpd_ring = (struct atl1c_tpd_ring *) | 1534 | struct atl1c_tpd_ring *tpd_ring = &adapter->tpd_ring[type]; |
1535 | &adapter->tpd_ring[type]; | ||
1536 | struct atl1c_buffer *buffer_info; | 1535 | struct atl1c_buffer *buffer_info; |
1537 | struct pci_dev *pdev = adapter->pdev; | 1536 | struct pci_dev *pdev = adapter->pdev; |
1538 | u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); | 1537 | u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); |
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c index 6e61f9f9ebb5..82b23861bf55 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_ethtool.c | |||
@@ -268,7 +268,7 @@ static int atl1e_set_eeprom(struct net_device *netdev, | |||
268 | if (eeprom_buff == NULL) | 268 | if (eeprom_buff == NULL) |
269 | return -ENOMEM; | 269 | return -ENOMEM; |
270 | 270 | ||
271 | ptr = (u32 *)eeprom_buff; | 271 | ptr = eeprom_buff; |
272 | 272 | ||
273 | if (eeprom->offset & 3) { | 273 | if (eeprom->offset & 3) { |
274 | /* need read/modify/write of first changed EEPROM word */ | 274 | /* need read/modify/write of first changed EEPROM word */ |
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 1220e511ced6..0aed82e1bb3e 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c | |||
@@ -641,8 +641,7 @@ static int __devinit atl1e_sw_init(struct atl1e_adapter *adapter) | |||
641 | */ | 641 | */ |
642 | static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) | 642 | static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) |
643 | { | 643 | { |
644 | struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) | 644 | struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; |
645 | &adapter->tx_ring; | ||
646 | struct atl1e_tx_buffer *tx_buffer = NULL; | 645 | struct atl1e_tx_buffer *tx_buffer = NULL; |
647 | struct pci_dev *pdev = adapter->pdev; | 646 | struct pci_dev *pdev = adapter->pdev; |
648 | u16 index, ring_count; | 647 | u16 index, ring_count; |
@@ -686,7 +685,7 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter) | |||
686 | static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter) | 685 | static void atl1e_clean_rx_ring(struct atl1e_adapter *adapter) |
687 | { | 686 | { |
688 | struct atl1e_rx_ring *rx_ring = | 687 | struct atl1e_rx_ring *rx_ring = |
689 | (struct atl1e_rx_ring *)&adapter->rx_ring; | 688 | &adapter->rx_ring; |
690 | struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc; | 689 | struct atl1e_rx_page_desc *rx_page_desc = rx_ring->rx_page_desc; |
691 | u16 i, j; | 690 | u16 i, j; |
692 | 691 | ||
@@ -884,14 +883,12 @@ failed: | |||
884 | return err; | 883 | return err; |
885 | } | 884 | } |
886 | 885 | ||
887 | static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter) | 886 | static inline void atl1e_configure_des_ring(struct atl1e_adapter *adapter) |
888 | { | 887 | { |
889 | 888 | ||
890 | struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; | 889 | struct atl1e_hw *hw = &adapter->hw; |
891 | struct atl1e_rx_ring *rx_ring = | 890 | struct atl1e_rx_ring *rx_ring = &adapter->rx_ring; |
892 | (struct atl1e_rx_ring *)&adapter->rx_ring; | 891 | struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; |
893 | struct atl1e_tx_ring *tx_ring = | ||
894 | (struct atl1e_tx_ring *)&adapter->tx_ring; | ||
895 | struct atl1e_rx_page_desc *rx_page_desc = NULL; | 892 | struct atl1e_rx_page_desc *rx_page_desc = NULL; |
896 | int i, j; | 893 | int i, j; |
897 | 894 | ||
@@ -932,7 +929,7 @@ static inline void atl1e_configure_des_ring(const struct atl1e_adapter *adapter) | |||
932 | 929 | ||
933 | static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) | 930 | static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) |
934 | { | 931 | { |
935 | struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; | 932 | struct atl1e_hw *hw = &adapter->hw; |
936 | u32 dev_ctrl_data = 0; | 933 | u32 dev_ctrl_data = 0; |
937 | u32 max_pay_load = 0; | 934 | u32 max_pay_load = 0; |
938 | u32 jumbo_thresh = 0; | 935 | u32 jumbo_thresh = 0; |
@@ -975,7 +972,7 @@ static inline void atl1e_configure_tx(struct atl1e_adapter *adapter) | |||
975 | 972 | ||
976 | static inline void atl1e_configure_rx(struct atl1e_adapter *adapter) | 973 | static inline void atl1e_configure_rx(struct atl1e_adapter *adapter) |
977 | { | 974 | { |
978 | struct atl1e_hw *hw = (struct atl1e_hw *)&adapter->hw; | 975 | struct atl1e_hw *hw = &adapter->hw; |
979 | u32 rxf_len = 0; | 976 | u32 rxf_len = 0; |
980 | u32 rxf_low = 0; | 977 | u32 rxf_low = 0; |
981 | u32 rxf_high = 0; | 978 | u32 rxf_high = 0; |
@@ -1224,8 +1221,7 @@ static inline void atl1e_clear_phy_int(struct atl1e_adapter *adapter) | |||
1224 | 1221 | ||
1225 | static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter) | 1222 | static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter) |
1226 | { | 1223 | { |
1227 | struct atl1e_tx_ring *tx_ring = (struct atl1e_tx_ring *) | 1224 | struct atl1e_tx_ring *tx_ring = &adapter->tx_ring; |
1228 | &adapter->tx_ring; | ||
1229 | struct atl1e_tx_buffer *tx_buffer = NULL; | 1225 | struct atl1e_tx_buffer *tx_buffer = NULL; |
1230 | u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX); | 1226 | u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX); |
1231 | u16 next_to_clean = atomic_read(&tx_ring->next_to_clean); | 1227 | u16 next_to_clean = atomic_read(&tx_ring->next_to_clean); |
@@ -1384,15 +1380,14 @@ static struct atl1e_rx_page *atl1e_get_rx_page(struct atl1e_adapter *adapter, | |||
1384 | (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc; | 1380 | (struct atl1e_rx_page_desc *) adapter->rx_ring.rx_page_desc; |
1385 | u8 rx_using = rx_page_desc[que].rx_using; | 1381 | u8 rx_using = rx_page_desc[que].rx_using; |
1386 | 1382 | ||
1387 | return (struct atl1e_rx_page *)&(rx_page_desc[que].rx_page[rx_using]); | 1383 | return &(rx_page_desc[que].rx_page[rx_using]); |
1388 | } | 1384 | } |
1389 | 1385 | ||
1390 | static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, | 1386 | static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que, |
1391 | int *work_done, int work_to_do) | 1387 | int *work_done, int work_to_do) |
1392 | { | 1388 | { |
1393 | struct net_device *netdev = adapter->netdev; | 1389 | struct net_device *netdev = adapter->netdev; |
1394 | struct atl1e_rx_ring *rx_ring = (struct atl1e_rx_ring *) | 1390 | struct atl1e_rx_ring *rx_ring = &adapter->rx_ring; |
1395 | &adapter->rx_ring; | ||
1396 | struct atl1e_rx_page_desc *rx_page_desc = | 1391 | struct atl1e_rx_page_desc *rx_page_desc = |
1397 | (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc; | 1392 | (struct atl1e_rx_page_desc *) rx_ring->rx_page_desc; |
1398 | struct sk_buff *skb = NULL; | 1393 | struct sk_buff *skb = NULL; |
@@ -1576,7 +1571,7 @@ static struct atl1e_tpd_desc *atl1e_get_tpd(struct atl1e_adapter *adapter) | |||
1576 | tx_ring->next_to_use = 0; | 1571 | tx_ring->next_to_use = 0; |
1577 | 1572 | ||
1578 | memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc)); | 1573 | memset(&tx_ring->desc[next_to_use], 0, sizeof(struct atl1e_tpd_desc)); |
1579 | return (struct atl1e_tpd_desc *)&tx_ring->desc[next_to_use]; | 1574 | return &tx_ring->desc[next_to_use]; |
1580 | } | 1575 | } |
1581 | 1576 | ||
1582 | static struct atl1e_tx_buffer * | 1577 | static struct atl1e_tx_buffer * |
@@ -2061,8 +2056,8 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2061 | 2056 | ||
2062 | if (wufc) { | 2057 | if (wufc) { |
2063 | /* get link status */ | 2058 | /* get link status */ |
2064 | atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); | 2059 | atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data); |
2065 | atl1e_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); | 2060 | atl1e_read_phy_reg(hw, MII_BMSR, &mii_bmsr_data); |
2066 | 2061 | ||
2067 | mii_advertise_data = ADVERTISE_10HALF; | 2062 | mii_advertise_data = ADVERTISE_10HALF; |
2068 | 2063 | ||
@@ -2086,7 +2081,7 @@ static int atl1e_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2086 | for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { | 2081 | for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { |
2087 | msleep(100); | 2082 | msleep(100); |
2088 | atl1e_read_phy_reg(hw, MII_BMSR, | 2083 | atl1e_read_phy_reg(hw, MII_BMSR, |
2089 | (u16 *)&mii_bmsr_data); | 2084 | &mii_bmsr_data); |
2090 | if (mii_bmsr_data & BMSR_LSTATUS) | 2085 | if (mii_bmsr_data & BMSR_LSTATUS) |
2091 | break; | 2086 | break; |
2092 | } | 2087 | } |
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index 5d10884e5080..149a294d54e9 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c | |||
@@ -1061,7 +1061,7 @@ static s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) | |||
1061 | goto err_nomem; | 1061 | goto err_nomem; |
1062 | } | 1062 | } |
1063 | rfd_ring->buffer_info = | 1063 | rfd_ring->buffer_info = |
1064 | (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count); | 1064 | (tpd_ring->buffer_info + tpd_ring->count); |
1065 | 1065 | ||
1066 | /* | 1066 | /* |
1067 | * real ring DMA buffer | 1067 | * real ring DMA buffer |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index ac7b74488531..ff5d3c1f1217 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -872,8 +872,7 @@ bnx2_alloc_mem(struct bnx2 *bp) | |||
872 | 872 | ||
873 | bnapi = &bp->bnx2_napi[i]; | 873 | bnapi = &bp->bnx2_napi[i]; |
874 | 874 | ||
875 | sblk = (void *) (status_blk + | 875 | sblk = (status_blk + BNX2_SBLK_MSIX_ALIGN_SIZE * i); |
876 | BNX2_SBLK_MSIX_ALIGN_SIZE * i); | ||
877 | bnapi->status_blk.msix = sblk; | 876 | bnapi->status_blk.msix = sblk; |
878 | bnapi->hw_tx_cons_ptr = | 877 | bnapi->hw_tx_cons_ptr = |
879 | &sblk->status_tx_quick_consumer_index; | 878 | &sblk->status_tx_quick_consumer_index; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index ddc18ee5c5ae..bf30e2829285 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -177,6 +177,8 @@ static const struct { | |||
177 | 4, STATS_FLAGS_FUNC, "recoverable_errors" }, | 177 | 4, STATS_FLAGS_FUNC, "recoverable_errors" }, |
178 | { STATS_OFFSET32(unrecoverable_error), | 178 | { STATS_OFFSET32(unrecoverable_error), |
179 | 4, STATS_FLAGS_FUNC, "unrecoverable_errors" }, | 179 | 4, STATS_FLAGS_FUNC, "unrecoverable_errors" }, |
180 | { STATS_OFFSET32(eee_tx_lpi), | ||
181 | 4, STATS_FLAGS_PORT, "Tx LPI entry count"} | ||
180 | }; | 182 | }; |
181 | 183 | ||
182 | #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) | 184 | #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) |
@@ -1543,6 +1545,136 @@ static const struct { | |||
1543 | { "idle check (online)" } | 1545 | { "idle check (online)" } |
1544 | }; | 1546 | }; |
1545 | 1547 | ||
1548 | static u32 bnx2x_eee_to_adv(u32 eee_adv) | ||
1549 | { | ||
1550 | u32 modes = 0; | ||
1551 | |||
1552 | if (eee_adv & SHMEM_EEE_100M_ADV) | ||
1553 | modes |= ADVERTISED_100baseT_Full; | ||
1554 | if (eee_adv & SHMEM_EEE_1G_ADV) | ||
1555 | modes |= ADVERTISED_1000baseT_Full; | ||
1556 | if (eee_adv & SHMEM_EEE_10G_ADV) | ||
1557 | modes |= ADVERTISED_10000baseT_Full; | ||
1558 | |||
1559 | return modes; | ||
1560 | } | ||
1561 | |||
1562 | static u32 bnx2x_adv_to_eee(u32 modes, u32 shift) | ||
1563 | { | ||
1564 | u32 eee_adv = 0; | ||
1565 | if (modes & ADVERTISED_100baseT_Full) | ||
1566 | eee_adv |= SHMEM_EEE_100M_ADV; | ||
1567 | if (modes & ADVERTISED_1000baseT_Full) | ||
1568 | eee_adv |= SHMEM_EEE_1G_ADV; | ||
1569 | if (modes & ADVERTISED_10000baseT_Full) | ||
1570 | eee_adv |= SHMEM_EEE_10G_ADV; | ||
1571 | |||
1572 | return eee_adv << shift; | ||
1573 | } | ||
1574 | |||
1575 | static int bnx2x_get_eee(struct net_device *dev, struct ethtool_eee *edata) | ||
1576 | { | ||
1577 | struct bnx2x *bp = netdev_priv(dev); | ||
1578 | u32 eee_cfg; | ||
1579 | |||
1580 | if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) { | ||
1581 | DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n"); | ||
1582 | return -EOPNOTSUPP; | ||
1583 | } | ||
1584 | |||
1585 | eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]); | ||
1586 | |||
1587 | edata->supported = | ||
1588 | bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_SUPPORTED_MASK) >> | ||
1589 | SHMEM_EEE_SUPPORTED_SHIFT); | ||
1590 | |||
1591 | edata->advertised = | ||
1592 | bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_ADV_STATUS_MASK) >> | ||
1593 | SHMEM_EEE_ADV_STATUS_SHIFT); | ||
1594 | edata->lp_advertised = | ||
1595 | bnx2x_eee_to_adv((eee_cfg & SHMEM_EEE_LP_ADV_STATUS_MASK) >> | ||
1596 | SHMEM_EEE_LP_ADV_STATUS_SHIFT); | ||
1597 | |||
1598 | /* SHMEM value is in 16u units --> Convert to 1u units. */ | ||
1599 | edata->tx_lpi_timer = (eee_cfg & SHMEM_EEE_TIMER_MASK) << 4; | ||
1600 | |||
1601 | edata->eee_enabled = (eee_cfg & SHMEM_EEE_REQUESTED_BIT) ? 1 : 0; | ||
1602 | edata->eee_active = (eee_cfg & SHMEM_EEE_ACTIVE_BIT) ? 1 : 0; | ||
1603 | edata->tx_lpi_enabled = (eee_cfg & SHMEM_EEE_LPI_REQUESTED_BIT) ? 1 : 0; | ||
1604 | |||
1605 | return 0; | ||
1606 | } | ||
1607 | |||
1608 | static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) | ||
1609 | { | ||
1610 | struct bnx2x *bp = netdev_priv(dev); | ||
1611 | u32 eee_cfg; | ||
1612 | u32 advertised; | ||
1613 | |||
1614 | if (IS_MF(bp)) | ||
1615 | return 0; | ||
1616 | |||
1617 | if (!SHMEM2_HAS(bp, eee_status[BP_PORT(bp)])) { | ||
1618 | DP(BNX2X_MSG_ETHTOOL, "BC Version does not support EEE\n"); | ||
1619 | return -EOPNOTSUPP; | ||
1620 | } | ||
1621 | |||
1622 | eee_cfg = SHMEM2_RD(bp, eee_status[BP_PORT(bp)]); | ||
1623 | |||
1624 | if (!(eee_cfg & SHMEM_EEE_SUPPORTED_MASK)) { | ||
1625 | DP(BNX2X_MSG_ETHTOOL, "Board does not support EEE!\n"); | ||
1626 | return -EOPNOTSUPP; | ||
1627 | } | ||
1628 | |||
1629 | advertised = bnx2x_adv_to_eee(edata->advertised, | ||
1630 | SHMEM_EEE_ADV_STATUS_SHIFT); | ||
1631 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { | ||
1632 | DP(BNX2X_MSG_ETHTOOL, | ||
1633 | "Direct manipulation of EEE advertisment is not supported\n"); | ||
1634 | return -EINVAL; | ||
1635 | } | ||
1636 | |||
1637 | if (edata->tx_lpi_timer > EEE_MODE_TIMER_MASK) { | ||
1638 | DP(BNX2X_MSG_ETHTOOL, | ||
1639 | "Maximal Tx Lpi timer supported is %x(u)\n", | ||
1640 | EEE_MODE_TIMER_MASK); | ||
1641 | return -EINVAL; | ||
1642 | } | ||
1643 | if (edata->tx_lpi_enabled && | ||
1644 | (edata->tx_lpi_timer < EEE_MODE_NVRAM_AGGRESSIVE_TIME)) { | ||
1645 | DP(BNX2X_MSG_ETHTOOL, | ||
1646 | "Minimal Tx Lpi timer supported is %d(u)\n", | ||
1647 | EEE_MODE_NVRAM_AGGRESSIVE_TIME); | ||
1648 | return -EINVAL; | ||
1649 | } | ||
1650 | |||
1651 | /* All is well; Apply changes*/ | ||
1652 | if (edata->eee_enabled) | ||
1653 | bp->link_params.eee_mode |= EEE_MODE_ADV_LPI; | ||
1654 | else | ||
1655 | bp->link_params.eee_mode &= ~EEE_MODE_ADV_LPI; | ||
1656 | |||
1657 | if (edata->tx_lpi_enabled) | ||
1658 | bp->link_params.eee_mode |= EEE_MODE_ENABLE_LPI; | ||
1659 | else | ||
1660 | bp->link_params.eee_mode &= ~EEE_MODE_ENABLE_LPI; | ||
1661 | |||
1662 | bp->link_params.eee_mode &= ~EEE_MODE_TIMER_MASK; | ||
1663 | bp->link_params.eee_mode |= (edata->tx_lpi_timer & | ||
1664 | EEE_MODE_TIMER_MASK) | | ||
1665 | EEE_MODE_OVERRIDE_NVRAM | | ||
1666 | EEE_MODE_OUTPUT_TIME; | ||
1667 | |||
1668 | /* Restart link to propogate changes */ | ||
1669 | if (netif_running(dev)) { | ||
1670 | bnx2x_stats_handle(bp, STATS_EVENT_STOP); | ||
1671 | bnx2x_link_set(bp); | ||
1672 | } | ||
1673 | |||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1677 | |||
1546 | enum { | 1678 | enum { |
1547 | BNX2X_CHIP_E1_OFST = 0, | 1679 | BNX2X_CHIP_E1_OFST = 0, |
1548 | BNX2X_CHIP_E1H_OFST, | 1680 | BNX2X_CHIP_E1H_OFST, |
@@ -2472,6 +2604,8 @@ static const struct ethtool_ops bnx2x_ethtool_ops = { | |||
2472 | .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, | 2604 | .get_rxfh_indir_size = bnx2x_get_rxfh_indir_size, |
2473 | .get_rxfh_indir = bnx2x_get_rxfh_indir, | 2605 | .get_rxfh_indir = bnx2x_get_rxfh_indir, |
2474 | .set_rxfh_indir = bnx2x_set_rxfh_indir, | 2606 | .set_rxfh_indir = bnx2x_set_rxfh_indir, |
2607 | .get_eee = bnx2x_get_eee, | ||
2608 | .set_eee = bnx2x_set_eee, | ||
2475 | }; | 2609 | }; |
2476 | 2610 | ||
2477 | void bnx2x_set_ethtool_ops(struct net_device *netdev) | 2611 | void bnx2x_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index a440a8ba85f2..c61aa37298a3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | |||
@@ -1067,8 +1067,18 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ | |||
1067 | uses the same defines as link_config */ | 1067 | uses the same defines as link_config */ |
1068 | u32 mfw_wol_link_cfg2; /* 0x480 */ | 1068 | u32 mfw_wol_link_cfg2; /* 0x480 */ |
1069 | 1069 | ||
1070 | u32 Reserved2[17]; /* 0x484 */ | ||
1071 | 1070 | ||
1071 | /* EEE power saving mode */ | ||
1072 | u32 eee_power_mode; /* 0x484 */ | ||
1073 | #define PORT_FEAT_CFG_EEE_POWER_MODE_MASK 0x000000FF | ||
1074 | #define PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT 0 | ||
1075 | #define PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED 0x00000000 | ||
1076 | #define PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED 0x00000001 | ||
1077 | #define PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE 0x00000002 | ||
1078 | #define PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY 0x00000003 | ||
1079 | |||
1080 | |||
1081 | u32 Reserved2[16]; /* 0x488 */ | ||
1072 | }; | 1082 | }; |
1073 | 1083 | ||
1074 | 1084 | ||
@@ -1255,6 +1265,8 @@ struct drv_func_mb { | |||
1255 | #define DRV_MSG_CODE_DRV_INFO_ACK 0xd8000000 | 1265 | #define DRV_MSG_CODE_DRV_INFO_ACK 0xd8000000 |
1256 | #define DRV_MSG_CODE_DRV_INFO_NACK 0xd9000000 | 1266 | #define DRV_MSG_CODE_DRV_INFO_NACK 0xd9000000 |
1257 | 1267 | ||
1268 | #define DRV_MSG_CODE_EEE_RESULTS_ACK 0xda000000 | ||
1269 | |||
1258 | #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 | 1270 | #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 |
1259 | #define REQ_BC_VER_4_SET_MF_BW 0x00060202 | 1271 | #define REQ_BC_VER_4_SET_MF_BW 0x00060202 |
1260 | #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 | 1272 | #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 |
@@ -1320,6 +1332,8 @@ struct drv_func_mb { | |||
1320 | #define FW_MSG_CODE_DRV_INFO_ACK 0xd8100000 | 1332 | #define FW_MSG_CODE_DRV_INFO_ACK 0xd8100000 |
1321 | #define FW_MSG_CODE_DRV_INFO_NACK 0xd9100000 | 1333 | #define FW_MSG_CODE_DRV_INFO_NACK 0xd9100000 |
1322 | 1334 | ||
1335 | #define FW_MSG_CODE_EEE_RESULS_ACK 0xda100000 | ||
1336 | |||
1323 | #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 | 1337 | #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 |
1324 | #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 | 1338 | #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 |
1325 | 1339 | ||
@@ -1383,6 +1397,8 @@ struct drv_func_mb { | |||
1383 | 1397 | ||
1384 | #define DRV_STATUS_DRV_INFO_REQ 0x04000000 | 1398 | #define DRV_STATUS_DRV_INFO_REQ 0x04000000 |
1385 | 1399 | ||
1400 | #define DRV_STATUS_EEE_NEGOTIATION_RESULTS 0x08000000 | ||
1401 | |||
1386 | u32 virt_mac_upper; | 1402 | u32 virt_mac_upper; |
1387 | #define VIRT_MAC_SIGN_MASK 0xffff0000 | 1403 | #define VIRT_MAC_SIGN_MASK 0xffff0000 |
1388 | #define VIRT_MAC_SIGNATURE 0x564d0000 | 1404 | #define VIRT_MAC_SIGNATURE 0x564d0000 |
@@ -1613,6 +1629,11 @@ struct fw_flr_mb { | |||
1613 | struct fw_flr_ack ack; | 1629 | struct fw_flr_ack ack; |
1614 | }; | 1630 | }; |
1615 | 1631 | ||
1632 | struct eee_remote_vals { | ||
1633 | u32 tx_tw; | ||
1634 | u32 rx_tw; | ||
1635 | }; | ||
1636 | |||
1616 | /**** SUPPORT FOR SHMEM ARRRAYS *** | 1637 | /**** SUPPORT FOR SHMEM ARRRAYS *** |
1617 | * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to | 1638 | * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to |
1618 | * define arrays with storage types smaller then unsigned dwords. | 1639 | * define arrays with storage types smaller then unsigned dwords. |
@@ -2053,6 +2074,41 @@ struct shmem2_region { | |||
2053 | #define DRV_INFO_CONTROL_OP_CODE_MASK 0x0000ff00 | 2074 | #define DRV_INFO_CONTROL_OP_CODE_MASK 0x0000ff00 |
2054 | #define DRV_INFO_CONTROL_OP_CODE_SHIFT 8 | 2075 | #define DRV_INFO_CONTROL_OP_CODE_SHIFT 8 |
2055 | u32 ibft_host_addr; /* initialized by option ROM */ | 2076 | u32 ibft_host_addr; /* initialized by option ROM */ |
2077 | struct eee_remote_vals eee_remote_vals[PORT_MAX]; | ||
2078 | u32 reserved[E2_FUNC_MAX]; | ||
2079 | |||
2080 | |||
2081 | /* the status of EEE auto-negotiation | ||
2082 | * bits 15:0 the configured tx-lpi entry timer value. Depends on bit 31. | ||
2083 | * bits 19:16 the supported modes for EEE. | ||
2084 | * bits 23:20 the speeds advertised for EEE. | ||
2085 | * bits 27:24 the speeds the Link partner advertised for EEE. | ||
2086 | * The supported/adv. modes in bits 27:19 originate from the | ||
2087 | * SHMEM_EEE_XXX_ADV definitions (where XXX is replaced by speed). | ||
2088 | * bit 28 when 1'b1 EEE was requested. | ||
2089 | * bit 29 when 1'b1 tx lpi was requested. | ||
2090 | * bit 30 when 1'b1 EEE was negotiated. Tx lpi will be asserted iff | ||
2091 | * 30:29 are 2'b11. | ||
2092 | * bit 31 when 1'b0 bits 15:0 contain a PORT_FEAT_CFG_EEE_ define as | ||
2093 | * value. When 1'b1 those bits contains a value times 16 microseconds. | ||
2094 | */ | ||
2095 | u32 eee_status[PORT_MAX]; | ||
2096 | #define SHMEM_EEE_TIMER_MASK 0x0000ffff | ||
2097 | #define SHMEM_EEE_SUPPORTED_MASK 0x000f0000 | ||
2098 | #define SHMEM_EEE_SUPPORTED_SHIFT 16 | ||
2099 | #define SHMEM_EEE_ADV_STATUS_MASK 0x00f00000 | ||
2100 | #define SHMEM_EEE_100M_ADV (1<<0) | ||
2101 | #define SHMEM_EEE_1G_ADV (1<<1) | ||
2102 | #define SHMEM_EEE_10G_ADV (1<<2) | ||
2103 | #define SHMEM_EEE_ADV_STATUS_SHIFT 20 | ||
2104 | #define SHMEM_EEE_LP_ADV_STATUS_MASK 0x0f000000 | ||
2105 | #define SHMEM_EEE_LP_ADV_STATUS_SHIFT 24 | ||
2106 | #define SHMEM_EEE_REQUESTED_BIT 0x10000000 | ||
2107 | #define SHMEM_EEE_LPI_REQUESTED_BIT 0x20000000 | ||
2108 | #define SHMEM_EEE_ACTIVE_BIT 0x40000000 | ||
2109 | #define SHMEM_EEE_TIME_OUTPUT_BIT 0x80000000 | ||
2110 | |||
2111 | u32 sizeof_port_stats; | ||
2056 | }; | 2112 | }; |
2057 | 2113 | ||
2058 | 2114 | ||
@@ -2599,6 +2655,9 @@ struct host_port_stats { | |||
2599 | u32 pfc_frames_tx_lo; | 2655 | u32 pfc_frames_tx_lo; |
2600 | u32 pfc_frames_rx_hi; | 2656 | u32 pfc_frames_rx_hi; |
2601 | u32 pfc_frames_rx_lo; | 2657 | u32 pfc_frames_rx_lo; |
2658 | |||
2659 | u32 eee_lpi_count_hi; | ||
2660 | u32 eee_lpi_count_lo; | ||
2602 | }; | 2661 | }; |
2603 | 2662 | ||
2604 | 2663 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a3fb7215cd89..c7c814db027d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -1305,6 +1305,94 @@ int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) | |||
1305 | 1305 | ||
1306 | return 0; | 1306 | return 0; |
1307 | } | 1307 | } |
1308 | |||
1309 | /******************************************************************/ | ||
1310 | /* EEE section */ | ||
1311 | /******************************************************************/ | ||
1312 | static u8 bnx2x_eee_has_cap(struct link_params *params) | ||
1313 | { | ||
1314 | struct bnx2x *bp = params->bp; | ||
1315 | |||
1316 | if (REG_RD(bp, params->shmem2_base) <= | ||
1317 | offsetof(struct shmem2_region, eee_status[params->port])) | ||
1318 | return 0; | ||
1319 | |||
1320 | return 1; | ||
1321 | } | ||
1322 | |||
1323 | static int bnx2x_eee_nvram_to_time(u32 nvram_mode, u32 *idle_timer) | ||
1324 | { | ||
1325 | switch (nvram_mode) { | ||
1326 | case PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED: | ||
1327 | *idle_timer = EEE_MODE_NVRAM_BALANCED_TIME; | ||
1328 | break; | ||
1329 | case PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE: | ||
1330 | *idle_timer = EEE_MODE_NVRAM_AGGRESSIVE_TIME; | ||
1331 | break; | ||
1332 | case PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY: | ||
1333 | *idle_timer = EEE_MODE_NVRAM_LATENCY_TIME; | ||
1334 | break; | ||
1335 | default: | ||
1336 | *idle_timer = 0; | ||
1337 | break; | ||
1338 | } | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | static int bnx2x_eee_time_to_nvram(u32 idle_timer, u32 *nvram_mode) | ||
1344 | { | ||
1345 | switch (idle_timer) { | ||
1346 | case EEE_MODE_NVRAM_BALANCED_TIME: | ||
1347 | *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED; | ||
1348 | break; | ||
1349 | case EEE_MODE_NVRAM_AGGRESSIVE_TIME: | ||
1350 | *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE; | ||
1351 | break; | ||
1352 | case EEE_MODE_NVRAM_LATENCY_TIME: | ||
1353 | *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY; | ||
1354 | break; | ||
1355 | default: | ||
1356 | *nvram_mode = PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED; | ||
1357 | break; | ||
1358 | } | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1363 | static u32 bnx2x_eee_calc_timer(struct link_params *params) | ||
1364 | { | ||
1365 | u32 eee_mode, eee_idle; | ||
1366 | struct bnx2x *bp = params->bp; | ||
1367 | |||
1368 | if (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) { | ||
1369 | if (params->eee_mode & EEE_MODE_OUTPUT_TIME) { | ||
1370 | /* time value in eee_mode --> used directly*/ | ||
1371 | eee_idle = params->eee_mode & EEE_MODE_TIMER_MASK; | ||
1372 | } else { | ||
1373 | /* hsi value in eee_mode --> time */ | ||
1374 | if (bnx2x_eee_nvram_to_time(params->eee_mode & | ||
1375 | EEE_MODE_NVRAM_MASK, | ||
1376 | &eee_idle)) | ||
1377 | return 0; | ||
1378 | } | ||
1379 | } else { | ||
1380 | /* hsi values in nvram --> time*/ | ||
1381 | eee_mode = ((REG_RD(bp, params->shmem_base + | ||
1382 | offsetof(struct shmem_region, dev_info. | ||
1383 | port_feature_config[params->port]. | ||
1384 | eee_power_mode)) & | ||
1385 | PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >> | ||
1386 | PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT); | ||
1387 | |||
1388 | if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle)) | ||
1389 | return 0; | ||
1390 | } | ||
1391 | |||
1392 | return eee_idle; | ||
1393 | } | ||
1394 | |||
1395 | |||
1308 | /******************************************************************/ | 1396 | /******************************************************************/ |
1309 | /* PFC section */ | 1397 | /* PFC section */ |
1310 | /******************************************************************/ | 1398 | /******************************************************************/ |
@@ -1729,6 +1817,14 @@ static int bnx2x_xmac_enable(struct link_params *params, | |||
1729 | /* update PFC */ | 1817 | /* update PFC */ |
1730 | bnx2x_update_pfc_xmac(params, vars, 0); | 1818 | bnx2x_update_pfc_xmac(params, vars, 0); |
1731 | 1819 | ||
1820 | if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) { | ||
1821 | DP(NETIF_MSG_LINK, "Setting XMAC for EEE\n"); | ||
1822 | REG_WR(bp, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008); | ||
1823 | REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x1); | ||
1824 | } else { | ||
1825 | REG_WR(bp, xmac_base + XMAC_REG_EEE_CTRL, 0x0); | ||
1826 | } | ||
1827 | |||
1732 | /* Enable TX and RX */ | 1828 | /* Enable TX and RX */ |
1733 | val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; | 1829 | val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN; |
1734 | 1830 | ||
@@ -2439,6 +2535,16 @@ static void bnx2x_update_mng(struct link_params *params, u32 link_status) | |||
2439 | port_mb[params->port].link_status), link_status); | 2535 | port_mb[params->port].link_status), link_status); |
2440 | } | 2536 | } |
2441 | 2537 | ||
2538 | static void bnx2x_update_mng_eee(struct link_params *params, u32 eee_status) | ||
2539 | { | ||
2540 | struct bnx2x *bp = params->bp; | ||
2541 | |||
2542 | if (bnx2x_eee_has_cap(params)) | ||
2543 | REG_WR(bp, params->shmem2_base + | ||
2544 | offsetof(struct shmem2_region, | ||
2545 | eee_status[params->port]), eee_status); | ||
2546 | } | ||
2547 | |||
2442 | static void bnx2x_update_pfc_nig(struct link_params *params, | 2548 | static void bnx2x_update_pfc_nig(struct link_params *params, |
2443 | struct link_vars *vars, | 2549 | struct link_vars *vars, |
2444 | struct bnx2x_nig_brb_pfc_port_params *nig_params) | 2550 | struct bnx2x_nig_brb_pfc_port_params *nig_params) |
@@ -3950,6 +4056,20 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3950 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 4056 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3951 | MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); | 4057 | MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); |
3952 | 4058 | ||
4059 | /* Enable LPI pass through */ | ||
4060 | if ((params->eee_mode & EEE_MODE_ADV_LPI) && | ||
4061 | (phy->flags & FLAGS_EEE_10GBT) && | ||
4062 | (!(params->eee_mode & EEE_MODE_ENABLE_LPI) || | ||
4063 | bnx2x_eee_calc_timer(params)) && | ||
4064 | (params->req_duplex[bnx2x_phy_selection(params)] == DUPLEX_FULL)) { | ||
4065 | DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n"); | ||
4066 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
4067 | MDIO_WC_REG_EEE_COMBO_CONTROL0, | ||
4068 | 0x7c); | ||
4069 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
4070 | MDIO_WC_REG_DIGITAL4_MISC5, 0xc000); | ||
4071 | } | ||
4072 | |||
3953 | /* 10G XFI Full Duplex */ | 4073 | /* 10G XFI Full Duplex */ |
3954 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 4074 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3955 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); | 4075 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); |
@@ -6462,6 +6582,15 @@ static int bnx2x_update_link_down(struct link_params *params, | |||
6462 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | 6582 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); |
6463 | } | 6583 | } |
6464 | if (CHIP_IS_E3(bp)) { | 6584 | if (CHIP_IS_E3(bp)) { |
6585 | REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), | ||
6586 | 0); | ||
6587 | REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0); | ||
6588 | REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2), | ||
6589 | 0); | ||
6590 | vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | | ||
6591 | SHMEM_EEE_ACTIVE_BIT); | ||
6592 | |||
6593 | bnx2x_update_mng_eee(params, vars->eee_status); | ||
6465 | bnx2x_xmac_disable(params); | 6594 | bnx2x_xmac_disable(params); |
6466 | bnx2x_umac_disable(params); | 6595 | bnx2x_umac_disable(params); |
6467 | } | 6596 | } |
@@ -6501,6 +6630,16 @@ static int bnx2x_update_link_up(struct link_params *params, | |||
6501 | bnx2x_umac_enable(params, vars, 0); | 6630 | bnx2x_umac_enable(params, vars, 0); |
6502 | bnx2x_set_led(params, vars, | 6631 | bnx2x_set_led(params, vars, |
6503 | LED_MODE_OPER, vars->line_speed); | 6632 | LED_MODE_OPER, vars->line_speed); |
6633 | |||
6634 | if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) && | ||
6635 | (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) { | ||
6636 | DP(NETIF_MSG_LINK, "Enabling LPI assertion\n"); | ||
6637 | REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + | ||
6638 | (params->port << 2), 1); | ||
6639 | REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 1); | ||
6640 | REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + | ||
6641 | (params->port << 2), 0xfc20); | ||
6642 | } | ||
6504 | } | 6643 | } |
6505 | if ((CHIP_IS_E1x(bp) || | 6644 | if ((CHIP_IS_E1x(bp) || |
6506 | CHIP_IS_E2(bp))) { | 6645 | CHIP_IS_E2(bp))) { |
@@ -6538,7 +6677,7 @@ static int bnx2x_update_link_up(struct link_params *params, | |||
6538 | 6677 | ||
6539 | /* update shared memory */ | 6678 | /* update shared memory */ |
6540 | bnx2x_update_mng(params, vars->link_status); | 6679 | bnx2x_update_mng(params, vars->link_status); |
6541 | 6680 | bnx2x_update_mng_eee(params, vars->eee_status); | |
6542 | /* Check remote fault */ | 6681 | /* Check remote fault */ |
6543 | for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { | 6682 | for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { |
6544 | if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { | 6683 | if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { |
@@ -6582,6 +6721,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
6582 | phy_vars[phy_index].phy_link_up = 0; | 6721 | phy_vars[phy_index].phy_link_up = 0; |
6583 | phy_vars[phy_index].link_up = 0; | 6722 | phy_vars[phy_index].link_up = 0; |
6584 | phy_vars[phy_index].fault_detected = 0; | 6723 | phy_vars[phy_index].fault_detected = 0; |
6724 | /* different consideration, since vars holds inner state */ | ||
6725 | phy_vars[phy_index].eee_status = vars->eee_status; | ||
6585 | } | 6726 | } |
6586 | 6727 | ||
6587 | if (USES_WARPCORE(bp)) | 6728 | if (USES_WARPCORE(bp)) |
@@ -6711,6 +6852,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
6711 | vars->link_status |= LINK_STATUS_SERDES_LINK; | 6852 | vars->link_status |= LINK_STATUS_SERDES_LINK; |
6712 | else | 6853 | else |
6713 | vars->link_status &= ~LINK_STATUS_SERDES_LINK; | 6854 | vars->link_status &= ~LINK_STATUS_SERDES_LINK; |
6855 | |||
6856 | vars->eee_status = phy_vars[active_external_phy].eee_status; | ||
6857 | |||
6714 | DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", | 6858 | DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", |
6715 | active_external_phy); | 6859 | active_external_phy); |
6716 | } | 6860 | } |
@@ -9579,9 +9723,9 @@ static int bnx2x_8481_config_init(struct bnx2x_phy *phy, | |||
9579 | static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | 9723 | static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, |
9580 | struct link_params *params, | 9724 | struct link_params *params, |
9581 | u16 fw_cmd, | 9725 | u16 fw_cmd, |
9582 | u16 cmd_args[]) | 9726 | u16 cmd_args[], int argc) |
9583 | { | 9727 | { |
9584 | u32 idx; | 9728 | int idx; |
9585 | u16 val; | 9729 | u16 val; |
9586 | struct bnx2x *bp = params->bp; | 9730 | struct bnx2x *bp = params->bp; |
9587 | /* Write CMD_OPEN_OVERRIDE to STATUS reg */ | 9731 | /* Write CMD_OPEN_OVERRIDE to STATUS reg */ |
@@ -9601,7 +9745,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | |||
9601 | } | 9745 | } |
9602 | 9746 | ||
9603 | /* Prepare argument(s) and issue command */ | 9747 | /* Prepare argument(s) and issue command */ |
9604 | for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { | 9748 | for (idx = 0; idx < argc; idx++) { |
9605 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, | 9749 | bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, |
9606 | MDIO_84833_CMD_HDLR_DATA1 + idx, | 9750 | MDIO_84833_CMD_HDLR_DATA1 + idx, |
9607 | cmd_args[idx]); | 9751 | cmd_args[idx]); |
@@ -9622,7 +9766,7 @@ static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy, | |||
9622 | return -EINVAL; | 9766 | return -EINVAL; |
9623 | } | 9767 | } |
9624 | /* Gather returning data */ | 9768 | /* Gather returning data */ |
9625 | for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) { | 9769 | for (idx = 0; idx < argc; idx++) { |
9626 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, | 9770 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, |
9627 | MDIO_84833_CMD_HDLR_DATA1 + idx, | 9771 | MDIO_84833_CMD_HDLR_DATA1 + idx, |
9628 | &cmd_args[idx]); | 9772 | &cmd_args[idx]); |
@@ -9656,7 +9800,7 @@ static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy, | |||
9656 | data[1] = (u16)pair_swap; | 9800 | data[1] = (u16)pair_swap; |
9657 | 9801 | ||
9658 | status = bnx2x_84833_cmd_hdlr(phy, params, | 9802 | status = bnx2x_84833_cmd_hdlr(phy, params, |
9659 | PHY84833_CMD_SET_PAIR_SWAP, data); | 9803 | PHY84833_CMD_SET_PAIR_SWAP, data, PHY84833_CMDHDLR_MAX_ARGS); |
9660 | if (status == 0) | 9804 | if (status == 0) |
9661 | DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); | 9805 | DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]); |
9662 | 9806 | ||
@@ -9734,6 +9878,95 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy, | |||
9734 | return 0; | 9878 | return 0; |
9735 | } | 9879 | } |
9736 | 9880 | ||
9881 | static int bnx2x_8483x_eee_timers(struct link_params *params, | ||
9882 | struct link_vars *vars) | ||
9883 | { | ||
9884 | u32 eee_idle = 0, eee_mode; | ||
9885 | struct bnx2x *bp = params->bp; | ||
9886 | |||
9887 | eee_idle = bnx2x_eee_calc_timer(params); | ||
9888 | |||
9889 | if (eee_idle) { | ||
9890 | REG_WR(bp, MISC_REG_CPMU_LP_IDLE_THR_P0 + (params->port << 2), | ||
9891 | eee_idle); | ||
9892 | } else if ((params->eee_mode & EEE_MODE_ENABLE_LPI) && | ||
9893 | (params->eee_mode & EEE_MODE_OVERRIDE_NVRAM) && | ||
9894 | (params->eee_mode & EEE_MODE_OUTPUT_TIME)) { | ||
9895 | DP(NETIF_MSG_LINK, "Error: Tx LPI is enabled with timer 0\n"); | ||
9896 | return -EINVAL; | ||
9897 | } | ||
9898 | |||
9899 | vars->eee_status &= ~(SHMEM_EEE_TIMER_MASK | SHMEM_EEE_TIME_OUTPUT_BIT); | ||
9900 | if (params->eee_mode & EEE_MODE_OUTPUT_TIME) { | ||
9901 | /* eee_idle in 1u --> eee_status in 16u */ | ||
9902 | eee_idle >>= 4; | ||
9903 | vars->eee_status |= (eee_idle & SHMEM_EEE_TIMER_MASK) | | ||
9904 | SHMEM_EEE_TIME_OUTPUT_BIT; | ||
9905 | } else { | ||
9906 | if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode)) | ||
9907 | return -EINVAL; | ||
9908 | vars->eee_status |= eee_mode; | ||
9909 | } | ||
9910 | |||
9911 | return 0; | ||
9912 | } | ||
9913 | |||
9914 | static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy, | ||
9915 | struct link_params *params, | ||
9916 | struct link_vars *vars) | ||
9917 | { | ||
9918 | int rc; | ||
9919 | struct bnx2x *bp = params->bp; | ||
9920 | u16 cmd_args = 0; | ||
9921 | |||
9922 | DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n"); | ||
9923 | |||
9924 | /* Make Certain LPI is disabled */ | ||
9925 | REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2), 0); | ||
9926 | REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 0); | ||
9927 | |||
9928 | /* Prevent Phy from working in EEE and advertising it */ | ||
9929 | rc = bnx2x_84833_cmd_hdlr(phy, params, | ||
9930 | PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); | ||
9931 | if (rc != 0) { | ||
9932 | DP(NETIF_MSG_LINK, "EEE disable failed.\n"); | ||
9933 | return rc; | ||
9934 | } | ||
9935 | |||
9936 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0); | ||
9937 | vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK; | ||
9938 | |||
9939 | return 0; | ||
9940 | } | ||
9941 | |||
9942 | static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy, | ||
9943 | struct link_params *params, | ||
9944 | struct link_vars *vars) | ||
9945 | { | ||
9946 | int rc; | ||
9947 | struct bnx2x *bp = params->bp; | ||
9948 | u16 cmd_args = 1; | ||
9949 | |||
9950 | DP(NETIF_MSG_LINK, "Advertise 10GBase-T EEE\n"); | ||
9951 | |||
9952 | rc = bnx2x_84833_cmd_hdlr(phy, params, | ||
9953 | PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1); | ||
9954 | if (rc != 0) { | ||
9955 | DP(NETIF_MSG_LINK, "EEE enable failed.\n"); | ||
9956 | return rc; | ||
9957 | } | ||
9958 | |||
9959 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_EEE_ADV, 0x8); | ||
9960 | |||
9961 | /* Mask events preventing LPI generation */ | ||
9962 | REG_WR(bp, MISC_REG_CPMU_LP_MASK_EXT_P0 + (params->port << 2), 0xfc20); | ||
9963 | |||
9964 | vars->eee_status &= ~SHMEM_EEE_ADV_STATUS_MASK; | ||
9965 | vars->eee_status |= (SHMEM_EEE_10G_ADV << SHMEM_EEE_ADV_STATUS_SHIFT); | ||
9966 | |||
9967 | return 0; | ||
9968 | } | ||
9969 | |||
9737 | #define PHY84833_CONSTANT_LATENCY 1193 | 9970 | #define PHY84833_CONSTANT_LATENCY 1193 |
9738 | static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | 9971 | static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, |
9739 | struct link_params *params, | 9972 | struct link_params *params, |
@@ -9833,7 +10066,8 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
9833 | cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; | 10066 | cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1; |
9834 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; | 10067 | cmd_args[3] = PHY84833_CONSTANT_LATENCY; |
9835 | rc = bnx2x_84833_cmd_hdlr(phy, params, | 10068 | rc = bnx2x_84833_cmd_hdlr(phy, params, |
9836 | PHY84833_CMD_SET_EEE_MODE, cmd_args); | 10069 | PHY84833_CMD_SET_EEE_MODE, cmd_args, |
10070 | PHY84833_CMDHDLR_MAX_ARGS); | ||
9837 | if (rc != 0) | 10071 | if (rc != 0) |
9838 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); | 10072 | DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n"); |
9839 | } | 10073 | } |
@@ -9858,6 +10092,48 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
9858 | MDIO_CTL_REG_84823_USER_CTRL_REG, val); | 10092 | MDIO_CTL_REG_84823_USER_CTRL_REG, val); |
9859 | } | 10093 | } |
9860 | 10094 | ||
10095 | bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, | ||
10096 | MDIO_84833_TOP_CFG_FW_REV, &val); | ||
10097 | |||
10098 | /* Configure EEE support */ | ||
10099 | if ((val >= MDIO_84833_TOP_CFG_FW_EEE) && bnx2x_eee_has_cap(params)) { | ||
10100 | phy->flags |= FLAGS_EEE_10GBT; | ||
10101 | vars->eee_status |= SHMEM_EEE_10G_ADV << | ||
10102 | SHMEM_EEE_SUPPORTED_SHIFT; | ||
10103 | /* Propogate params' bits --> vars (for migration exposure) */ | ||
10104 | if (params->eee_mode & EEE_MODE_ENABLE_LPI) | ||
10105 | vars->eee_status |= SHMEM_EEE_LPI_REQUESTED_BIT; | ||
10106 | else | ||
10107 | vars->eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT; | ||
10108 | |||
10109 | if (params->eee_mode & EEE_MODE_ADV_LPI) | ||
10110 | vars->eee_status |= SHMEM_EEE_REQUESTED_BIT; | ||
10111 | else | ||
10112 | vars->eee_status &= ~SHMEM_EEE_REQUESTED_BIT; | ||
10113 | |||
10114 | rc = bnx2x_8483x_eee_timers(params, vars); | ||
10115 | if (rc != 0) { | ||
10116 | DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n"); | ||
10117 | bnx2x_8483x_disable_eee(phy, params, vars); | ||
10118 | return rc; | ||
10119 | } | ||
10120 | |||
10121 | if ((params->req_duplex[actual_phy_selection] == DUPLEX_FULL) && | ||
10122 | (params->eee_mode & EEE_MODE_ADV_LPI) && | ||
10123 | (bnx2x_eee_calc_timer(params) || | ||
10124 | !(params->eee_mode & EEE_MODE_ENABLE_LPI))) | ||
10125 | rc = bnx2x_8483x_enable_eee(phy, params, vars); | ||
10126 | else | ||
10127 | rc = bnx2x_8483x_disable_eee(phy, params, vars); | ||
10128 | if (rc != 0) { | ||
10129 | DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); | ||
10130 | return rc; | ||
10131 | } | ||
10132 | } else { | ||
10133 | phy->flags &= ~FLAGS_EEE_10GBT; | ||
10134 | vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK; | ||
10135 | } | ||
10136 | |||
9861 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { | 10137 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { |
9862 | /* Bring PHY out of super isolate mode as the final step. */ | 10138 | /* Bring PHY out of super isolate mode as the final step. */ |
9863 | bnx2x_cl45_read(bp, phy, | 10139 | bnx2x_cl45_read(bp, phy, |
@@ -9989,6 +10265,31 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, | |||
9989 | if (val & (1<<11)) | 10265 | if (val & (1<<11)) |
9990 | vars->link_status |= | 10266 | vars->link_status |= |
9991 | LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE; | 10267 | LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE; |
10268 | |||
10269 | /* Determine if EEE was negotiated */ | ||
10270 | if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { | ||
10271 | u32 eee_shmem = 0; | ||
10272 | |||
10273 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
10274 | MDIO_AN_REG_EEE_ADV, &val1); | ||
10275 | bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, | ||
10276 | MDIO_AN_REG_LP_EEE_ADV, &val2); | ||
10277 | if ((val1 & val2) & 0x8) { | ||
10278 | DP(NETIF_MSG_LINK, "EEE negotiated\n"); | ||
10279 | vars->eee_status |= SHMEM_EEE_ACTIVE_BIT; | ||
10280 | } | ||
10281 | |||
10282 | if (val2 & 0x12) | ||
10283 | eee_shmem |= SHMEM_EEE_100M_ADV; | ||
10284 | if (val2 & 0x4) | ||
10285 | eee_shmem |= SHMEM_EEE_1G_ADV; | ||
10286 | if (val2 & 0x68) | ||
10287 | eee_shmem |= SHMEM_EEE_10G_ADV; | ||
10288 | |||
10289 | vars->eee_status &= ~SHMEM_EEE_LP_ADV_STATUS_MASK; | ||
10290 | vars->eee_status |= (eee_shmem << | ||
10291 | SHMEM_EEE_LP_ADV_STATUS_SHIFT); | ||
10292 | } | ||
9992 | } | 10293 | } |
9993 | 10294 | ||
9994 | return link_up; | 10295 | return link_up; |
@@ -11243,7 +11544,8 @@ static struct bnx2x_phy phy_84833 = { | |||
11243 | .def_md_devad = 0, | 11544 | .def_md_devad = 0, |
11244 | .flags = (FLAGS_FAN_FAILURE_DET_REQ | | 11545 | .flags = (FLAGS_FAN_FAILURE_DET_REQ | |
11245 | FLAGS_REARM_LATCH_SIGNAL | | 11546 | FLAGS_REARM_LATCH_SIGNAL | |
11246 | FLAGS_TX_ERROR_CHECK), | 11547 | FLAGS_TX_ERROR_CHECK | |
11548 | FLAGS_EEE_10GBT), | ||
11247 | .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | 11549 | .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, |
11248 | .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | 11550 | .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, |
11249 | .mdio_ctrl = 0, | 11551 | .mdio_ctrl = 0, |
@@ -12011,6 +12313,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
12011 | break; | 12313 | break; |
12012 | } | 12314 | } |
12013 | bnx2x_update_mng(params, vars->link_status); | 12315 | bnx2x_update_mng(params, vars->link_status); |
12316 | |||
12317 | bnx2x_update_mng_eee(params, vars->eee_status); | ||
12014 | return 0; | 12318 | return 0; |
12015 | } | 12319 | } |
12016 | 12320 | ||
@@ -12023,6 +12327,9 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
12023 | /* disable attentions */ | 12327 | /* disable attentions */ |
12024 | vars->link_status = 0; | 12328 | vars->link_status = 0; |
12025 | bnx2x_update_mng(params, vars->link_status); | 12329 | bnx2x_update_mng(params, vars->link_status); |
12330 | vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | | ||
12331 | SHMEM_EEE_ACTIVE_BIT); | ||
12332 | bnx2x_update_mng_eee(params, vars->eee_status); | ||
12026 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | 12333 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, |
12027 | (NIG_MASK_XGXS0_LINK_STATUS | | 12334 | (NIG_MASK_XGXS0_LINK_STATUS | |
12028 | NIG_MASK_XGXS0_LINK10G | | 12335 | NIG_MASK_XGXS0_LINK10G | |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index ea4371f4335f..e920800a7bc5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | |||
@@ -149,6 +149,7 @@ struct bnx2x_phy { | |||
149 | #define FLAGS_DUMMY_READ (1<<9) | 149 | #define FLAGS_DUMMY_READ (1<<9) |
150 | #define FLAGS_MDC_MDIO_WA_B0 (1<<10) | 150 | #define FLAGS_MDC_MDIO_WA_B0 (1<<10) |
151 | #define FLAGS_TX_ERROR_CHECK (1<<12) | 151 | #define FLAGS_TX_ERROR_CHECK (1<<12) |
152 | #define FLAGS_EEE_10GBT (1<<13) | ||
152 | 153 | ||
153 | /* preemphasis values for the rx side */ | 154 | /* preemphasis values for the rx side */ |
154 | u16 rx_preemphasis[4]; | 155 | u16 rx_preemphasis[4]; |
@@ -265,6 +266,30 @@ struct link_params { | |||
265 | u8 num_phys; | 266 | u8 num_phys; |
266 | 267 | ||
267 | u8 rsrv; | 268 | u8 rsrv; |
269 | |||
270 | /* Used to configure the EEE Tx LPI timer, has several modes of | ||
271 | * operation, according to bits 29:28 - | ||
272 | * 2'b00: Timer will be configured by nvram, output will be the value | ||
273 | * from nvram. | ||
274 | * 2'b01: Timer will be configured by nvram, output will be in | ||
275 | * microseconds. | ||
276 | * 2'b10: bits 1:0 contain an nvram value which will be used instead | ||
277 | * of the one located in the nvram. Output will be that value. | ||
278 | * 2'b11: bits 19:0 contain the idle timer in microseconds; output | ||
279 | * will be in microseconds. | ||
280 | * Bits 31:30 should be 2'b11 in order for EEE to be enabled. | ||
281 | */ | ||
282 | u32 eee_mode; | ||
283 | #define EEE_MODE_NVRAM_BALANCED_TIME (0xa00) | ||
284 | #define EEE_MODE_NVRAM_AGGRESSIVE_TIME (0x100) | ||
285 | #define EEE_MODE_NVRAM_LATENCY_TIME (0x6000) | ||
286 | #define EEE_MODE_NVRAM_MASK (0x3) | ||
287 | #define EEE_MODE_TIMER_MASK (0xfffff) | ||
288 | #define EEE_MODE_OUTPUT_TIME (1<<28) | ||
289 | #define EEE_MODE_OVERRIDE_NVRAM (1<<29) | ||
290 | #define EEE_MODE_ENABLE_LPI (1<<30) | ||
291 | #define EEE_MODE_ADV_LPI (1<<31) | ||
292 | |||
268 | u16 hw_led_mode; /* part of the hw_config read from the shmem */ | 293 | u16 hw_led_mode; /* part of the hw_config read from the shmem */ |
269 | u32 multi_phy_config; | 294 | u32 multi_phy_config; |
270 | 295 | ||
@@ -301,6 +326,7 @@ struct link_vars { | |||
301 | 326 | ||
302 | /* The same definitions as the shmem parameter */ | 327 | /* The same definitions as the shmem parameter */ |
303 | u32 link_status; | 328 | u32 link_status; |
329 | u32 eee_status; | ||
304 | u8 fault_detected; | 330 | u8 fault_detected; |
305 | u8 rsrv1; | 331 | u8 rsrv1; |
306 | u16 periodic_flags; | 332 | u16 periodic_flags; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f755a665dab3..a622bb7bf21d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -3176,6 +3176,12 @@ static void bnx2x_set_mf_bw(struct bnx2x *bp) | |||
3176 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); | 3176 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); |
3177 | } | 3177 | } |
3178 | 3178 | ||
3179 | static void bnx2x_handle_eee_event(struct bnx2x *bp) | ||
3180 | { | ||
3181 | DP(BNX2X_MSG_MCP, "EEE - LLDP event\n"); | ||
3182 | bnx2x_fw_command(bp, DRV_MSG_CODE_EEE_RESULTS_ACK, 0); | ||
3183 | } | ||
3184 | |||
3179 | static void bnx2x_handle_drv_info_req(struct bnx2x *bp) | 3185 | static void bnx2x_handle_drv_info_req(struct bnx2x *bp) |
3180 | { | 3186 | { |
3181 | enum drv_info_opcode op_code; | 3187 | enum drv_info_opcode op_code; |
@@ -3742,6 +3748,8 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) | |||
3742 | if (val & DRV_STATUS_AFEX_EVENT_MASK) | 3748 | if (val & DRV_STATUS_AFEX_EVENT_MASK) |
3743 | bnx2x_handle_afex_cmd(bp, | 3749 | bnx2x_handle_afex_cmd(bp, |
3744 | val & DRV_STATUS_AFEX_EVENT_MASK); | 3750 | val & DRV_STATUS_AFEX_EVENT_MASK); |
3751 | if (val & DRV_STATUS_EEE_NEGOTIATION_RESULTS) | ||
3752 | bnx2x_handle_eee_event(bp); | ||
3745 | if (bp->link_vars.periodic_flags & | 3753 | if (bp->link_vars.periodic_flags & |
3746 | PERIODIC_FLAGS_LINK_EVENT) { | 3754 | PERIODIC_FLAGS_LINK_EVENT) { |
3747 | /* sync with link */ | 3755 | /* sync with link */ |
@@ -10082,7 +10090,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
10082 | { | 10090 | { |
10083 | int port = BP_PORT(bp); | 10091 | int port = BP_PORT(bp); |
10084 | u32 config; | 10092 | u32 config; |
10085 | u32 ext_phy_type, ext_phy_config; | 10093 | u32 ext_phy_type, ext_phy_config, eee_mode; |
10086 | 10094 | ||
10087 | bp->link_params.bp = bp; | 10095 | bp->link_params.bp = bp; |
10088 | bp->link_params.port = port; | 10096 | bp->link_params.port = port; |
@@ -10149,6 +10157,19 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
10149 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, | 10157 | bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, |
10150 | bp->common.shmem_base, | 10158 | bp->common.shmem_base, |
10151 | bp->common.shmem2_base); | 10159 | bp->common.shmem2_base); |
10160 | |||
10161 | /* Configure link feature according to nvram value */ | ||
10162 | eee_mode = (((SHMEM_RD(bp, dev_info. | ||
10163 | port_feature_config[port].eee_power_mode)) & | ||
10164 | PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >> | ||
10165 | PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT); | ||
10166 | if (eee_mode != PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED) { | ||
10167 | bp->link_params.eee_mode = EEE_MODE_ADV_LPI | | ||
10168 | EEE_MODE_ENABLE_LPI | | ||
10169 | EEE_MODE_OUTPUT_TIME; | ||
10170 | } else { | ||
10171 | bp->link_params.eee_mode = 0; | ||
10172 | } | ||
10152 | } | 10173 | } |
10153 | 10174 | ||
10154 | void bnx2x_get_iscsi_info(struct bnx2x *bp) | 10175 | void bnx2x_get_iscsi_info(struct bnx2x *bp) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index bbd387492a80..bfef98f666c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -1488,6 +1488,121 @@ | |||
1488 | * 2:1 - otp_misc_do[51:50]; 0 - otp_misc_do[1]. */ | 1488 | * 2:1 - otp_misc_do[51:50]; 0 - otp_misc_do[1]. */ |
1489 | #define MISC_REG_CHIP_TYPE 0xac60 | 1489 | #define MISC_REG_CHIP_TYPE 0xac60 |
1490 | #define MISC_REG_CHIP_TYPE_57811_MASK (1<<1) | 1490 | #define MISC_REG_CHIP_TYPE_57811_MASK (1<<1) |
1491 | #define MISC_REG_CPMU_LP_DR_ENABLE 0xa858 | ||
1492 | /* [RW 1] FW EEE LPI Enable. When 1 indicates that EEE LPI mode is enabled | ||
1493 | * by FW. When 0 indicates that the EEE LPI mode is disabled by FW. Clk | ||
1494 | * 25MHz. Reset on hard reset. */ | ||
1495 | #define MISC_REG_CPMU_LP_FW_ENABLE_P0 0xa84c | ||
1496 | /* [RW 32] EEE LPI Idle Threshold. The threshold value for the idle EEE LPI | ||
1497 | * counter. Timer tick is 1 us. Clock 25MHz. Reset on hard reset. */ | ||
1498 | #define MISC_REG_CPMU_LP_IDLE_THR_P0 0xa8a0 | ||
1499 | /* [RW 18] LPI entry events mask. [0] - Vmain SM Mask. When 1 indicates that | ||
1500 | * the Vmain SM end state is disabled. When 0 indicates that the Vmain SM | ||
1501 | * end state is enabled. [1] - FW Queues Empty Mask. When 1 indicates that | ||
1502 | * the FW command that all Queues are empty is disabled. When 0 indicates | ||
1503 | * that the FW command that all Queues are empty is enabled. [2] - FW Early | ||
1504 | * Exit Mask / Reserved (Entry mask). When 1 indicates that the FW Early | ||
1505 | * Exit command is disabled. When 0 indicates that the FW Early Exit command | ||
1506 | * is enabled. This bit applicable only in the EXIT Events Mask registers. | ||
1507 | * [3] - PBF Request Mask. When 1 indicates that the PBF Request indication | ||
1508 | * is disabled. When 0 indicates that the PBF Request indication is enabled. | ||
1509 | * [4] - Tx Request Mask. When =1 indicates that the Tx other Than PBF | ||
1510 | * Request indication is disabled. When 0 indicates that the Tx Other Than | ||
1511 | * PBF Request indication is enabled. [5] - Rx EEE LPI Status Mask. When 1 | ||
1512 | * indicates that the RX EEE LPI Status indication is disabled. When 0 | ||
1513 | * indicates that the RX EEE LPI Status indication is enabled. In the EXIT | ||
1514 | * Events Masks registers; this bit masks the falling edge detect of the LPI | ||
1515 | * Status (Rx LPI is on - off). [6] - Tx Pause Mask. When 1 indicates that | ||
1516 | * the Tx Pause indication is disabled. When 0 indicates that the Tx Pause | ||
1517 | * indication is enabled. [7] - BRB1 Empty Mask. When 1 indicates that the | ||
1518 | * BRB1 EMPTY indication is disabled. When 0 indicates that the BRB1 EMPTY | ||
1519 | * indication is enabled. [8] - QM Idle Mask. When 1 indicates that the QM | ||
1520 | * IDLE indication is disabled. When 0 indicates that the QM IDLE indication | ||
1521 | * is enabled. (One bit for both VOQ0 and VOQ1). [9] - QM LB Idle Mask. When | ||
1522 | * 1 indicates that the QM IDLE indication for LOOPBACK is disabled. When 0 | ||
1523 | * indicates that the QM IDLE indication for LOOPBACK is enabled. [10] - L1 | ||
1524 | * Status Mask. When 1 indicates that the L1 Status indication from the PCIE | ||
1525 | * CORE is disabled. When 0 indicates that the RX EEE LPI Status indication | ||
1526 | * from the PCIE CORE is enabled. In the EXIT Events Masks registers; this | ||
1527 | * bit masks the falling edge detect of the L1 status (L1 is on - off). [11] | ||
1528 | * - P0 E0 EEE EEE LPI REQ Mask. When =1 indicates that the P0 E0 EEE EEE | ||
1529 | * LPI REQ indication is disabled. When =0 indicates that the P0 E0 EEE LPI | ||
1530 | * REQ indication is enabled. [12] - P1 E0 EEE LPI REQ Mask. When =1 | ||
1531 | * indicates that the P0 EEE LPI REQ indication is disabled. When =0 | ||
1532 | * indicates that the P0 EEE LPI REQ indication is enabled. [13] - P0 E1 EEE | ||
1533 | * LPI REQ Mask. When =1 indicates that the P0 EEE LPI REQ indication is | ||
1534 | * disabled. When =0 indicates that the P0 EEE LPI REQ indication is | ||
1535 | * enabled. [14] - P1 E1 EEE LPI REQ Mask. When =1 indicates that the P0 EEE | ||
1536 | * LPI REQ indication is disabled. When =0 indicates that the P0 EEE LPI REQ | ||
1537 | * indication is enabled. [15] - L1 REQ Mask. When =1 indicates that the L1 | ||
1538 | * REQ indication is disabled. When =0 indicates that the L1 indication is | ||
1539 | * enabled. [16] - Rx EEE LPI Status Edge Detect Mask. When =1 indicates | ||
1540 | * that the RX EEE LPI Status Falling Edge Detect indication is disabled (Rx | ||
1541 | * EEE LPI is on - off). When =0 indicates that the RX EEE LPI Status | ||
1542 | * Falling Edge Detec indication is enabled (Rx EEE LPI is on - off). This | ||
1543 | * bit is applicable only in the EXIT Events Masks registers. [17] - L1 | ||
1544 | * Status Edge Detect Mask. When =1 indicates that the L1 Status Falling | ||
1545 | * Edge Detect indication from the PCIE CORE is disabled (L1 is on - off). | ||
1546 | * When =0 indicates that the L1 Status Falling Edge Detect indication from | ||
1547 | * the PCIE CORE is enabled (L1 is on - off). This bit is applicable only in | ||
1548 | * the EXIT Events Masks registers. Clock 25MHz. Reset on hard reset. */ | ||
1549 | #define MISC_REG_CPMU_LP_MASK_ENT_P0 0xa880 | ||
1550 | /* [RW 18] EEE LPI exit events mask. [0] - Vmain SM Mask. When 1 indicates | ||
1551 | * that the Vmain SM end state is disabled. When 0 indicates that the Vmain | ||
1552 | * SM end state is enabled. [1] - FW Queues Empty Mask. When 1 indicates | ||
1553 | * that the FW command that all Queues are empty is disabled. When 0 | ||
1554 | * indicates that the FW command that all Queues are empty is enabled. [2] - | ||
1555 | * FW Early Exit Mask / Reserved (Entry mask). When 1 indicates that the FW | ||
1556 | * Early Exit command is disabled. When 0 indicates that the FW Early Exit | ||
1557 | * command is enabled. This bit applicable only in the EXIT Events Mask | ||
1558 | * registers. [3] - PBF Request Mask. When 1 indicates that the PBF Request | ||
1559 | * indication is disabled. When 0 indicates that the PBF Request indication | ||
1560 | * is enabled. [4] - Tx Request Mask. When =1 indicates that the Tx other | ||
1561 | * Than PBF Request indication is disabled. When 0 indicates that the Tx | ||
1562 | * Other Than PBF Request indication is enabled. [5] - Rx EEE LPI Status | ||
1563 | * Mask. When 1 indicates that the RX EEE LPI Status indication is disabled. | ||
1564 | * When 0 indicates that the RX LPI Status indication is enabled. In the | ||
1565 | * EXIT Events Masks registers; this bit masks the falling edge detect of | ||
1566 | * the EEE LPI Status (Rx EEE LPI is on - off). [6] - Tx Pause Mask. When 1 | ||
1567 | * indicates that the Tx Pause indication is disabled. When 0 indicates that | ||
1568 | * the Tx Pause indication is enabled. [7] - BRB1 Empty Mask. When 1 | ||
1569 | * indicates that the BRB1 EMPTY indication is disabled. When 0 indicates | ||
1570 | * that the BRB1 EMPTY indication is enabled. [8] - QM Idle Mask. When 1 | ||
1571 | * indicates that the QM IDLE indication is disabled. When 0 indicates that | ||
1572 | * the QM IDLE indication is enabled. (One bit for both VOQ0 and VOQ1). [9] | ||
1573 | * - QM LB Idle Mask. When 1 indicates that the QM IDLE indication for | ||
1574 | * LOOPBACK is disabled. When 0 indicates that the QM IDLE indication for | ||
1575 | * LOOPBACK is enabled. [10] - L1 Status Mask. When 1 indicates that the L1 | ||
1576 | * Status indication from the PCIE CORE is disabled. When 0 indicates that | ||
1577 | * the RX EEE LPI Status indication from the PCIE CORE is enabled. In the | ||
1578 | * EXIT Events Masks registers; this bit masks the falling edge detect of | ||
1579 | * the L1 status (L1 is on - off). [11] - P0 E0 EEE EEE LPI REQ Mask. When | ||
1580 | * =1 indicates that the P0 E0 EEE EEE LPI REQ indication is disabled. When | ||
1581 | * =0 indicates that the P0 E0 EEE LPI REQ indication is enabled. [12] - P1 | ||
1582 | * E0 EEE LPI REQ Mask. When =1 indicates that the P0 EEE LPI REQ indication | ||
1583 | * is disabled. When =0 indicates that the P0 EEE LPI REQ indication is | ||
1584 | * enabled. [13] - P0 E1 EEE LPI REQ Mask. When =1 indicates that the P0 EEE | ||
1585 | * LPI REQ indication is disabled. When =0 indicates that the P0 EEE LPI REQ | ||
1586 | * indication is enabled. [14] - P1 E1 EEE LPI REQ Mask. When =1 indicates | ||
1587 | * that the P0 EEE LPI REQ indication is disabled. When =0 indicates that | ||
1588 | * the P0 EEE LPI REQ indication is enabled. [15] - L1 REQ Mask. When =1 | ||
1589 | * indicates that the L1 REQ indication is disabled. When =0 indicates that | ||
1590 | * the L1 indication is enabled. [16] - Rx EEE LPI Status Edge Detect Mask. | ||
1591 | * When =1 indicates that the RX EEE LPI Status Falling Edge Detect | ||
1592 | * indication is disabled (Rx EEE LPI is on - off). When =0 indicates that | ||
1593 | * the RX EEE LPI Status Falling Edge Detec indication is enabled (Rx EEE | ||
1594 | * LPI is on - off). This bit is applicable only in the EXIT Events Masks | ||
1595 | * registers. [17] - L1 Status Edge Detect Mask. When =1 indicates that the | ||
1596 | * L1 Status Falling Edge Detect indication from the PCIE CORE is disabled | ||
1597 | * (L1 is on - off). When =0 indicates that the L1 Status Falling Edge | ||
1598 | * Detect indication from the PCIE CORE is enabled (L1 is on - off). This | ||
1599 | * bit is applicable only in the EXIT Events Masks registers.Clock 25MHz. | ||
1600 | * Reset on hard reset. */ | ||
1601 | #define MISC_REG_CPMU_LP_MASK_EXT_P0 0xa888 | ||
1602 | /* [RW 16] EEE LPI Entry Events Counter. A statistic counter with the number | ||
1603 | * of counts that the SM entered the EEE LPI state. Clock 25MHz. Read only | ||
1604 | * register. Reset on hard reset. */ | ||
1605 | #define MISC_REG_CPMU_LP_SM_ENT_CNT_P0 0xa8b8 | ||
1491 | /* [RW 32] The following driver registers(1...16) represent 16 drivers and | 1606 | /* [RW 32] The following driver registers(1...16) represent 16 drivers and |
1492 | 32 clients. Each client can be controlled by one driver only. One in each | 1607 | 32 clients. Each client can be controlled by one driver only. One in each |
1493 | bit represent that this driver control the appropriate client (Ex: bit 5 | 1608 | bit represent that this driver control the appropriate client (Ex: bit 5 |
@@ -5372,6 +5487,8 @@ | |||
5372 | /* [RW 32] Lower 48 bits of ctrl_sa register. Used as the SA in PAUSE/PFC | 5487 | /* [RW 32] Lower 48 bits of ctrl_sa register. Used as the SA in PAUSE/PFC |
5373 | * packets transmitted by the MAC */ | 5488 | * packets transmitted by the MAC */ |
5374 | #define XMAC_REG_CTRL_SA_LO 0x28 | 5489 | #define XMAC_REG_CTRL_SA_LO 0x28 |
5490 | #define XMAC_REG_EEE_CTRL 0xd8 | ||
5491 | #define XMAC_REG_EEE_TIMERS_HI 0xe4 | ||
5375 | #define XMAC_REG_PAUSE_CTRL 0x68 | 5492 | #define XMAC_REG_PAUSE_CTRL 0x68 |
5376 | #define XMAC_REG_PFC_CTRL 0x70 | 5493 | #define XMAC_REG_PFC_CTRL 0x70 |
5377 | #define XMAC_REG_PFC_CTRL_HI 0x74 | 5494 | #define XMAC_REG_PFC_CTRL_HI 0x74 |
@@ -6813,6 +6930,8 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6813 | #define MDIO_AN_REG_LP_AUTO_NEG 0x0013 | 6930 | #define MDIO_AN_REG_LP_AUTO_NEG 0x0013 |
6814 | #define MDIO_AN_REG_LP_AUTO_NEG2 0x0014 | 6931 | #define MDIO_AN_REG_LP_AUTO_NEG2 0x0014 |
6815 | #define MDIO_AN_REG_MASTER_STATUS 0x0021 | 6932 | #define MDIO_AN_REG_MASTER_STATUS 0x0021 |
6933 | #define MDIO_AN_REG_EEE_ADV 0x003c | ||
6934 | #define MDIO_AN_REG_LP_EEE_ADV 0x003d | ||
6816 | /*bcm*/ | 6935 | /*bcm*/ |
6817 | #define MDIO_AN_REG_LINK_STATUS 0x8304 | 6936 | #define MDIO_AN_REG_LINK_STATUS 0x8304 |
6818 | #define MDIO_AN_REG_CL37_CL73 0x8370 | 6937 | #define MDIO_AN_REG_CL37_CL73 0x8370 |
@@ -6866,6 +6985,8 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6866 | #define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080 | 6985 | #define MDIO_PMA_REG_84823_LED3_STRETCH_EN 0x0080 |
6867 | 6986 | ||
6868 | /* BCM84833 only */ | 6987 | /* BCM84833 only */ |
6988 | #define MDIO_84833_TOP_CFG_FW_REV 0x400f | ||
6989 | #define MDIO_84833_TOP_CFG_FW_EEE 0x10b1 | ||
6869 | #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a | 6990 | #define MDIO_84833_TOP_CFG_XGPHY_STRAP1 0x401a |
6870 | #define MDIO_84833_SUPER_ISOLATE 0x8000 | 6991 | #define MDIO_84833_SUPER_ISOLATE 0x8000 |
6871 | /* These are mailbox register set used by 84833. */ | 6992 | /* These are mailbox register set used by 84833. */ |
@@ -6993,11 +7114,13 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6993 | #define MDIO_WC_REG_DIGITAL3_UP1 0x8329 | 7114 | #define MDIO_WC_REG_DIGITAL3_UP1 0x8329 |
6994 | #define MDIO_WC_REG_DIGITAL3_LP_UP1 0x832c | 7115 | #define MDIO_WC_REG_DIGITAL3_LP_UP1 0x832c |
6995 | #define MDIO_WC_REG_DIGITAL4_MISC3 0x833c | 7116 | #define MDIO_WC_REG_DIGITAL4_MISC3 0x833c |
7117 | #define MDIO_WC_REG_DIGITAL4_MISC5 0x833e | ||
6996 | #define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 | 7118 | #define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 |
6997 | #define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 | 7119 | #define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 |
6998 | #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e | 7120 | #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e |
6999 | #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL 0x8350 | 7121 | #define MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL 0x8350 |
7000 | #define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 | 7122 | #define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 |
7123 | #define MDIO_WC_REG_EEE_COMBO_CONTROL0 0x8390 | ||
7001 | #define MDIO_WC_REG_TX66_CONTROL 0x83b0 | 7124 | #define MDIO_WC_REG_TX66_CONTROL 0x83b0 |
7002 | #define MDIO_WC_REG_RX66_CONTROL 0x83c0 | 7125 | #define MDIO_WC_REG_RX66_CONTROL 0x83c0 |
7003 | #define MDIO_WC_REG_RX66_SCW0 0x83c2 | 7126 | #define MDIO_WC_REG_RX66_SCW0 0x83c2 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 1e2785cd11d0..0e8bdcb9c748 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -785,6 +785,10 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) | |||
785 | 785 | ||
786 | pstats->host_port_stats_counter++; | 786 | pstats->host_port_stats_counter++; |
787 | 787 | ||
788 | if (CHIP_IS_E3(bp)) | ||
789 | estats->eee_tx_lpi += REG_RD(bp, | ||
790 | MISC_REG_CPMU_LP_SM_ENT_CNT_P0); | ||
791 | |||
788 | if (!BP_NOMCP(bp)) { | 792 | if (!BP_NOMCP(bp)) { |
789 | u32 nig_timer_max = | 793 | u32 nig_timer_max = |
790 | SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); | 794 | SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 93e689fdfeda..24b8e505b60c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | |||
@@ -203,6 +203,8 @@ struct bnx2x_eth_stats { | |||
203 | /* Recovery */ | 203 | /* Recovery */ |
204 | u32 recoverable_error; | 204 | u32 recoverable_error; |
205 | u32 unrecoverable_error; | 205 | u32 unrecoverable_error; |
206 | /* src: Clear-on-Read register; Will not survive PMF Migration */ | ||
207 | u32 eee_tx_lpi; | ||
206 | }; | 208 | }; |
207 | 209 | ||
208 | 210 | ||
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index c95e7b5e2b85..65e66caea50d 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -2585,7 +2585,7 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe) | |||
2585 | return; | 2585 | return; |
2586 | } | 2586 | } |
2587 | 2587 | ||
2588 | cqes[0] = (struct kcqe *) &kcqe; | 2588 | cqes[0] = &kcqe; |
2589 | cnic_reply_bnx2x_kcqes(dev, ulp_type, cqes, 1); | 2589 | cnic_reply_bnx2x_kcqes(dev, ulp_type, cqes, 1); |
2590 | } | 2590 | } |
2591 | 2591 | ||
@@ -4665,9 +4665,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
4665 | 4665 | ||
4666 | cp->kcq1.sw_prod_idx = 0; | 4666 | cp->kcq1.sw_prod_idx = 0; |
4667 | cp->kcq1.hw_prod_idx_ptr = | 4667 | cp->kcq1.hw_prod_idx_ptr = |
4668 | (u16 *) &sblk->status_completion_producer_index; | 4668 | &sblk->status_completion_producer_index; |
4669 | 4669 | ||
4670 | cp->kcq1.status_idx_ptr = (u16 *) &sblk->status_idx; | 4670 | cp->kcq1.status_idx_ptr = &sblk->status_idx; |
4671 | 4671 | ||
4672 | /* Initialize the kernel complete queue context. */ | 4672 | /* Initialize the kernel complete queue context. */ |
4673 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | | 4673 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | |
@@ -4693,9 +4693,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
4693 | u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id); | 4693 | u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id); |
4694 | 4694 | ||
4695 | cp->kcq1.hw_prod_idx_ptr = | 4695 | cp->kcq1.hw_prod_idx_ptr = |
4696 | (u16 *) &msblk->status_completion_producer_index; | 4696 | &msblk->status_completion_producer_index; |
4697 | cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx; | 4697 | cp->kcq1.status_idx_ptr = &msblk->status_idx; |
4698 | cp->kwq_con_idx_ptr = (u16 *) &msblk->status_cmd_consumer_index; | 4698 | cp->kwq_con_idx_ptr = &msblk->status_cmd_consumer_index; |
4699 | cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; | 4699 | cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT; |
4700 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); | 4700 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); |
4701 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); | 4701 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); |
diff --git a/drivers/net/ethernet/brocade/bna/cna_fwimg.c b/drivers/net/ethernet/brocade/bna/cna_fwimg.c index cfc22a64157e..6a68e8d93309 100644 --- a/drivers/net/ethernet/brocade/bna/cna_fwimg.c +++ b/drivers/net/ethernet/brocade/bna/cna_fwimg.c | |||
@@ -67,10 +67,10 @@ bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off) | |||
67 | { | 67 | { |
68 | switch (asic_gen) { | 68 | switch (asic_gen) { |
69 | case BFI_ASIC_GEN_CT: | 69 | case BFI_ASIC_GEN_CT: |
70 | return (u32 *)(bfi_image_ct_cna + off); | 70 | return (bfi_image_ct_cna + off); |
71 | break; | 71 | break; |
72 | case BFI_ASIC_GEN_CT2: | 72 | case BFI_ASIC_GEN_CT2: |
73 | return (u32 *)(bfi_image_ct2_cna + off); | 73 | return (bfi_image_ct2_cna + off); |
74 | break; | 74 | break; |
75 | default: | 75 | default: |
76 | return NULL; | 76 | return NULL; |
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c index 65e4b280619a..55cf72af69ce 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | |||
@@ -575,7 +575,7 @@ static void t3_process_tid_release_list(struct work_struct *work) | |||
575 | if (!skb) { | 575 | if (!skb) { |
576 | spin_lock_bh(&td->tid_release_lock); | 576 | spin_lock_bh(&td->tid_release_lock); |
577 | p->ctx = (void *)td->tid_release_list; | 577 | p->ctx = (void *)td->tid_release_list; |
578 | td->tid_release_list = (struct t3c_tid_entry *)p; | 578 | td->tid_release_list = p; |
579 | break; | 579 | break; |
580 | } | 580 | } |
581 | mk_tid_release(skb, p - td->tid_maps.tid_tab); | 581 | mk_tid_release(skb, p - td->tid_maps.tid_tab); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c index e111d974afd8..8596acaa402b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c | |||
@@ -753,7 +753,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q, | |||
753 | end = (void *)q->desc + part1; | 753 | end = (void *)q->desc + part1; |
754 | } | 754 | } |
755 | if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ | 755 | if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ |
756 | *(u64 *)end = 0; | 756 | *end = 0; |
757 | } | 757 | } |
758 | 758 | ||
759 | /** | 759 | /** |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 25e3308fc9d8..9dad56101e23 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
@@ -418,7 +418,7 @@ static int fwevtq_handler(struct sge_rspq *rspq, const __be64 *rsp, | |||
418 | * restart a TX Ethernet Queue which was stopped for lack of | 418 | * restart a TX Ethernet Queue which was stopped for lack of |
419 | * free TX Queue Descriptors ... | 419 | * free TX Queue Descriptors ... |
420 | */ | 420 | */ |
421 | const struct cpl_sge_egr_update *p = (void *)cpl; | 421 | const struct cpl_sge_egr_update *p = cpl; |
422 | unsigned int qid = EGR_QID(be32_to_cpu(p->opcode_qid)); | 422 | unsigned int qid = EGR_QID(be32_to_cpu(p->opcode_qid)); |
423 | struct sge *s = &adapter->sge; | 423 | struct sge *s = &adapter->sge; |
424 | struct sge_txq *tq; | 424 | struct sge_txq *tq; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c index 0bd585bba39d..f2d1ecdcaf98 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c | |||
@@ -934,7 +934,7 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *tq, | |||
934 | end = (void *)tq->desc + part1; | 934 | end = (void *)tq->desc + part1; |
935 | } | 935 | } |
936 | if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ | 936 | if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */ |
937 | *(u64 *)end = 0; | 937 | *end = 0; |
938 | } | 938 | } |
939 | 939 | ||
940 | /** | 940 | /** |
@@ -1323,8 +1323,7 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1323 | */ | 1323 | */ |
1324 | if (unlikely((void *)sgl == (void *)tq->stat)) { | 1324 | if (unlikely((void *)sgl == (void *)tq->stat)) { |
1325 | sgl = (void *)tq->desc; | 1325 | sgl = (void *)tq->desc; |
1326 | end = (void *)((void *)tq->desc + | 1326 | end = ((void *)tq->desc + ((void *)end - (void *)tq->stat)); |
1327 | ((void *)end - (void *)tq->stat)); | ||
1328 | } | 1327 | } |
1329 | 1328 | ||
1330 | write_sgl(skb, tq, sgl, end, 0, addr); | 1329 | write_sgl(skb, tq, sgl, end, 0, addr); |
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index d3cd489d11a2..f879e9224846 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c | |||
@@ -3973,7 +3973,7 @@ DevicePresent(struct net_device *dev, u_long aprom_addr) | |||
3973 | tmp = srom_rd(aprom_addr, i); | 3973 | tmp = srom_rd(aprom_addr, i); |
3974 | *p++ = cpu_to_le16(tmp); | 3974 | *p++ = cpu_to_le16(tmp); |
3975 | } | 3975 | } |
3976 | de4x5_dbg_srom((struct de4x5_srom *)&lp->srom); | 3976 | de4x5_dbg_srom(&lp->srom); |
3977 | } | 3977 | } |
3978 | } | 3978 | } |
3979 | 3979 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index c5c4c0e83bd1..7b5cc2b212e5 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "be_hw.h" | 34 | #include "be_hw.h" |
35 | #include "be_roce.h" | 35 | #include "be_roce.h" |
36 | 36 | ||
37 | #define DRV_VER "4.2.220u" | 37 | #define DRV_VER "4.2.248.0u" |
38 | #define DRV_NAME "be2net" | 38 | #define DRV_NAME "be2net" |
39 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" | 39 | #define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" |
40 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" | 40 | #define BE3_NAME "ServerEngines BladeEngine3 10Gbps NIC" |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea381741..f8997521b147 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -1132,7 +1132,7 @@ err: | |||
1132 | * Uses MCCQ | 1132 | * Uses MCCQ |
1133 | */ | 1133 | */ |
1134 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | 1134 | int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, |
1135 | u8 *mac, u32 *if_handle, u32 *pmac_id, u32 domain) | 1135 | u32 *if_handle, u32 domain) |
1136 | { | 1136 | { |
1137 | struct be_mcc_wrb *wrb; | 1137 | struct be_mcc_wrb *wrb; |
1138 | struct be_cmd_req_if_create *req; | 1138 | struct be_cmd_req_if_create *req; |
@@ -1152,17 +1152,13 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
1152 | req->hdr.domain = domain; | 1152 | req->hdr.domain = domain; |
1153 | req->capability_flags = cpu_to_le32(cap_flags); | 1153 | req->capability_flags = cpu_to_le32(cap_flags); |
1154 | req->enable_flags = cpu_to_le32(en_flags); | 1154 | req->enable_flags = cpu_to_le32(en_flags); |
1155 | if (mac) | 1155 | |
1156 | memcpy(req->mac_addr, mac, ETH_ALEN); | 1156 | req->pmac_invalid = true; |
1157 | else | ||
1158 | req->pmac_invalid = true; | ||
1159 | 1157 | ||
1160 | status = be_mcc_notify_wait(adapter); | 1158 | status = be_mcc_notify_wait(adapter); |
1161 | if (!status) { | 1159 | if (!status) { |
1162 | struct be_cmd_resp_if_create *resp = embedded_payload(wrb); | 1160 | struct be_cmd_resp_if_create *resp = embedded_payload(wrb); |
1163 | *if_handle = le32_to_cpu(resp->interface_id); | 1161 | *if_handle = le32_to_cpu(resp->interface_id); |
1164 | if (mac) | ||
1165 | *pmac_id = le32_to_cpu(resp->pmac_id); | ||
1166 | } | 1162 | } |
1167 | 1163 | ||
1168 | err: | 1164 | err: |
@@ -2330,8 +2326,8 @@ err: | |||
2330 | } | 2326 | } |
2331 | 2327 | ||
2332 | /* Uses synchronous MCCQ */ | 2328 | /* Uses synchronous MCCQ */ |
2333 | int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, | 2329 | int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, |
2334 | bool *pmac_id_active, u32 *pmac_id, u8 *mac) | 2330 | bool *pmac_id_active, u32 *pmac_id, u8 domain) |
2335 | { | 2331 | { |
2336 | struct be_mcc_wrb *wrb; | 2332 | struct be_mcc_wrb *wrb; |
2337 | struct be_cmd_req_get_mac_list *req; | 2333 | struct be_cmd_req_get_mac_list *req; |
@@ -2376,8 +2372,9 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, | |||
2376 | get_mac_list_cmd.va; | 2372 | get_mac_list_cmd.va; |
2377 | mac_count = resp->true_mac_count + resp->pseudo_mac_count; | 2373 | mac_count = resp->true_mac_count + resp->pseudo_mac_count; |
2378 | /* Mac list returned could contain one or more active mac_ids | 2374 | /* Mac list returned could contain one or more active mac_ids |
2379 | * or one or more pseudo permanant mac addresses. If an active | 2375 | * or one or more true or pseudo permanant mac addresses. |
2380 | * mac_id is present, return first active mac_id found | 2376 | * If an active mac_id is present, return first active mac_id |
2377 | * found. | ||
2381 | */ | 2378 | */ |
2382 | for (i = 0; i < mac_count; i++) { | 2379 | for (i = 0; i < mac_count; i++) { |
2383 | struct get_list_macaddr *mac_entry; | 2380 | struct get_list_macaddr *mac_entry; |
@@ -2396,7 +2393,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, | |||
2396 | goto out; | 2393 | goto out; |
2397 | } | 2394 | } |
2398 | } | 2395 | } |
2399 | /* If no active mac_id found, return first pseudo mac addr */ | 2396 | /* If no active mac_id found, return first mac addr */ |
2400 | *pmac_id_active = false; | 2397 | *pmac_id_active = false; |
2401 | memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr, | 2398 | memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr, |
2402 | ETH_ALEN); | 2399 | ETH_ALEN); |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf420c16..2f6bb06df9c6 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h | |||
@@ -1664,8 +1664,7 @@ extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
1664 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, | 1664 | extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, |
1665 | int pmac_id, u32 domain); | 1665 | int pmac_id, u32 domain); |
1666 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, | 1666 | extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, |
1667 | u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id, | 1667 | u32 en_flags, u32 *if_handle, u32 domain); |
1668 | u32 domain); | ||
1669 | extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, | 1668 | extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle, |
1670 | u32 domain); | 1669 | u32 domain); |
1671 | extern int be_cmd_eq_create(struct be_adapter *adapter, | 1670 | extern int be_cmd_eq_create(struct be_adapter *adapter, |
@@ -1751,8 +1750,9 @@ extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); | |||
1751 | extern int be_cmd_req_native_mode(struct be_adapter *adapter); | 1750 | extern int be_cmd_req_native_mode(struct be_adapter *adapter); |
1752 | extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); | 1751 | extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size); |
1753 | extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); | 1752 | extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf); |
1754 | extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain, | 1753 | extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac, |
1755 | bool *pmac_id_active, u32 *pmac_id, u8 *mac); | 1754 | bool *pmac_id_active, u32 *pmac_id, |
1755 | u8 domain); | ||
1756 | extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, | 1756 | extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, |
1757 | u8 mac_count, u32 domain); | 1757 | u8 mac_count, u32 domain); |
1758 | extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, | 1758 | extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, |
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index d9fb0c501fa1..7c8a710eac2f 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
@@ -58,8 +58,6 @@ | |||
58 | 58 | ||
59 | #define SLI_PORT_CONTROL_IP_MASK 0x08000000 | 59 | #define SLI_PORT_CONTROL_IP_MASK 0x08000000 |
60 | 60 | ||
61 | #define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC | ||
62 | |||
63 | /********* Memory BAR register ************/ | 61 | /********* Memory BAR register ************/ |
64 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc | 62 | #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc |
65 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt | 63 | /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fdb50cec6b51..5a34503b6a14 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -719,8 +719,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, | |||
719 | * 60 bytes long. | 719 | * 60 bytes long. |
720 | * As a workaround disable TX vlan offloading in such cases. | 720 | * As a workaround disable TX vlan offloading in such cases. |
721 | */ | 721 | */ |
722 | if (unlikely(vlan_tx_tag_present(skb) && | 722 | if (vlan_tx_tag_present(skb) && |
723 | (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60))) { | 723 | (skb->ip_summed != CHECKSUM_PARTIAL || skb->len <= 60)) { |
724 | skb = skb_share_check(skb, GFP_ATOMIC); | 724 | skb = skb_share_check(skb, GFP_ATOMIC); |
725 | if (unlikely(!skb)) | 725 | if (unlikely(!skb)) |
726 | goto tx_drop; | 726 | goto tx_drop; |
@@ -786,19 +786,12 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu) | |||
786 | * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE. | 786 | * A max of 64 (BE_NUM_VLANS_SUPPORTED) vlans can be configured in BE. |
787 | * If the user configures more, place BE in vlan promiscuous mode. | 787 | * If the user configures more, place BE in vlan promiscuous mode. |
788 | */ | 788 | */ |
789 | static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) | 789 | static int be_vid_config(struct be_adapter *adapter) |
790 | { | 790 | { |
791 | struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf_num]; | 791 | u16 vids[BE_NUM_VLANS_SUPPORTED]; |
792 | u16 vtag[BE_NUM_VLANS_SUPPORTED]; | 792 | u16 num = 0, i; |
793 | u16 ntags = 0, i; | ||
794 | int status = 0; | 793 | int status = 0; |
795 | 794 | ||
796 | if (vf) { | ||
797 | vtag[0] = cpu_to_le16(vf_cfg->vlan_tag); | ||
798 | status = be_cmd_vlan_config(adapter, vf_cfg->if_handle, vtag, | ||
799 | 1, 1, 0); | ||
800 | } | ||
801 | |||
802 | /* No need to further configure vids if in promiscuous mode */ | 795 | /* No need to further configure vids if in promiscuous mode */ |
803 | if (adapter->promiscuous) | 796 | if (adapter->promiscuous) |
804 | return 0; | 797 | return 0; |
@@ -809,10 +802,10 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) | |||
809 | /* Construct VLAN Table to give to HW */ | 802 | /* Construct VLAN Table to give to HW */ |
810 | for (i = 0; i < VLAN_N_VID; i++) | 803 | for (i = 0; i < VLAN_N_VID; i++) |
811 | if (adapter->vlan_tag[i]) | 804 | if (adapter->vlan_tag[i]) |
812 | vtag[ntags++] = cpu_to_le16(i); | 805 | vids[num++] = cpu_to_le16(i); |
813 | 806 | ||
814 | status = be_cmd_vlan_config(adapter, adapter->if_handle, | 807 | status = be_cmd_vlan_config(adapter, adapter->if_handle, |
815 | vtag, ntags, 1, 0); | 808 | vids, num, 1, 0); |
816 | 809 | ||
817 | /* Set to VLAN promisc mode as setting VLAN filter failed */ | 810 | /* Set to VLAN promisc mode as setting VLAN filter failed */ |
818 | if (status) { | 811 | if (status) { |
@@ -841,7 +834,7 @@ static int be_vlan_add_vid(struct net_device *netdev, u16 vid) | |||
841 | 834 | ||
842 | adapter->vlan_tag[vid] = 1; | 835 | adapter->vlan_tag[vid] = 1; |
843 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) | 836 | if (adapter->vlans_added <= (adapter->max_vlans + 1)) |
844 | status = be_vid_config(adapter, false, 0); | 837 | status = be_vid_config(adapter); |
845 | 838 | ||
846 | if (!status) | 839 | if (!status) |
847 | adapter->vlans_added++; | 840 | adapter->vlans_added++; |
@@ -863,7 +856,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, u16 vid) | |||
863 | 856 | ||
864 | adapter->vlan_tag[vid] = 0; | 857 | adapter->vlan_tag[vid] = 0; |
865 | if (adapter->vlans_added <= adapter->max_vlans) | 858 | if (adapter->vlans_added <= adapter->max_vlans) |
866 | status = be_vid_config(adapter, false, 0); | 859 | status = be_vid_config(adapter); |
867 | 860 | ||
868 | if (!status) | 861 | if (!status) |
869 | adapter->vlans_added--; | 862 | adapter->vlans_added--; |
@@ -890,7 +883,7 @@ static void be_set_rx_mode(struct net_device *netdev) | |||
890 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); | 883 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); |
891 | 884 | ||
892 | if (adapter->vlans_added) | 885 | if (adapter->vlans_added) |
893 | be_vid_config(adapter, false, 0); | 886 | be_vid_config(adapter); |
894 | } | 887 | } |
895 | 888 | ||
896 | /* Enable multicast promisc if num configured exceeds what we support */ | 889 | /* Enable multicast promisc if num configured exceeds what we support */ |
@@ -1057,6 +1050,8 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state) | |||
1057 | u16 offset, stride; | 1050 | u16 offset, stride; |
1058 | 1051 | ||
1059 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); | 1052 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); |
1053 | if (!pos) | ||
1054 | return 0; | ||
1060 | pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); | 1055 | pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset); |
1061 | pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); | 1056 | pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride); |
1062 | 1057 | ||
@@ -1898,6 +1893,12 @@ static int be_rx_cqs_create(struct be_adapter *adapter) | |||
1898 | */ | 1893 | */ |
1899 | adapter->num_rx_qs = (num_irqs(adapter) > 1) ? | 1894 | adapter->num_rx_qs = (num_irqs(adapter) > 1) ? |
1900 | num_irqs(adapter) + 1 : 1; | 1895 | num_irqs(adapter) + 1 : 1; |
1896 | if (adapter->num_rx_qs != MAX_RX_QS) { | ||
1897 | rtnl_lock(); | ||
1898 | netif_set_real_num_rx_queues(adapter->netdev, | ||
1899 | adapter->num_rx_qs); | ||
1900 | rtnl_unlock(); | ||
1901 | } | ||
1901 | 1902 | ||
1902 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; | 1903 | adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; |
1903 | for_all_rx_queues(adapter, rxo, i) { | 1904 | for_all_rx_queues(adapter, rxo, i) { |
@@ -2544,7 +2545,6 @@ static int be_clear(struct be_adapter *adapter) | |||
2544 | be_cmd_fw_clean(adapter); | 2545 | be_cmd_fw_clean(adapter); |
2545 | 2546 | ||
2546 | be_msix_disable(adapter); | 2547 | be_msix_disable(adapter); |
2547 | pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0); | ||
2548 | return 0; | 2548 | return 0; |
2549 | } | 2549 | } |
2550 | 2550 | ||
@@ -2602,8 +2602,8 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
2602 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 2602 | cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
2603 | BE_IF_FLAGS_MULTICAST; | 2603 | BE_IF_FLAGS_MULTICAST; |
2604 | for_all_vfs(adapter, vf_cfg, vf) { | 2604 | for_all_vfs(adapter, vf_cfg, vf) { |
2605 | status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL, | 2605 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
2606 | &vf_cfg->if_handle, NULL, vf + 1); | 2606 | &vf_cfg->if_handle, vf + 1); |
2607 | if (status) | 2607 | if (status) |
2608 | goto err; | 2608 | goto err; |
2609 | } | 2609 | } |
@@ -2643,29 +2643,43 @@ static void be_setup_init(struct be_adapter *adapter) | |||
2643 | adapter->phy.forced_port_speed = -1; | 2643 | adapter->phy.forced_port_speed = -1; |
2644 | } | 2644 | } |
2645 | 2645 | ||
2646 | static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac) | 2646 | static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle, |
2647 | bool *active_mac, u32 *pmac_id) | ||
2647 | { | 2648 | { |
2648 | u32 pmac_id; | 2649 | int status = 0; |
2649 | int status; | ||
2650 | bool pmac_id_active; | ||
2651 | 2650 | ||
2652 | status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active, | 2651 | if (!is_zero_ether_addr(adapter->netdev->perm_addr)) { |
2653 | &pmac_id, mac); | 2652 | memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN); |
2654 | if (status != 0) | 2653 | if (!lancer_chip(adapter) && !be_physfn(adapter)) |
2655 | goto do_none; | 2654 | *active_mac = true; |
2655 | else | ||
2656 | *active_mac = false; | ||
2656 | 2657 | ||
2657 | if (pmac_id_active) { | 2658 | return status; |
2658 | status = be_cmd_mac_addr_query(adapter, mac, | 2659 | } |
2659 | MAC_ADDRESS_TYPE_NETWORK, | ||
2660 | false, adapter->if_handle, pmac_id); | ||
2661 | 2660 | ||
2662 | if (!status) | 2661 | if (lancer_chip(adapter)) { |
2663 | adapter->pmac_id[0] = pmac_id; | 2662 | status = be_cmd_get_mac_from_list(adapter, mac, |
2663 | active_mac, pmac_id, 0); | ||
2664 | if (*active_mac) { | ||
2665 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2666 | MAC_ADDRESS_TYPE_NETWORK, | ||
2667 | false, if_handle, | ||
2668 | *pmac_id); | ||
2669 | } | ||
2670 | } else if (be_physfn(adapter)) { | ||
2671 | /* For BE3, for PF get permanent MAC */ | ||
2672 | status = be_cmd_mac_addr_query(adapter, mac, | ||
2673 | MAC_ADDRESS_TYPE_NETWORK, true, | ||
2674 | 0, 0); | ||
2675 | *active_mac = false; | ||
2664 | } else { | 2676 | } else { |
2665 | status = be_cmd_pmac_add(adapter, mac, | 2677 | /* For BE3, for VF get soft MAC assigned by PF*/ |
2666 | adapter->if_handle, &adapter->pmac_id[0], 0); | 2678 | status = be_cmd_mac_addr_query(adapter, mac, |
2679 | MAC_ADDRESS_TYPE_NETWORK, false, | ||
2680 | if_handle, 0); | ||
2681 | *active_mac = true; | ||
2667 | } | 2682 | } |
2668 | do_none: | ||
2669 | return status; | 2683 | return status; |
2670 | } | 2684 | } |
2671 | 2685 | ||
@@ -2686,12 +2700,12 @@ static int be_get_config(struct be_adapter *adapter) | |||
2686 | 2700 | ||
2687 | static int be_setup(struct be_adapter *adapter) | 2701 | static int be_setup(struct be_adapter *adapter) |
2688 | { | 2702 | { |
2689 | struct net_device *netdev = adapter->netdev; | ||
2690 | struct device *dev = &adapter->pdev->dev; | 2703 | struct device *dev = &adapter->pdev->dev; |
2691 | u32 cap_flags, en_flags; | 2704 | u32 cap_flags, en_flags; |
2692 | u32 tx_fc, rx_fc; | 2705 | u32 tx_fc, rx_fc; |
2693 | int status; | 2706 | int status; |
2694 | u8 mac[ETH_ALEN]; | 2707 | u8 mac[ETH_ALEN]; |
2708 | bool active_mac; | ||
2695 | 2709 | ||
2696 | be_setup_init(adapter); | 2710 | be_setup_init(adapter); |
2697 | 2711 | ||
@@ -2717,14 +2731,6 @@ static int be_setup(struct be_adapter *adapter) | |||
2717 | if (status) | 2731 | if (status) |
2718 | goto err; | 2732 | goto err; |
2719 | 2733 | ||
2720 | memset(mac, 0, ETH_ALEN); | ||
2721 | status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK, | ||
2722 | true /*permanent */, 0, 0); | ||
2723 | if (status) | ||
2724 | return status; | ||
2725 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2726 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2727 | |||
2728 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | | 2734 | en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST | |
2729 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; | 2735 | BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS; |
2730 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | | 2736 | cap_flags = en_flags | BE_IF_FLAGS_MCAST_PROMISCUOUS | |
@@ -2734,27 +2740,29 @@ static int be_setup(struct be_adapter *adapter) | |||
2734 | cap_flags |= BE_IF_FLAGS_RSS; | 2740 | cap_flags |= BE_IF_FLAGS_RSS; |
2735 | en_flags |= BE_IF_FLAGS_RSS; | 2741 | en_flags |= BE_IF_FLAGS_RSS; |
2736 | } | 2742 | } |
2743 | |||
2737 | status = be_cmd_if_create(adapter, cap_flags, en_flags, | 2744 | status = be_cmd_if_create(adapter, cap_flags, en_flags, |
2738 | netdev->dev_addr, &adapter->if_handle, | 2745 | &adapter->if_handle, 0); |
2739 | &adapter->pmac_id[0], 0); | ||
2740 | if (status != 0) | 2746 | if (status != 0) |
2741 | goto err; | 2747 | goto err; |
2742 | 2748 | ||
2743 | /* The VF's permanent mac queried from card is incorrect. | 2749 | memset(mac, 0, ETH_ALEN); |
2744 | * For BEx: Query the mac configued by the PF using if_handle | 2750 | active_mac = false; |
2745 | * For Lancer: Get and use mac_list to obtain mac address. | 2751 | status = be_get_mac_addr(adapter, mac, adapter->if_handle, |
2746 | */ | 2752 | &active_mac, &adapter->pmac_id[0]); |
2747 | if (!be_physfn(adapter)) { | 2753 | if (status != 0) |
2748 | if (lancer_chip(adapter)) | 2754 | goto err; |
2749 | status = be_add_mac_from_list(adapter, mac); | 2755 | |
2750 | else | 2756 | if (!active_mac) { |
2751 | status = be_cmd_mac_addr_query(adapter, mac, | 2757 | status = be_cmd_pmac_add(adapter, mac, adapter->if_handle, |
2752 | MAC_ADDRESS_TYPE_NETWORK, false, | 2758 | &adapter->pmac_id[0], 0); |
2753 | adapter->if_handle, 0); | 2759 | if (status != 0) |
2754 | if (!status) { | 2760 | goto err; |
2755 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | 2761 | } |
2756 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | 2762 | |
2757 | } | 2763 | if (is_zero_ether_addr(adapter->netdev->dev_addr)) { |
2764 | memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN); | ||
2765 | memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN); | ||
2758 | } | 2766 | } |
2759 | 2767 | ||
2760 | status = be_tx_qs_create(adapter); | 2768 | status = be_tx_qs_create(adapter); |
@@ -2763,7 +2771,8 @@ static int be_setup(struct be_adapter *adapter) | |||
2763 | 2771 | ||
2764 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); | 2772 | be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL); |
2765 | 2773 | ||
2766 | be_vid_config(adapter, false, 0); | 2774 | if (adapter->vlans_added) |
2775 | be_vid_config(adapter); | ||
2767 | 2776 | ||
2768 | be_set_rx_mode(adapter->netdev); | 2777 | be_set_rx_mode(adapter->netdev); |
2769 | 2778 | ||
@@ -2773,8 +2782,6 @@ static int be_setup(struct be_adapter *adapter) | |||
2773 | be_cmd_set_flow_control(adapter, adapter->tx_fc, | 2782 | be_cmd_set_flow_control(adapter, adapter->tx_fc, |
2774 | adapter->rx_fc); | 2783 | adapter->rx_fc); |
2775 | 2784 | ||
2776 | pcie_set_readrq(adapter->pdev, 4096); | ||
2777 | |||
2778 | if (be_physfn(adapter) && num_vfs) { | 2785 | if (be_physfn(adapter) && num_vfs) { |
2779 | if (adapter->dev_num_vfs) | 2786 | if (adapter->dev_num_vfs) |
2780 | be_vf_setup(adapter); | 2787 | be_vf_setup(adapter); |
@@ -2788,8 +2795,6 @@ static int be_setup(struct be_adapter *adapter) | |||
2788 | 2795 | ||
2789 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); | 2796 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
2790 | adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; | 2797 | adapter->flags |= BE_FLAGS_WORKER_SCHEDULED; |
2791 | |||
2792 | pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1); | ||
2793 | return 0; | 2798 | return 0; |
2794 | err: | 2799 | err: |
2795 | be_clear(adapter); | 2800 | be_clear(adapter); |
@@ -3727,10 +3732,7 @@ reschedule: | |||
3727 | 3732 | ||
3728 | static bool be_reset_required(struct be_adapter *adapter) | 3733 | static bool be_reset_required(struct be_adapter *adapter) |
3729 | { | 3734 | { |
3730 | u32 reg; | 3735 | return be_find_vfs(adapter, ENABLED) > 0 ? false : true; |
3731 | |||
3732 | pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, ®); | ||
3733 | return reg; | ||
3734 | } | 3736 | } |
3735 | 3737 | ||
3736 | static int __devinit be_probe(struct pci_dev *pdev, | 3738 | static int __devinit be_probe(struct pci_dev *pdev, |
@@ -3749,7 +3751,7 @@ static int __devinit be_probe(struct pci_dev *pdev, | |||
3749 | goto disable_dev; | 3751 | goto disable_dev; |
3750 | pci_set_master(pdev); | 3752 | pci_set_master(pdev); |
3751 | 3753 | ||
3752 | netdev = alloc_etherdev_mq(sizeof(struct be_adapter), MAX_TX_QS); | 3754 | netdev = alloc_etherdev_mqs(sizeof(*adapter), MAX_TX_QS, MAX_RX_QS); |
3753 | if (netdev == NULL) { | 3755 | if (netdev == NULL) { |
3754 | status = -ENOMEM; | 3756 | status = -ENOMEM; |
3755 | goto rel_reg; | 3757 | goto rel_reg; |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 0741aded9eb0..f00a095f37b4 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* drivers/net/ethernet/freescale/gianfar.c |
2 | * drivers/net/ethernet/freescale/gianfar.c | ||
3 | * | 2 | * |
4 | * Gianfar Ethernet Driver | 3 | * Gianfar Ethernet Driver |
5 | * This driver is designed for the non-CPM ethernet controllers | 4 | * This driver is designed for the non-CPM ethernet controllers |
@@ -114,7 +113,7 @@ static void gfar_timeout(struct net_device *dev); | |||
114 | static int gfar_close(struct net_device *dev); | 113 | static int gfar_close(struct net_device *dev); |
115 | struct sk_buff *gfar_new_skb(struct net_device *dev); | 114 | struct sk_buff *gfar_new_skb(struct net_device *dev); |
116 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, | 115 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, |
117 | struct sk_buff *skb); | 116 | struct sk_buff *skb); |
118 | static int gfar_set_mac_address(struct net_device *dev); | 117 | static int gfar_set_mac_address(struct net_device *dev); |
119 | static int gfar_change_mtu(struct net_device *dev, int new_mtu); | 118 | static int gfar_change_mtu(struct net_device *dev, int new_mtu); |
120 | static irqreturn_t gfar_error(int irq, void *dev_id); | 119 | static irqreturn_t gfar_error(int irq, void *dev_id); |
@@ -266,8 +265,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) | |||
266 | tx_queue->tx_bd_dma_base = addr; | 265 | tx_queue->tx_bd_dma_base = addr; |
267 | tx_queue->dev = ndev; | 266 | tx_queue->dev = ndev; |
268 | /* enet DMA only understands physical addresses */ | 267 | /* enet DMA only understands physical addresses */ |
269 | addr += sizeof(struct txbd8) *tx_queue->tx_ring_size; | 268 | addr += sizeof(struct txbd8) * tx_queue->tx_ring_size; |
270 | vaddr += sizeof(struct txbd8) *tx_queue->tx_ring_size; | 269 | vaddr += sizeof(struct txbd8) * tx_queue->tx_ring_size; |
271 | } | 270 | } |
272 | 271 | ||
273 | /* Start the rx descriptor ring where the tx ring leaves off */ | 272 | /* Start the rx descriptor ring where the tx ring leaves off */ |
@@ -276,15 +275,16 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) | |||
276 | rx_queue->rx_bd_base = vaddr; | 275 | rx_queue->rx_bd_base = vaddr; |
277 | rx_queue->rx_bd_dma_base = addr; | 276 | rx_queue->rx_bd_dma_base = addr; |
278 | rx_queue->dev = ndev; | 277 | rx_queue->dev = ndev; |
279 | addr += sizeof (struct rxbd8) * rx_queue->rx_ring_size; | 278 | addr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; |
280 | vaddr += sizeof (struct rxbd8) * rx_queue->rx_ring_size; | 279 | vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size; |
281 | } | 280 | } |
282 | 281 | ||
283 | /* Setup the skbuff rings */ | 282 | /* Setup the skbuff rings */ |
284 | for (i = 0; i < priv->num_tx_queues; i++) { | 283 | for (i = 0; i < priv->num_tx_queues; i++) { |
285 | tx_queue = priv->tx_queue[i]; | 284 | tx_queue = priv->tx_queue[i]; |
286 | tx_queue->tx_skbuff = kmalloc(sizeof(*tx_queue->tx_skbuff) * | 285 | tx_queue->tx_skbuff = kmalloc(sizeof(*tx_queue->tx_skbuff) * |
287 | tx_queue->tx_ring_size, GFP_KERNEL); | 286 | tx_queue->tx_ring_size, |
287 | GFP_KERNEL); | ||
288 | if (!tx_queue->tx_skbuff) { | 288 | if (!tx_queue->tx_skbuff) { |
289 | netif_err(priv, ifup, ndev, | 289 | netif_err(priv, ifup, ndev, |
290 | "Could not allocate tx_skbuff\n"); | 290 | "Could not allocate tx_skbuff\n"); |
@@ -298,7 +298,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) | |||
298 | for (i = 0; i < priv->num_rx_queues; i++) { | 298 | for (i = 0; i < priv->num_rx_queues; i++) { |
299 | rx_queue = priv->rx_queue[i]; | 299 | rx_queue = priv->rx_queue[i]; |
300 | rx_queue->rx_skbuff = kmalloc(sizeof(*rx_queue->rx_skbuff) * | 300 | rx_queue->rx_skbuff = kmalloc(sizeof(*rx_queue->rx_skbuff) * |
301 | rx_queue->rx_ring_size, GFP_KERNEL); | 301 | rx_queue->rx_ring_size, |
302 | GFP_KERNEL); | ||
302 | 303 | ||
303 | if (!rx_queue->rx_skbuff) { | 304 | if (!rx_queue->rx_skbuff) { |
304 | netif_err(priv, ifup, ndev, | 305 | netif_err(priv, ifup, ndev, |
@@ -327,15 +328,15 @@ static void gfar_init_tx_rx_base(struct gfar_private *priv) | |||
327 | int i; | 328 | int i; |
328 | 329 | ||
329 | baddr = ®s->tbase0; | 330 | baddr = ®s->tbase0; |
330 | for(i = 0; i < priv->num_tx_queues; i++) { | 331 | for (i = 0; i < priv->num_tx_queues; i++) { |
331 | gfar_write(baddr, priv->tx_queue[i]->tx_bd_dma_base); | 332 | gfar_write(baddr, priv->tx_queue[i]->tx_bd_dma_base); |
332 | baddr += 2; | 333 | baddr += 2; |
333 | } | 334 | } |
334 | 335 | ||
335 | baddr = ®s->rbase0; | 336 | baddr = ®s->rbase0; |
336 | for(i = 0; i < priv->num_rx_queues; i++) { | 337 | for (i = 0; i < priv->num_rx_queues; i++) { |
337 | gfar_write(baddr, priv->rx_queue[i]->rx_bd_dma_base); | 338 | gfar_write(baddr, priv->rx_queue[i]->rx_bd_dma_base); |
338 | baddr += 2; | 339 | baddr += 2; |
339 | } | 340 | } |
340 | } | 341 | } |
341 | 342 | ||
@@ -405,7 +406,8 @@ static void gfar_init_mac(struct net_device *ndev) | |||
405 | gfar_write(®s->attreli, attrs); | 406 | gfar_write(®s->attreli, attrs); |
406 | 407 | ||
407 | /* Start with defaults, and add stashing or locking | 408 | /* Start with defaults, and add stashing or locking |
408 | * depending on the approprate variables */ | 409 | * depending on the approprate variables |
410 | */ | ||
409 | attrs = ATTR_INIT_SETTINGS; | 411 | attrs = ATTR_INIT_SETTINGS; |
410 | 412 | ||
411 | if (priv->bd_stash_en) | 413 | if (priv->bd_stash_en) |
@@ -426,16 +428,16 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) | |||
426 | struct gfar_private *priv = netdev_priv(dev); | 428 | struct gfar_private *priv = netdev_priv(dev); |
427 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; | 429 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; |
428 | unsigned long tx_packets = 0, tx_bytes = 0; | 430 | unsigned long tx_packets = 0, tx_bytes = 0; |
429 | int i = 0; | 431 | int i; |
430 | 432 | ||
431 | for (i = 0; i < priv->num_rx_queues; i++) { | 433 | for (i = 0; i < priv->num_rx_queues; i++) { |
432 | rx_packets += priv->rx_queue[i]->stats.rx_packets; | 434 | rx_packets += priv->rx_queue[i]->stats.rx_packets; |
433 | rx_bytes += priv->rx_queue[i]->stats.rx_bytes; | 435 | rx_bytes += priv->rx_queue[i]->stats.rx_bytes; |
434 | rx_dropped += priv->rx_queue[i]->stats.rx_dropped; | 436 | rx_dropped += priv->rx_queue[i]->stats.rx_dropped; |
435 | } | 437 | } |
436 | 438 | ||
437 | dev->stats.rx_packets = rx_packets; | 439 | dev->stats.rx_packets = rx_packets; |
438 | dev->stats.rx_bytes = rx_bytes; | 440 | dev->stats.rx_bytes = rx_bytes; |
439 | dev->stats.rx_dropped = rx_dropped; | 441 | dev->stats.rx_dropped = rx_dropped; |
440 | 442 | ||
441 | for (i = 0; i < priv->num_tx_queues; i++) { | 443 | for (i = 0; i < priv->num_tx_queues; i++) { |
@@ -443,7 +445,7 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev) | |||
443 | tx_packets += priv->tx_queue[i]->stats.tx_packets; | 445 | tx_packets += priv->tx_queue[i]->stats.tx_packets; |
444 | } | 446 | } |
445 | 447 | ||
446 | dev->stats.tx_bytes = tx_bytes; | 448 | dev->stats.tx_bytes = tx_bytes; |
447 | dev->stats.tx_packets = tx_packets; | 449 | dev->stats.tx_packets = tx_packets; |
448 | 450 | ||
449 | return &dev->stats; | 451 | return &dev->stats; |
@@ -468,7 +470,7 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
468 | 470 | ||
469 | void lock_rx_qs(struct gfar_private *priv) | 471 | void lock_rx_qs(struct gfar_private *priv) |
470 | { | 472 | { |
471 | int i = 0x0; | 473 | int i; |
472 | 474 | ||
473 | for (i = 0; i < priv->num_rx_queues; i++) | 475 | for (i = 0; i < priv->num_rx_queues; i++) |
474 | spin_lock(&priv->rx_queue[i]->rxlock); | 476 | spin_lock(&priv->rx_queue[i]->rxlock); |
@@ -476,7 +478,7 @@ void lock_rx_qs(struct gfar_private *priv) | |||
476 | 478 | ||
477 | void lock_tx_qs(struct gfar_private *priv) | 479 | void lock_tx_qs(struct gfar_private *priv) |
478 | { | 480 | { |
479 | int i = 0x0; | 481 | int i; |
480 | 482 | ||
481 | for (i = 0; i < priv->num_tx_queues; i++) | 483 | for (i = 0; i < priv->num_tx_queues; i++) |
482 | spin_lock(&priv->tx_queue[i]->txlock); | 484 | spin_lock(&priv->tx_queue[i]->txlock); |
@@ -484,7 +486,7 @@ void lock_tx_qs(struct gfar_private *priv) | |||
484 | 486 | ||
485 | void unlock_rx_qs(struct gfar_private *priv) | 487 | void unlock_rx_qs(struct gfar_private *priv) |
486 | { | 488 | { |
487 | int i = 0x0; | 489 | int i; |
488 | 490 | ||
489 | for (i = 0; i < priv->num_rx_queues; i++) | 491 | for (i = 0; i < priv->num_rx_queues; i++) |
490 | spin_unlock(&priv->rx_queue[i]->rxlock); | 492 | spin_unlock(&priv->rx_queue[i]->rxlock); |
@@ -492,7 +494,7 @@ void unlock_rx_qs(struct gfar_private *priv) | |||
492 | 494 | ||
493 | void unlock_tx_qs(struct gfar_private *priv) | 495 | void unlock_tx_qs(struct gfar_private *priv) |
494 | { | 496 | { |
495 | int i = 0x0; | 497 | int i; |
496 | 498 | ||
497 | for (i = 0; i < priv->num_tx_queues; i++) | 499 | for (i = 0; i < priv->num_tx_queues; i++) |
498 | spin_unlock(&priv->tx_queue[i]->txlock); | 500 | spin_unlock(&priv->tx_queue[i]->txlock); |
@@ -508,13 +510,13 @@ static bool gfar_is_vlan_on(struct gfar_private *priv) | |||
508 | static inline int gfar_uses_fcb(struct gfar_private *priv) | 510 | static inline int gfar_uses_fcb(struct gfar_private *priv) |
509 | { | 511 | { |
510 | return gfar_is_vlan_on(priv) || | 512 | return gfar_is_vlan_on(priv) || |
511 | (priv->ndev->features & NETIF_F_RXCSUM) || | 513 | (priv->ndev->features & NETIF_F_RXCSUM) || |
512 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); | 514 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); |
513 | } | 515 | } |
514 | 516 | ||
515 | static void free_tx_pointers(struct gfar_private *priv) | 517 | static void free_tx_pointers(struct gfar_private *priv) |
516 | { | 518 | { |
517 | int i = 0; | 519 | int i; |
518 | 520 | ||
519 | for (i = 0; i < priv->num_tx_queues; i++) | 521 | for (i = 0; i < priv->num_tx_queues; i++) |
520 | kfree(priv->tx_queue[i]); | 522 | kfree(priv->tx_queue[i]); |
@@ -522,7 +524,7 @@ static void free_tx_pointers(struct gfar_private *priv) | |||
522 | 524 | ||
523 | static void free_rx_pointers(struct gfar_private *priv) | 525 | static void free_rx_pointers(struct gfar_private *priv) |
524 | { | 526 | { |
525 | int i = 0; | 527 | int i; |
526 | 528 | ||
527 | for (i = 0; i < priv->num_rx_queues; i++) | 529 | for (i = 0; i < priv->num_rx_queues; i++) |
528 | kfree(priv->rx_queue[i]); | 530 | kfree(priv->rx_queue[i]); |
@@ -530,7 +532,7 @@ static void free_rx_pointers(struct gfar_private *priv) | |||
530 | 532 | ||
531 | static void unmap_group_regs(struct gfar_private *priv) | 533 | static void unmap_group_regs(struct gfar_private *priv) |
532 | { | 534 | { |
533 | int i = 0; | 535 | int i; |
534 | 536 | ||
535 | for (i = 0; i < MAXGROUPS; i++) | 537 | for (i = 0; i < MAXGROUPS; i++) |
536 | if (priv->gfargrp[i].regs) | 538 | if (priv->gfargrp[i].regs) |
@@ -539,7 +541,7 @@ static void unmap_group_regs(struct gfar_private *priv) | |||
539 | 541 | ||
540 | static void disable_napi(struct gfar_private *priv) | 542 | static void disable_napi(struct gfar_private *priv) |
541 | { | 543 | { |
542 | int i = 0; | 544 | int i; |
543 | 545 | ||
544 | for (i = 0; i < priv->num_grps; i++) | 546 | for (i = 0; i < priv->num_grps; i++) |
545 | napi_disable(&priv->gfargrp[i].napi); | 547 | napi_disable(&priv->gfargrp[i].napi); |
@@ -547,14 +549,14 @@ static void disable_napi(struct gfar_private *priv) | |||
547 | 549 | ||
548 | static void enable_napi(struct gfar_private *priv) | 550 | static void enable_napi(struct gfar_private *priv) |
549 | { | 551 | { |
550 | int i = 0; | 552 | int i; |
551 | 553 | ||
552 | for (i = 0; i < priv->num_grps; i++) | 554 | for (i = 0; i < priv->num_grps; i++) |
553 | napi_enable(&priv->gfargrp[i].napi); | 555 | napi_enable(&priv->gfargrp[i].napi); |
554 | } | 556 | } |
555 | 557 | ||
556 | static int gfar_parse_group(struct device_node *np, | 558 | static int gfar_parse_group(struct device_node *np, |
557 | struct gfar_private *priv, const char *model) | 559 | struct gfar_private *priv, const char *model) |
558 | { | 560 | { |
559 | u32 *queue_mask; | 561 | u32 *queue_mask; |
560 | 562 | ||
@@ -580,15 +582,13 @@ static int gfar_parse_group(struct device_node *np, | |||
580 | priv->gfargrp[priv->num_grps].grp_id = priv->num_grps; | 582 | priv->gfargrp[priv->num_grps].grp_id = priv->num_grps; |
581 | priv->gfargrp[priv->num_grps].priv = priv; | 583 | priv->gfargrp[priv->num_grps].priv = priv; |
582 | spin_lock_init(&priv->gfargrp[priv->num_grps].grplock); | 584 | spin_lock_init(&priv->gfargrp[priv->num_grps].grplock); |
583 | if(priv->mode == MQ_MG_MODE) { | 585 | if (priv->mode == MQ_MG_MODE) { |
584 | queue_mask = (u32 *)of_get_property(np, | 586 | queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL); |
585 | "fsl,rx-bit-map", NULL); | 587 | priv->gfargrp[priv->num_grps].rx_bit_map = queue_mask ? |
586 | priv->gfargrp[priv->num_grps].rx_bit_map = | 588 | *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); |
587 | queue_mask ? *queue_mask :(DEFAULT_MAPPING >> priv->num_grps); | 589 | queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL); |
588 | queue_mask = (u32 *)of_get_property(np, | 590 | priv->gfargrp[priv->num_grps].tx_bit_map = queue_mask ? |
589 | "fsl,tx-bit-map", NULL); | 591 | *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); |
590 | priv->gfargrp[priv->num_grps].tx_bit_map = | ||
591 | queue_mask ? *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); | ||
592 | } else { | 592 | } else { |
593 | priv->gfargrp[priv->num_grps].rx_bit_map = 0xFF; | 593 | priv->gfargrp[priv->num_grps].rx_bit_map = 0xFF; |
594 | priv->gfargrp[priv->num_grps].tx_bit_map = 0xFF; | 594 | priv->gfargrp[priv->num_grps].tx_bit_map = 0xFF; |
@@ -652,7 +652,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
652 | priv->num_rx_queues = num_rx_qs; | 652 | priv->num_rx_queues = num_rx_qs; |
653 | priv->num_grps = 0x0; | 653 | priv->num_grps = 0x0; |
654 | 654 | ||
655 | /* Init Rx queue filer rule set linked list*/ | 655 | /* Init Rx queue filer rule set linked list */ |
656 | INIT_LIST_HEAD(&priv->rx_list.list); | 656 | INIT_LIST_HEAD(&priv->rx_list.list); |
657 | priv->rx_list.count = 0; | 657 | priv->rx_list.count = 0; |
658 | mutex_init(&priv->rx_queue_access); | 658 | mutex_init(&priv->rx_queue_access); |
@@ -673,7 +673,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
673 | } else { | 673 | } else { |
674 | priv->mode = SQ_SG_MODE; | 674 | priv->mode = SQ_SG_MODE; |
675 | err = gfar_parse_group(np, priv, model); | 675 | err = gfar_parse_group(np, priv, model); |
676 | if(err) | 676 | if (err) |
677 | goto err_grp_init; | 677 | goto err_grp_init; |
678 | } | 678 | } |
679 | 679 | ||
@@ -730,27 +730,27 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
730 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; | 730 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; |
731 | 731 | ||
732 | mac_addr = of_get_mac_address(np); | 732 | mac_addr = of_get_mac_address(np); |
733 | |||
733 | if (mac_addr) | 734 | if (mac_addr) |
734 | memcpy(dev->dev_addr, mac_addr, ETH_ALEN); | 735 | memcpy(dev->dev_addr, mac_addr, ETH_ALEN); |
735 | 736 | ||
736 | if (model && !strcasecmp(model, "TSEC")) | 737 | if (model && !strcasecmp(model, "TSEC")) |
737 | priv->device_flags = | 738 | priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | |
738 | FSL_GIANFAR_DEV_HAS_GIGABIT | | 739 | FSL_GIANFAR_DEV_HAS_COALESCE | |
739 | FSL_GIANFAR_DEV_HAS_COALESCE | | 740 | FSL_GIANFAR_DEV_HAS_RMON | |
740 | FSL_GIANFAR_DEV_HAS_RMON | | 741 | FSL_GIANFAR_DEV_HAS_MULTI_INTR; |
741 | FSL_GIANFAR_DEV_HAS_MULTI_INTR; | 742 | |
742 | if (model && !strcasecmp(model, "eTSEC")) | 743 | if (model && !strcasecmp(model, "eTSEC")) |
743 | priv->device_flags = | 744 | priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | |
744 | FSL_GIANFAR_DEV_HAS_GIGABIT | | 745 | FSL_GIANFAR_DEV_HAS_COALESCE | |
745 | FSL_GIANFAR_DEV_HAS_COALESCE | | 746 | FSL_GIANFAR_DEV_HAS_RMON | |
746 | FSL_GIANFAR_DEV_HAS_RMON | | 747 | FSL_GIANFAR_DEV_HAS_MULTI_INTR | |
747 | FSL_GIANFAR_DEV_HAS_MULTI_INTR | | 748 | FSL_GIANFAR_DEV_HAS_PADDING | |
748 | FSL_GIANFAR_DEV_HAS_PADDING | | 749 | FSL_GIANFAR_DEV_HAS_CSUM | |
749 | FSL_GIANFAR_DEV_HAS_CSUM | | 750 | FSL_GIANFAR_DEV_HAS_VLAN | |
750 | FSL_GIANFAR_DEV_HAS_VLAN | | 751 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | |
751 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | | 752 | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | |
752 | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | | 753 | FSL_GIANFAR_DEV_HAS_TIMER; |
753 | FSL_GIANFAR_DEV_HAS_TIMER; | ||
754 | 754 | ||
755 | ctype = of_get_property(np, "phy-connection-type", NULL); | 755 | ctype = of_get_property(np, "phy-connection-type", NULL); |
756 | 756 | ||
@@ -781,7 +781,7 @@ err_grp_init: | |||
781 | } | 781 | } |
782 | 782 | ||
783 | static int gfar_hwtstamp_ioctl(struct net_device *netdev, | 783 | static int gfar_hwtstamp_ioctl(struct net_device *netdev, |
784 | struct ifreq *ifr, int cmd) | 784 | struct ifreq *ifr, int cmd) |
785 | { | 785 | { |
786 | struct hwtstamp_config config; | 786 | struct hwtstamp_config config; |
787 | struct gfar_private *priv = netdev_priv(netdev); | 787 | struct gfar_private *priv = netdev_priv(netdev); |
@@ -851,6 +851,7 @@ static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs) | |||
851 | { | 851 | { |
852 | unsigned int new_bit_map = 0x0; | 852 | unsigned int new_bit_map = 0x0; |
853 | int mask = 0x1 << (max_qs - 1), i; | 853 | int mask = 0x1 << (max_qs - 1), i; |
854 | |||
854 | for (i = 0; i < max_qs; i++) { | 855 | for (i = 0; i < max_qs; i++) { |
855 | if (bit_map & mask) | 856 | if (bit_map & mask) |
856 | new_bit_map = new_bit_map + (1 << i); | 857 | new_bit_map = new_bit_map + (1 << i); |
@@ -936,22 +937,22 @@ static void gfar_detect_errata(struct gfar_private *priv) | |||
936 | 937 | ||
937 | /* MPC8313 Rev 2.0 and higher; All MPC837x */ | 938 | /* MPC8313 Rev 2.0 and higher; All MPC837x */ |
938 | if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) || | 939 | if ((pvr == 0x80850010 && mod == 0x80b0 && rev >= 0x0020) || |
939 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) | 940 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) |
940 | priv->errata |= GFAR_ERRATA_74; | 941 | priv->errata |= GFAR_ERRATA_74; |
941 | 942 | ||
942 | /* MPC8313 and MPC837x all rev */ | 943 | /* MPC8313 and MPC837x all rev */ |
943 | if ((pvr == 0x80850010 && mod == 0x80b0) || | 944 | if ((pvr == 0x80850010 && mod == 0x80b0) || |
944 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) | 945 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) |
945 | priv->errata |= GFAR_ERRATA_76; | 946 | priv->errata |= GFAR_ERRATA_76; |
946 | 947 | ||
947 | /* MPC8313 and MPC837x all rev */ | 948 | /* MPC8313 and MPC837x all rev */ |
948 | if ((pvr == 0x80850010 && mod == 0x80b0) || | 949 | if ((pvr == 0x80850010 && mod == 0x80b0) || |
949 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) | 950 | (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) |
950 | priv->errata |= GFAR_ERRATA_A002; | 951 | priv->errata |= GFAR_ERRATA_A002; |
951 | 952 | ||
952 | /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */ | 953 | /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */ |
953 | if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) || | 954 | if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) || |
954 | (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)) | 955 | (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)) |
955 | priv->errata |= GFAR_ERRATA_12; | 956 | priv->errata |= GFAR_ERRATA_12; |
956 | 957 | ||
957 | if (priv->errata) | 958 | if (priv->errata) |
@@ -960,7 +961,8 @@ static void gfar_detect_errata(struct gfar_private *priv) | |||
960 | } | 961 | } |
961 | 962 | ||
962 | /* Set up the ethernet device structure, private data, | 963 | /* Set up the ethernet device structure, private data, |
963 | * and anything else we need before we start */ | 964 | * and anything else we need before we start |
965 | */ | ||
964 | static int gfar_probe(struct platform_device *ofdev) | 966 | static int gfar_probe(struct platform_device *ofdev) |
965 | { | 967 | { |
966 | u32 tempval; | 968 | u32 tempval; |
@@ -991,8 +993,9 @@ static int gfar_probe(struct platform_device *ofdev) | |||
991 | 993 | ||
992 | gfar_detect_errata(priv); | 994 | gfar_detect_errata(priv); |
993 | 995 | ||
994 | /* Stop the DMA engine now, in case it was running before */ | 996 | /* Stop the DMA engine now, in case it was running before |
995 | /* (The firmware could have used it, and left it running). */ | 997 | * (The firmware could have used it, and left it running). |
998 | */ | ||
996 | gfar_halt(dev); | 999 | gfar_halt(dev); |
997 | 1000 | ||
998 | /* Reset MAC layer */ | 1001 | /* Reset MAC layer */ |
@@ -1026,13 +1029,14 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1026 | 1029 | ||
1027 | /* Register for napi ...We are registering NAPI for each grp */ | 1030 | /* Register for napi ...We are registering NAPI for each grp */ |
1028 | for (i = 0; i < priv->num_grps; i++) | 1031 | for (i = 0; i < priv->num_grps; i++) |
1029 | netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT); | 1032 | netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, |
1033 | GFAR_DEV_WEIGHT); | ||
1030 | 1034 | ||
1031 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { | 1035 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { |
1032 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | | 1036 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
1033 | NETIF_F_RXCSUM; | 1037 | NETIF_F_RXCSUM; |
1034 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | | 1038 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | |
1035 | NETIF_F_RXCSUM | NETIF_F_HIGHDMA; | 1039 | NETIF_F_RXCSUM | NETIF_F_HIGHDMA; |
1036 | } | 1040 | } |
1037 | 1041 | ||
1038 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { | 1042 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { |
@@ -1081,7 +1085,7 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1081 | priv->padding = 0; | 1085 | priv->padding = 0; |
1082 | 1086 | ||
1083 | if (dev->features & NETIF_F_IP_CSUM || | 1087 | if (dev->features & NETIF_F_IP_CSUM || |
1084 | priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) | 1088 | priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) |
1085 | dev->needed_headroom = GMAC_FCB_LEN; | 1089 | dev->needed_headroom = GMAC_FCB_LEN; |
1086 | 1090 | ||
1087 | /* Program the isrg regs only if number of grps > 1 */ | 1091 | /* Program the isrg regs only if number of grps > 1 */ |
@@ -1098,28 +1102,32 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1098 | 1102 | ||
1099 | /* Need to reverse the bit maps as bit_map's MSB is q0 | 1103 | /* Need to reverse the bit maps as bit_map's MSB is q0 |
1100 | * but, for_each_set_bit parses from right to left, which | 1104 | * but, for_each_set_bit parses from right to left, which |
1101 | * basically reverses the queue numbers */ | 1105 | * basically reverses the queue numbers |
1106 | */ | ||
1102 | for (i = 0; i< priv->num_grps; i++) { | 1107 | for (i = 0; i< priv->num_grps; i++) { |
1103 | priv->gfargrp[i].tx_bit_map = reverse_bitmap( | 1108 | priv->gfargrp[i].tx_bit_map = |
1104 | priv->gfargrp[i].tx_bit_map, MAX_TX_QS); | 1109 | reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS); |
1105 | priv->gfargrp[i].rx_bit_map = reverse_bitmap( | 1110 | priv->gfargrp[i].rx_bit_map = |
1106 | priv->gfargrp[i].rx_bit_map, MAX_RX_QS); | 1111 | reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS); |
1107 | } | 1112 | } |
1108 | 1113 | ||
1109 | /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, | 1114 | /* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values, |
1110 | * also assign queues to groups */ | 1115 | * also assign queues to groups |
1116 | */ | ||
1111 | for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { | 1117 | for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) { |
1112 | priv->gfargrp[grp_idx].num_rx_queues = 0x0; | 1118 | priv->gfargrp[grp_idx].num_rx_queues = 0x0; |
1119 | |||
1113 | for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, | 1120 | for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map, |
1114 | priv->num_rx_queues) { | 1121 | priv->num_rx_queues) { |
1115 | priv->gfargrp[grp_idx].num_rx_queues++; | 1122 | priv->gfargrp[grp_idx].num_rx_queues++; |
1116 | priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx]; | 1123 | priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx]; |
1117 | rstat = rstat | (RSTAT_CLEAR_RHALT >> i); | 1124 | rstat = rstat | (RSTAT_CLEAR_RHALT >> i); |
1118 | rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i); | 1125 | rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i); |
1119 | } | 1126 | } |
1120 | priv->gfargrp[grp_idx].num_tx_queues = 0x0; | 1127 | priv->gfargrp[grp_idx].num_tx_queues = 0x0; |
1128 | |||
1121 | for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map, | 1129 | for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map, |
1122 | priv->num_tx_queues) { | 1130 | priv->num_tx_queues) { |
1123 | priv->gfargrp[grp_idx].num_tx_queues++; | 1131 | priv->gfargrp[grp_idx].num_tx_queues++; |
1124 | priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx]; | 1132 | priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx]; |
1125 | tstat = tstat | (TSTAT_CLEAR_THALT >> i); | 1133 | tstat = tstat | (TSTAT_CLEAR_THALT >> i); |
@@ -1149,7 +1157,7 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1149 | priv->rx_queue[i]->rxic = DEFAULT_RXIC; | 1157 | priv->rx_queue[i]->rxic = DEFAULT_RXIC; |
1150 | } | 1158 | } |
1151 | 1159 | ||
1152 | /* always enable rx filer*/ | 1160 | /* always enable rx filer */ |
1153 | priv->rx_filer_enable = 1; | 1161 | priv->rx_filer_enable = 1; |
1154 | /* Enable most messages by default */ | 1162 | /* Enable most messages by default */ |
1155 | priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; | 1163 | priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; |
@@ -1165,7 +1173,8 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1165 | } | 1173 | } |
1166 | 1174 | ||
1167 | device_init_wakeup(&dev->dev, | 1175 | device_init_wakeup(&dev->dev, |
1168 | priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | 1176 | priv->device_flags & |
1177 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | ||
1169 | 1178 | ||
1170 | /* fill out IRQ number and name fields */ | 1179 | /* fill out IRQ number and name fields */ |
1171 | for (i = 0; i < priv->num_grps; i++) { | 1180 | for (i = 0; i < priv->num_grps; i++) { |
@@ -1189,13 +1198,14 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1189 | /* Print out the device info */ | 1198 | /* Print out the device info */ |
1190 | netdev_info(dev, "mac: %pM\n", dev->dev_addr); | 1199 | netdev_info(dev, "mac: %pM\n", dev->dev_addr); |
1191 | 1200 | ||
1192 | /* Even more device info helps when determining which kernel */ | 1201 | /* Even more device info helps when determining which kernel |
1193 | /* provided which set of benchmarks. */ | 1202 | * provided which set of benchmarks. |
1203 | */ | ||
1194 | netdev_info(dev, "Running with NAPI enabled\n"); | 1204 | netdev_info(dev, "Running with NAPI enabled\n"); |
1195 | for (i = 0; i < priv->num_rx_queues; i++) | 1205 | for (i = 0; i < priv->num_rx_queues; i++) |
1196 | netdev_info(dev, "RX BD ring size for Q[%d]: %d\n", | 1206 | netdev_info(dev, "RX BD ring size for Q[%d]: %d\n", |
1197 | i, priv->rx_queue[i]->rx_ring_size); | 1207 | i, priv->rx_queue[i]->rx_ring_size); |
1198 | for(i = 0; i < priv->num_tx_queues; i++) | 1208 | for (i = 0; i < priv->num_tx_queues; i++) |
1199 | netdev_info(dev, "TX BD ring size for Q[%d]: %d\n", | 1209 | netdev_info(dev, "TX BD ring size for Q[%d]: %d\n", |
1200 | i, priv->tx_queue[i]->tx_ring_size); | 1210 | i, priv->tx_queue[i]->tx_ring_size); |
1201 | 1211 | ||
@@ -1242,7 +1252,8 @@ static int gfar_suspend(struct device *dev) | |||
1242 | u32 tempval; | 1252 | u32 tempval; |
1243 | 1253 | ||
1244 | int magic_packet = priv->wol_en && | 1254 | int magic_packet = priv->wol_en && |
1245 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | 1255 | (priv->device_flags & |
1256 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | ||
1246 | 1257 | ||
1247 | netif_device_detach(ndev); | 1258 | netif_device_detach(ndev); |
1248 | 1259 | ||
@@ -1294,7 +1305,8 @@ static int gfar_resume(struct device *dev) | |||
1294 | unsigned long flags; | 1305 | unsigned long flags; |
1295 | u32 tempval; | 1306 | u32 tempval; |
1296 | int magic_packet = priv->wol_en && | 1307 | int magic_packet = priv->wol_en && |
1297 | (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | 1308 | (priv->device_flags & |
1309 | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | ||
1298 | 1310 | ||
1299 | if (!netif_running(ndev)) { | 1311 | if (!netif_running(ndev)) { |
1300 | netif_device_attach(ndev); | 1312 | netif_device_attach(ndev); |
@@ -1393,13 +1405,13 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) | |||
1393 | } | 1405 | } |
1394 | 1406 | ||
1395 | if (ecntrl & ECNTRL_REDUCED_MODE) { | 1407 | if (ecntrl & ECNTRL_REDUCED_MODE) { |
1396 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) | 1408 | if (ecntrl & ECNTRL_REDUCED_MII_MODE) { |
1397 | return PHY_INTERFACE_MODE_RMII; | 1409 | return PHY_INTERFACE_MODE_RMII; |
1410 | } | ||
1398 | else { | 1411 | else { |
1399 | phy_interface_t interface = priv->interface; | 1412 | phy_interface_t interface = priv->interface; |
1400 | 1413 | ||
1401 | /* | 1414 | /* This isn't autodetected right now, so it must |
1402 | * This isn't autodetected right now, so it must | ||
1403 | * be set by the device tree or platform code. | 1415 | * be set by the device tree or platform code. |
1404 | */ | 1416 | */ |
1405 | if (interface == PHY_INTERFACE_MODE_RGMII_ID) | 1417 | if (interface == PHY_INTERFACE_MODE_RGMII_ID) |
@@ -1453,8 +1465,7 @@ static int init_phy(struct net_device *dev) | |||
1453 | return 0; | 1465 | return 0; |
1454 | } | 1466 | } |
1455 | 1467 | ||
1456 | /* | 1468 | /* Initialize TBI PHY interface for communicating with the |
1457 | * Initialize TBI PHY interface for communicating with the | ||
1458 | * SERDES lynx PHY on the chip. We communicate with this PHY | 1469 | * SERDES lynx PHY on the chip. We communicate with this PHY |
1459 | * through the MDIO bus on each controller, treating it as a | 1470 | * through the MDIO bus on each controller, treating it as a |
1460 | * "normal" PHY at the address found in the TBIPA register. We assume | 1471 | * "normal" PHY at the address found in the TBIPA register. We assume |
@@ -1479,8 +1490,7 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
1479 | return; | 1490 | return; |
1480 | } | 1491 | } |
1481 | 1492 | ||
1482 | /* | 1493 | /* If the link is already up, we must already be ok, and don't need to |
1483 | * If the link is already up, we must already be ok, and don't need to | ||
1484 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | 1494 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured |
1485 | * everything for us? Resetting it takes the link down and requires | 1495 | * everything for us? Resetting it takes the link down and requires |
1486 | * several seconds for it to come back. | 1496 | * several seconds for it to come back. |
@@ -1492,18 +1502,19 @@ static void gfar_configure_serdes(struct net_device *dev) | |||
1492 | phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT); | 1502 | phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT); |
1493 | 1503 | ||
1494 | phy_write(tbiphy, MII_ADVERTISE, | 1504 | phy_write(tbiphy, MII_ADVERTISE, |
1495 | ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | | 1505 | ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | |
1496 | ADVERTISE_1000XPSE_ASYM); | 1506 | ADVERTISE_1000XPSE_ASYM); |
1497 | 1507 | ||
1498 | phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE | | 1508 | phy_write(tbiphy, MII_BMCR, |
1499 | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); | 1509 | BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | |
1510 | BMCR_SPEED1000); | ||
1500 | } | 1511 | } |
1501 | 1512 | ||
1502 | static void init_registers(struct net_device *dev) | 1513 | static void init_registers(struct net_device *dev) |
1503 | { | 1514 | { |
1504 | struct gfar_private *priv = netdev_priv(dev); | 1515 | struct gfar_private *priv = netdev_priv(dev); |
1505 | struct gfar __iomem *regs = NULL; | 1516 | struct gfar __iomem *regs = NULL; |
1506 | int i = 0; | 1517 | int i; |
1507 | 1518 | ||
1508 | for (i = 0; i < priv->num_grps; i++) { | 1519 | for (i = 0; i < priv->num_grps; i++) { |
1509 | regs = priv->gfargrp[i].regs; | 1520 | regs = priv->gfargrp[i].regs; |
@@ -1554,15 +1565,13 @@ static int __gfar_is_rx_idle(struct gfar_private *priv) | |||
1554 | { | 1565 | { |
1555 | u32 res; | 1566 | u32 res; |
1556 | 1567 | ||
1557 | /* | 1568 | /* Normaly TSEC should not hang on GRS commands, so we should |
1558 | * Normaly TSEC should not hang on GRS commands, so we should | ||
1559 | * actually wait for IEVENT_GRSC flag. | 1569 | * actually wait for IEVENT_GRSC flag. |
1560 | */ | 1570 | */ |
1561 | if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002))) | 1571 | if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002))) |
1562 | return 0; | 1572 | return 0; |
1563 | 1573 | ||
1564 | /* | 1574 | /* Read the eTSEC register at offset 0xD1C. If bits 7-14 are |
1565 | * Read the eTSEC register at offset 0xD1C. If bits 7-14 are | ||
1566 | * the same as bits 23-30, the eTSEC Rx is assumed to be idle | 1575 | * the same as bits 23-30, the eTSEC Rx is assumed to be idle |
1567 | * and the Rx can be safely reset. | 1576 | * and the Rx can be safely reset. |
1568 | */ | 1577 | */ |
@@ -1580,7 +1589,7 @@ static void gfar_halt_nodisable(struct net_device *dev) | |||
1580 | struct gfar_private *priv = netdev_priv(dev); | 1589 | struct gfar_private *priv = netdev_priv(dev); |
1581 | struct gfar __iomem *regs = NULL; | 1590 | struct gfar __iomem *regs = NULL; |
1582 | u32 tempval; | 1591 | u32 tempval; |
1583 | int i = 0; | 1592 | int i; |
1584 | 1593 | ||
1585 | for (i = 0; i < priv->num_grps; i++) { | 1594 | for (i = 0; i < priv->num_grps; i++) { |
1586 | regs = priv->gfargrp[i].regs; | 1595 | regs = priv->gfargrp[i].regs; |
@@ -1594,8 +1603,8 @@ static void gfar_halt_nodisable(struct net_device *dev) | |||
1594 | regs = priv->gfargrp[0].regs; | 1603 | regs = priv->gfargrp[0].regs; |
1595 | /* Stop the DMA, and wait for it to stop */ | 1604 | /* Stop the DMA, and wait for it to stop */ |
1596 | tempval = gfar_read(®s->dmactrl); | 1605 | tempval = gfar_read(®s->dmactrl); |
1597 | if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) | 1606 | if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) != |
1598 | != (DMACTRL_GRS | DMACTRL_GTS)) { | 1607 | (DMACTRL_GRS | DMACTRL_GTS)) { |
1599 | int ret; | 1608 | int ret; |
1600 | 1609 | ||
1601 | tempval |= (DMACTRL_GRS | DMACTRL_GTS); | 1610 | tempval |= (DMACTRL_GRS | DMACTRL_GTS); |
@@ -1660,7 +1669,7 @@ void stop_gfar(struct net_device *dev) | |||
1660 | } else { | 1669 | } else { |
1661 | for (i = 0; i < priv->num_grps; i++) | 1670 | for (i = 0; i < priv->num_grps; i++) |
1662 | free_irq(priv->gfargrp[i].interruptTransmit, | 1671 | free_irq(priv->gfargrp[i].interruptTransmit, |
1663 | &priv->gfargrp[i]); | 1672 | &priv->gfargrp[i]); |
1664 | } | 1673 | } |
1665 | 1674 | ||
1666 | free_skb_resources(priv); | 1675 | free_skb_resources(priv); |
@@ -1679,13 +1688,13 @@ static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue) | |||
1679 | continue; | 1688 | continue; |
1680 | 1689 | ||
1681 | dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr, | 1690 | dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr, |
1682 | txbdp->length, DMA_TO_DEVICE); | 1691 | txbdp->length, DMA_TO_DEVICE); |
1683 | txbdp->lstatus = 0; | 1692 | txbdp->lstatus = 0; |
1684 | for (j = 0; j < skb_shinfo(tx_queue->tx_skbuff[i])->nr_frags; | 1693 | for (j = 0; j < skb_shinfo(tx_queue->tx_skbuff[i])->nr_frags; |
1685 | j++) { | 1694 | j++) { |
1686 | txbdp++; | 1695 | txbdp++; |
1687 | dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr, | 1696 | dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr, |
1688 | txbdp->length, DMA_TO_DEVICE); | 1697 | txbdp->length, DMA_TO_DEVICE); |
1689 | } | 1698 | } |
1690 | txbdp++; | 1699 | txbdp++; |
1691 | dev_kfree_skb_any(tx_queue->tx_skbuff[i]); | 1700 | dev_kfree_skb_any(tx_queue->tx_skbuff[i]); |
@@ -1705,8 +1714,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) | |||
1705 | for (i = 0; i < rx_queue->rx_ring_size; i++) { | 1714 | for (i = 0; i < rx_queue->rx_ring_size; i++) { |
1706 | if (rx_queue->rx_skbuff[i]) { | 1715 | if (rx_queue->rx_skbuff[i]) { |
1707 | dma_unmap_single(&priv->ofdev->dev, | 1716 | dma_unmap_single(&priv->ofdev->dev, |
1708 | rxbdp->bufPtr, priv->rx_buffer_size, | 1717 | rxbdp->bufPtr, priv->rx_buffer_size, |
1709 | DMA_FROM_DEVICE); | 1718 | DMA_FROM_DEVICE); |
1710 | dev_kfree_skb_any(rx_queue->rx_skbuff[i]); | 1719 | dev_kfree_skb_any(rx_queue->rx_skbuff[i]); |
1711 | rx_queue->rx_skbuff[i] = NULL; | 1720 | rx_queue->rx_skbuff[i] = NULL; |
1712 | } | 1721 | } |
@@ -1718,7 +1727,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue) | |||
1718 | } | 1727 | } |
1719 | 1728 | ||
1720 | /* If there are any tx skbs or rx skbs still around, free them. | 1729 | /* If there are any tx skbs or rx skbs still around, free them. |
1721 | * Then free tx_skbuff and rx_skbuff */ | 1730 | * Then free tx_skbuff and rx_skbuff |
1731 | */ | ||
1722 | static void free_skb_resources(struct gfar_private *priv) | 1732 | static void free_skb_resources(struct gfar_private *priv) |
1723 | { | 1733 | { |
1724 | struct gfar_priv_tx_q *tx_queue = NULL; | 1734 | struct gfar_priv_tx_q *tx_queue = NULL; |
@@ -1728,24 +1738,25 @@ static void free_skb_resources(struct gfar_private *priv) | |||
1728 | /* Go through all the buffer descriptors and free their data buffers */ | 1738 | /* Go through all the buffer descriptors and free their data buffers */ |
1729 | for (i = 0; i < priv->num_tx_queues; i++) { | 1739 | for (i = 0; i < priv->num_tx_queues; i++) { |
1730 | struct netdev_queue *txq; | 1740 | struct netdev_queue *txq; |
1741 | |||
1731 | tx_queue = priv->tx_queue[i]; | 1742 | tx_queue = priv->tx_queue[i]; |
1732 | txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); | 1743 | txq = netdev_get_tx_queue(tx_queue->dev, tx_queue->qindex); |
1733 | if(tx_queue->tx_skbuff) | 1744 | if (tx_queue->tx_skbuff) |
1734 | free_skb_tx_queue(tx_queue); | 1745 | free_skb_tx_queue(tx_queue); |
1735 | netdev_tx_reset_queue(txq); | 1746 | netdev_tx_reset_queue(txq); |
1736 | } | 1747 | } |
1737 | 1748 | ||
1738 | for (i = 0; i < priv->num_rx_queues; i++) { | 1749 | for (i = 0; i < priv->num_rx_queues; i++) { |
1739 | rx_queue = priv->rx_queue[i]; | 1750 | rx_queue = priv->rx_queue[i]; |
1740 | if(rx_queue->rx_skbuff) | 1751 | if (rx_queue->rx_skbuff) |
1741 | free_skb_rx_queue(rx_queue); | 1752 | free_skb_rx_queue(rx_queue); |
1742 | } | 1753 | } |
1743 | 1754 | ||
1744 | dma_free_coherent(&priv->ofdev->dev, | 1755 | dma_free_coherent(&priv->ofdev->dev, |
1745 | sizeof(struct txbd8) * priv->total_tx_ring_size + | 1756 | sizeof(struct txbd8) * priv->total_tx_ring_size + |
1746 | sizeof(struct rxbd8) * priv->total_rx_ring_size, | 1757 | sizeof(struct rxbd8) * priv->total_rx_ring_size, |
1747 | priv->tx_queue[0]->tx_bd_base, | 1758 | priv->tx_queue[0]->tx_bd_base, |
1748 | priv->tx_queue[0]->tx_bd_dma_base); | 1759 | priv->tx_queue[0]->tx_bd_dma_base); |
1749 | skb_queue_purge(&priv->rx_recycle); | 1760 | skb_queue_purge(&priv->rx_recycle); |
1750 | } | 1761 | } |
1751 | 1762 | ||
@@ -1784,7 +1795,7 @@ void gfar_start(struct net_device *dev) | |||
1784 | } | 1795 | } |
1785 | 1796 | ||
1786 | void gfar_configure_coalescing(struct gfar_private *priv, | 1797 | void gfar_configure_coalescing(struct gfar_private *priv, |
1787 | unsigned long tx_mask, unsigned long rx_mask) | 1798 | unsigned long tx_mask, unsigned long rx_mask) |
1788 | { | 1799 | { |
1789 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | 1800 | struct gfar __iomem *regs = priv->gfargrp[0].regs; |
1790 | u32 __iomem *baddr; | 1801 | u32 __iomem *baddr; |
@@ -1794,11 +1805,11 @@ void gfar_configure_coalescing(struct gfar_private *priv, | |||
1794 | * multiple queues, there's only single reg to program | 1805 | * multiple queues, there's only single reg to program |
1795 | */ | 1806 | */ |
1796 | gfar_write(®s->txic, 0); | 1807 | gfar_write(®s->txic, 0); |
1797 | if(likely(priv->tx_queue[0]->txcoalescing)) | 1808 | if (likely(priv->tx_queue[0]->txcoalescing)) |
1798 | gfar_write(®s->txic, priv->tx_queue[0]->txic); | 1809 | gfar_write(®s->txic, priv->tx_queue[0]->txic); |
1799 | 1810 | ||
1800 | gfar_write(®s->rxic, 0); | 1811 | gfar_write(®s->rxic, 0); |
1801 | if(unlikely(priv->rx_queue[0]->rxcoalescing)) | 1812 | if (unlikely(priv->rx_queue[0]->rxcoalescing)) |
1802 | gfar_write(®s->rxic, priv->rx_queue[0]->rxic); | 1813 | gfar_write(®s->rxic, priv->rx_queue[0]->rxic); |
1803 | 1814 | ||
1804 | if (priv->mode == MQ_MG_MODE) { | 1815 | if (priv->mode == MQ_MG_MODE) { |
@@ -1827,12 +1838,14 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) | |||
1827 | int err; | 1838 | int err; |
1828 | 1839 | ||
1829 | /* If the device has multiple interrupts, register for | 1840 | /* If the device has multiple interrupts, register for |
1830 | * them. Otherwise, only register for the one */ | 1841 | * them. Otherwise, only register for the one |
1842 | */ | ||
1831 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 1843 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
1832 | /* Install our interrupt handlers for Error, | 1844 | /* Install our interrupt handlers for Error, |
1833 | * Transmit, and Receive */ | 1845 | * Transmit, and Receive |
1834 | if ((err = request_irq(grp->interruptError, gfar_error, 0, | 1846 | */ |
1835 | grp->int_name_er,grp)) < 0) { | 1847 | if ((err = request_irq(grp->interruptError, gfar_error, |
1848 | 0, grp->int_name_er, grp)) < 0) { | ||
1836 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", | 1849 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", |
1837 | grp->interruptError); | 1850 | grp->interruptError); |
1838 | 1851 | ||
@@ -1840,21 +1853,21 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) | |||
1840 | } | 1853 | } |
1841 | 1854 | ||
1842 | if ((err = request_irq(grp->interruptTransmit, gfar_transmit, | 1855 | if ((err = request_irq(grp->interruptTransmit, gfar_transmit, |
1843 | 0, grp->int_name_tx, grp)) < 0) { | 1856 | 0, grp->int_name_tx, grp)) < 0) { |
1844 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", | 1857 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", |
1845 | grp->interruptTransmit); | 1858 | grp->interruptTransmit); |
1846 | goto tx_irq_fail; | 1859 | goto tx_irq_fail; |
1847 | } | 1860 | } |
1848 | 1861 | ||
1849 | if ((err = request_irq(grp->interruptReceive, gfar_receive, 0, | 1862 | if ((err = request_irq(grp->interruptReceive, gfar_receive, |
1850 | grp->int_name_rx, grp)) < 0) { | 1863 | 0, grp->int_name_rx, grp)) < 0) { |
1851 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", | 1864 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", |
1852 | grp->interruptReceive); | 1865 | grp->interruptReceive); |
1853 | goto rx_irq_fail; | 1866 | goto rx_irq_fail; |
1854 | } | 1867 | } |
1855 | } else { | 1868 | } else { |
1856 | if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, 0, | 1869 | if ((err = request_irq(grp->interruptTransmit, gfar_interrupt, |
1857 | grp->int_name_tx, grp)) < 0) { | 1870 | 0, grp->int_name_tx, grp)) < 0) { |
1858 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", | 1871 | netif_err(priv, intr, dev, "Can't get IRQ %d\n", |
1859 | grp->interruptTransmit); | 1872 | grp->interruptTransmit); |
1860 | goto err_irq_fail; | 1873 | goto err_irq_fail; |
@@ -1914,8 +1927,9 @@ irq_fail: | |||
1914 | return err; | 1927 | return err; |
1915 | } | 1928 | } |
1916 | 1929 | ||
1917 | /* Called when something needs to use the ethernet device */ | 1930 | /* Called when something needs to use the ethernet device |
1918 | /* Returns 0 for success. */ | 1931 | * Returns 0 for success. |
1932 | */ | ||
1919 | static int gfar_enet_open(struct net_device *dev) | 1933 | static int gfar_enet_open(struct net_device *dev) |
1920 | { | 1934 | { |
1921 | struct gfar_private *priv = netdev_priv(dev); | 1935 | struct gfar_private *priv = netdev_priv(dev); |
@@ -1960,18 +1974,17 @@ static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) | |||
1960 | } | 1974 | } |
1961 | 1975 | ||
1962 | static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, | 1976 | static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, |
1963 | int fcb_length) | 1977 | int fcb_length) |
1964 | { | 1978 | { |
1965 | u8 flags = 0; | ||
1966 | |||
1967 | /* If we're here, it's a IP packet with a TCP or UDP | 1979 | /* If we're here, it's a IP packet with a TCP or UDP |
1968 | * payload. We set it to checksum, using a pseudo-header | 1980 | * payload. We set it to checksum, using a pseudo-header |
1969 | * we provide | 1981 | * we provide |
1970 | */ | 1982 | */ |
1971 | flags = TXFCB_DEFAULT; | 1983 | u8 flags = TXFCB_DEFAULT; |
1972 | 1984 | ||
1973 | /* Tell the controller what the protocol is */ | 1985 | /* Tell the controller what the protocol is |
1974 | /* And provide the already calculated phcs */ | 1986 | * And provide the already calculated phcs |
1987 | */ | ||
1975 | if (ip_hdr(skb)->protocol == IPPROTO_UDP) { | 1988 | if (ip_hdr(skb)->protocol == IPPROTO_UDP) { |
1976 | flags |= TXFCB_UDP; | 1989 | flags |= TXFCB_UDP; |
1977 | fcb->phcs = udp_hdr(skb)->check; | 1990 | fcb->phcs = udp_hdr(skb)->check; |
@@ -1981,7 +1994,8 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, | |||
1981 | /* l3os is the distance between the start of the | 1994 | /* l3os is the distance between the start of the |
1982 | * frame (skb->data) and the start of the IP hdr. | 1995 | * frame (skb->data) and the start of the IP hdr. |
1983 | * l4os is the distance between the start of the | 1996 | * l4os is the distance between the start of the |
1984 | * l3 hdr and the l4 hdr */ | 1997 | * l3 hdr and the l4 hdr |
1998 | */ | ||
1985 | fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length); | 1999 | fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length); |
1986 | fcb->l4os = skb_network_header_len(skb); | 2000 | fcb->l4os = skb_network_header_len(skb); |
1987 | 2001 | ||
@@ -1995,7 +2009,7 @@ void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb) | |||
1995 | } | 2009 | } |
1996 | 2010 | ||
1997 | static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, | 2011 | static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, |
1998 | struct txbd8 *base, int ring_size) | 2012 | struct txbd8 *base, int ring_size) |
1999 | { | 2013 | { |
2000 | struct txbd8 *new_bd = bdp + stride; | 2014 | struct txbd8 *new_bd = bdp + stride; |
2001 | 2015 | ||
@@ -2003,13 +2017,14 @@ static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, | |||
2003 | } | 2017 | } |
2004 | 2018 | ||
2005 | static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, | 2019 | static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, |
2006 | int ring_size) | 2020 | int ring_size) |
2007 | { | 2021 | { |
2008 | return skip_txbd(bdp, 1, base, ring_size); | 2022 | return skip_txbd(bdp, 1, base, ring_size); |
2009 | } | 2023 | } |
2010 | 2024 | ||
2011 | /* This is called by the kernel when a frame is ready for transmission. */ | 2025 | /* This is called by the kernel when a frame is ready for transmission. |
2012 | /* It is pointed to by the dev->hard_start_xmit function pointer */ | 2026 | * It is pointed to by the dev->hard_start_xmit function pointer |
2027 | */ | ||
2013 | static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | 2028 | static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) |
2014 | { | 2029 | { |
2015 | struct gfar_private *priv = netdev_priv(dev); | 2030 | struct gfar_private *priv = netdev_priv(dev); |
@@ -2024,13 +2039,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2024 | unsigned long flags; | 2039 | unsigned long flags; |
2025 | unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; | 2040 | unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; |
2026 | 2041 | ||
2027 | /* | 2042 | /* TOE=1 frames larger than 2500 bytes may see excess delays |
2028 | * TOE=1 frames larger than 2500 bytes may see excess delays | ||
2029 | * before start of transmission. | 2043 | * before start of transmission. |
2030 | */ | 2044 | */ |
2031 | if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) && | 2045 | if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) && |
2032 | skb->ip_summed == CHECKSUM_PARTIAL && | 2046 | skb->ip_summed == CHECKSUM_PARTIAL && |
2033 | skb->len > 2500)) { | 2047 | skb->len > 2500)) { |
2034 | int ret; | 2048 | int ret; |
2035 | 2049 | ||
2036 | ret = skb_checksum_help(skb); | 2050 | ret = skb_checksum_help(skb); |
@@ -2046,16 +2060,16 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2046 | 2060 | ||
2047 | /* check if time stamp should be generated */ | 2061 | /* check if time stamp should be generated */ |
2048 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && | 2062 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && |
2049 | priv->hwts_tx_en)) { | 2063 | priv->hwts_tx_en)) { |
2050 | do_tstamp = 1; | 2064 | do_tstamp = 1; |
2051 | fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN; | 2065 | fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN; |
2052 | } | 2066 | } |
2053 | 2067 | ||
2054 | /* make space for additional header when fcb is needed */ | 2068 | /* make space for additional header when fcb is needed */ |
2055 | if (((skb->ip_summed == CHECKSUM_PARTIAL) || | 2069 | if (((skb->ip_summed == CHECKSUM_PARTIAL) || |
2056 | vlan_tx_tag_present(skb) || | 2070 | vlan_tx_tag_present(skb) || |
2057 | unlikely(do_tstamp)) && | 2071 | unlikely(do_tstamp)) && |
2058 | (skb_headroom(skb) < fcb_length)) { | 2072 | (skb_headroom(skb) < fcb_length)) { |
2059 | struct sk_buff *skb_new; | 2073 | struct sk_buff *skb_new; |
2060 | 2074 | ||
2061 | skb_new = skb_realloc_headroom(skb, fcb_length); | 2075 | skb_new = skb_realloc_headroom(skb, fcb_length); |
@@ -2099,12 +2113,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2099 | /* Time stamp insertion requires one additional TxBD */ | 2113 | /* Time stamp insertion requires one additional TxBD */ |
2100 | if (unlikely(do_tstamp)) | 2114 | if (unlikely(do_tstamp)) |
2101 | txbdp_tstamp = txbdp = next_txbd(txbdp, base, | 2115 | txbdp_tstamp = txbdp = next_txbd(txbdp, base, |
2102 | tx_queue->tx_ring_size); | 2116 | tx_queue->tx_ring_size); |
2103 | 2117 | ||
2104 | if (nr_frags == 0) { | 2118 | if (nr_frags == 0) { |
2105 | if (unlikely(do_tstamp)) | 2119 | if (unlikely(do_tstamp)) |
2106 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_LAST | | 2120 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_LAST | |
2107 | TXBD_INTERRUPT); | 2121 | TXBD_INTERRUPT); |
2108 | else | 2122 | else |
2109 | lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); | 2123 | lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); |
2110 | } else { | 2124 | } else { |
@@ -2116,7 +2130,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2116 | length = skb_shinfo(skb)->frags[i].size; | 2130 | length = skb_shinfo(skb)->frags[i].size; |
2117 | 2131 | ||
2118 | lstatus = txbdp->lstatus | length | | 2132 | lstatus = txbdp->lstatus | length | |
2119 | BD_LFLAG(TXBD_READY); | 2133 | BD_LFLAG(TXBD_READY); |
2120 | 2134 | ||
2121 | /* Handle the last BD specially */ | 2135 | /* Handle the last BD specially */ |
2122 | if (i == nr_frags - 1) | 2136 | if (i == nr_frags - 1) |
@@ -2146,8 +2160,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2146 | if (CHECKSUM_PARTIAL == skb->ip_summed) { | 2160 | if (CHECKSUM_PARTIAL == skb->ip_summed) { |
2147 | fcb = gfar_add_fcb(skb); | 2161 | fcb = gfar_add_fcb(skb); |
2148 | /* as specified by errata */ | 2162 | /* as specified by errata */ |
2149 | if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) | 2163 | if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) && |
2150 | && ((unsigned long)fcb % 0x20) > 0x18)) { | 2164 | ((unsigned long)fcb % 0x20) > 0x18)) { |
2151 | __skb_pull(skb, GMAC_FCB_LEN); | 2165 | __skb_pull(skb, GMAC_FCB_LEN); |
2152 | skb_checksum_help(skb); | 2166 | skb_checksum_help(skb); |
2153 | } else { | 2167 | } else { |
@@ -2175,10 +2189,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2175 | } | 2189 | } |
2176 | 2190 | ||
2177 | txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, | 2191 | txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, |
2178 | skb_headlen(skb), DMA_TO_DEVICE); | 2192 | skb_headlen(skb), DMA_TO_DEVICE); |
2179 | 2193 | ||
2180 | /* | 2194 | /* If time stamping is requested one additional TxBD must be set up. The |
2181 | * If time stamping is requested one additional TxBD must be set up. The | ||
2182 | * first TxBD points to the FCB and must have a data length of | 2195 | * first TxBD points to the FCB and must have a data length of |
2183 | * GMAC_FCB_LEN. The second TxBD points to the actual frame data with | 2196 | * GMAC_FCB_LEN. The second TxBD points to the actual frame data with |
2184 | * the full frame length. | 2197 | * the full frame length. |
@@ -2186,7 +2199,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2186 | if (unlikely(do_tstamp)) { | 2199 | if (unlikely(do_tstamp)) { |
2187 | txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length; | 2200 | txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length; |
2188 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | | 2201 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | |
2189 | (skb_headlen(skb) - fcb_length); | 2202 | (skb_headlen(skb) - fcb_length); |
2190 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; | 2203 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; |
2191 | } else { | 2204 | } else { |
2192 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); | 2205 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); |
@@ -2194,8 +2207,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2194 | 2207 | ||
2195 | netdev_tx_sent_queue(txq, skb->len); | 2208 | netdev_tx_sent_queue(txq, skb->len); |
2196 | 2209 | ||
2197 | /* | 2210 | /* We can work in parallel with gfar_clean_tx_ring(), except |
2198 | * We can work in parallel with gfar_clean_tx_ring(), except | ||
2199 | * when modifying num_txbdfree. Note that we didn't grab the lock | 2211 | * when modifying num_txbdfree. Note that we didn't grab the lock |
2200 | * when we were reading the num_txbdfree and checking for available | 2212 | * when we were reading the num_txbdfree and checking for available |
2201 | * space, that's because outside of this function it can only grow, | 2213 | * space, that's because outside of this function it can only grow, |
@@ -2208,8 +2220,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2208 | */ | 2220 | */ |
2209 | spin_lock_irqsave(&tx_queue->txlock, flags); | 2221 | spin_lock_irqsave(&tx_queue->txlock, flags); |
2210 | 2222 | ||
2211 | /* | 2223 | /* The powerpc-specific eieio() is used, as wmb() has too strong |
2212 | * The powerpc-specific eieio() is used, as wmb() has too strong | ||
2213 | * semantics (it requires synchronization between cacheable and | 2224 | * semantics (it requires synchronization between cacheable and |
2214 | * uncacheable mappings, which eieio doesn't provide and which we | 2225 | * uncacheable mappings, which eieio doesn't provide and which we |
2215 | * don't need), thus requiring a more expensive sync instruction. At | 2226 | * don't need), thus requiring a more expensive sync instruction. At |
@@ -2225,9 +2236,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2225 | tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; | 2236 | tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; |
2226 | 2237 | ||
2227 | /* Update the current skb pointer to the next entry we will use | 2238 | /* Update the current skb pointer to the next entry we will use |
2228 | * (wrapping if necessary) */ | 2239 | * (wrapping if necessary) |
2240 | */ | ||
2229 | tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & | 2241 | tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & |
2230 | TX_RING_MOD_MASK(tx_queue->tx_ring_size); | 2242 | TX_RING_MOD_MASK(tx_queue->tx_ring_size); |
2231 | 2243 | ||
2232 | tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size); | 2244 | tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size); |
2233 | 2245 | ||
@@ -2235,7 +2247,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2235 | tx_queue->num_txbdfree -= (nr_txbds); | 2247 | tx_queue->num_txbdfree -= (nr_txbds); |
2236 | 2248 | ||
2237 | /* If the next BD still needs to be cleaned up, then the bds | 2249 | /* If the next BD still needs to be cleaned up, then the bds |
2238 | are full. We need to tell the kernel to stop sending us stuff. */ | 2250 | * are full. We need to tell the kernel to stop sending us stuff. |
2251 | */ | ||
2239 | if (!tx_queue->num_txbdfree) { | 2252 | if (!tx_queue->num_txbdfree) { |
2240 | netif_tx_stop_queue(txq); | 2253 | netif_tx_stop_queue(txq); |
2241 | 2254 | ||
@@ -2360,12 +2373,12 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
2360 | 2373 | ||
2361 | frame_size += priv->padding; | 2374 | frame_size += priv->padding; |
2362 | 2375 | ||
2363 | tempsize = | 2376 | tempsize = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + |
2364 | (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + | 2377 | INCREMENTAL_BUFFER_SIZE; |
2365 | INCREMENTAL_BUFFER_SIZE; | ||
2366 | 2378 | ||
2367 | /* Only stop and start the controller if it isn't already | 2379 | /* Only stop and start the controller if it isn't already |
2368 | * stopped, and we changed something */ | 2380 | * stopped, and we changed something |
2381 | */ | ||
2369 | if ((oldsize != tempsize) && (dev->flags & IFF_UP)) | 2382 | if ((oldsize != tempsize) && (dev->flags & IFF_UP)) |
2370 | stop_gfar(dev); | 2383 | stop_gfar(dev); |
2371 | 2384 | ||
@@ -2378,11 +2391,12 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
2378 | 2391 | ||
2379 | /* If the mtu is larger than the max size for standard | 2392 | /* If the mtu is larger than the max size for standard |
2380 | * ethernet frames (ie, a jumbo frame), then set maccfg2 | 2393 | * ethernet frames (ie, a jumbo frame), then set maccfg2 |
2381 | * to allow huge frames, and to check the length */ | 2394 | * to allow huge frames, and to check the length |
2395 | */ | ||
2382 | tempval = gfar_read(®s->maccfg2); | 2396 | tempval = gfar_read(®s->maccfg2); |
2383 | 2397 | ||
2384 | if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || | 2398 | if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE || |
2385 | gfar_has_errata(priv, GFAR_ERRATA_74)) | 2399 | gfar_has_errata(priv, GFAR_ERRATA_74)) |
2386 | tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); | 2400 | tempval |= (MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); |
2387 | else | 2401 | else |
2388 | tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); | 2402 | tempval &= ~(MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK); |
@@ -2403,7 +2417,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
2403 | static void gfar_reset_task(struct work_struct *work) | 2417 | static void gfar_reset_task(struct work_struct *work) |
2404 | { | 2418 | { |
2405 | struct gfar_private *priv = container_of(work, struct gfar_private, | 2419 | struct gfar_private *priv = container_of(work, struct gfar_private, |
2406 | reset_task); | 2420 | reset_task); |
2407 | struct net_device *dev = priv->ndev; | 2421 | struct net_device *dev = priv->ndev; |
2408 | 2422 | ||
2409 | if (dev->flags & IFF_UP) { | 2423 | if (dev->flags & IFF_UP) { |
@@ -2430,7 +2444,7 @@ static void gfar_align_skb(struct sk_buff *skb) | |||
2430 | * as many bytes as needed to align the data properly | 2444 | * as many bytes as needed to align the data properly |
2431 | */ | 2445 | */ |
2432 | skb_reserve(skb, RXBUF_ALIGNMENT - | 2446 | skb_reserve(skb, RXBUF_ALIGNMENT - |
2433 | (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); | 2447 | (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); |
2434 | } | 2448 | } |
2435 | 2449 | ||
2436 | /* Interrupt Handler for Transmit complete */ | 2450 | /* Interrupt Handler for Transmit complete */ |
@@ -2464,8 +2478,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2464 | 2478 | ||
2465 | frags = skb_shinfo(skb)->nr_frags; | 2479 | frags = skb_shinfo(skb)->nr_frags; |
2466 | 2480 | ||
2467 | /* | 2481 | /* When time stamping, one additional TxBD must be freed. |
2468 | * When time stamping, one additional TxBD must be freed. | ||
2469 | * Also, we need to dma_unmap_single() the TxPAL. | 2482 | * Also, we need to dma_unmap_single() the TxPAL. |
2470 | */ | 2483 | */ |
2471 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) | 2484 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) |
@@ -2479,7 +2492,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2479 | 2492 | ||
2480 | /* Only clean completed frames */ | 2493 | /* Only clean completed frames */ |
2481 | if ((lstatus & BD_LFLAG(TXBD_READY)) && | 2494 | if ((lstatus & BD_LFLAG(TXBD_READY)) && |
2482 | (lstatus & BD_LENGTH_MASK)) | 2495 | (lstatus & BD_LENGTH_MASK)) |
2483 | break; | 2496 | break; |
2484 | 2497 | ||
2485 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { | 2498 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { |
@@ -2489,11 +2502,12 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2489 | buflen = bdp->length; | 2502 | buflen = bdp->length; |
2490 | 2503 | ||
2491 | dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, | 2504 | dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, |
2492 | buflen, DMA_TO_DEVICE); | 2505 | buflen, DMA_TO_DEVICE); |
2493 | 2506 | ||
2494 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { | 2507 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { |
2495 | struct skb_shared_hwtstamps shhwtstamps; | 2508 | struct skb_shared_hwtstamps shhwtstamps; |
2496 | u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); | 2509 | u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); |
2510 | |||
2497 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | 2511 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); |
2498 | shhwtstamps.hwtstamp = ns_to_ktime(*ns); | 2512 | shhwtstamps.hwtstamp = ns_to_ktime(*ns); |
2499 | skb_pull(skb, GMAC_FCB_LEN + GMAC_TXPAL_LEN); | 2513 | skb_pull(skb, GMAC_FCB_LEN + GMAC_TXPAL_LEN); |
@@ -2506,23 +2520,20 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2506 | bdp = next_txbd(bdp, base, tx_ring_size); | 2520 | bdp = next_txbd(bdp, base, tx_ring_size); |
2507 | 2521 | ||
2508 | for (i = 0; i < frags; i++) { | 2522 | for (i = 0; i < frags; i++) { |
2509 | dma_unmap_page(&priv->ofdev->dev, | 2523 | dma_unmap_page(&priv->ofdev->dev, bdp->bufPtr, |
2510 | bdp->bufPtr, | 2524 | bdp->length, DMA_TO_DEVICE); |
2511 | bdp->length, | ||
2512 | DMA_TO_DEVICE); | ||
2513 | bdp->lstatus &= BD_LFLAG(TXBD_WRAP); | 2525 | bdp->lstatus &= BD_LFLAG(TXBD_WRAP); |
2514 | bdp = next_txbd(bdp, base, tx_ring_size); | 2526 | bdp = next_txbd(bdp, base, tx_ring_size); |
2515 | } | 2527 | } |
2516 | 2528 | ||
2517 | bytes_sent += skb->len; | 2529 | bytes_sent += skb->len; |
2518 | 2530 | ||
2519 | /* | 2531 | /* If there's room in the queue (limit it to rx_buffer_size) |
2520 | * If there's room in the queue (limit it to rx_buffer_size) | ||
2521 | * we add this skb back into the pool, if it's the right size | 2532 | * we add this skb back into the pool, if it's the right size |
2522 | */ | 2533 | */ |
2523 | if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size && | 2534 | if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size && |
2524 | skb_recycle_check(skb, priv->rx_buffer_size + | 2535 | skb_recycle_check(skb, priv->rx_buffer_size + |
2525 | RXBUF_ALIGNMENT)) { | 2536 | RXBUF_ALIGNMENT)) { |
2526 | gfar_align_skb(skb); | 2537 | gfar_align_skb(skb); |
2527 | skb_queue_head(&priv->rx_recycle, skb); | 2538 | skb_queue_head(&priv->rx_recycle, skb); |
2528 | } else | 2539 | } else |
@@ -2531,7 +2542,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2531 | tx_queue->tx_skbuff[skb_dirtytx] = NULL; | 2542 | tx_queue->tx_skbuff[skb_dirtytx] = NULL; |
2532 | 2543 | ||
2533 | skb_dirtytx = (skb_dirtytx + 1) & | 2544 | skb_dirtytx = (skb_dirtytx + 1) & |
2534 | TX_RING_MOD_MASK(tx_ring_size); | 2545 | TX_RING_MOD_MASK(tx_ring_size); |
2535 | 2546 | ||
2536 | howmany++; | 2547 | howmany++; |
2537 | spin_lock_irqsave(&tx_queue->txlock, flags); | 2548 | spin_lock_irqsave(&tx_queue->txlock, flags); |
@@ -2561,8 +2572,7 @@ static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp) | |||
2561 | gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED); | 2572 | gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED); |
2562 | __napi_schedule(&gfargrp->napi); | 2573 | __napi_schedule(&gfargrp->napi); |
2563 | } else { | 2574 | } else { |
2564 | /* | 2575 | /* Clear IEVENT, so interrupts aren't called again |
2565 | * Clear IEVENT, so interrupts aren't called again | ||
2566 | * because of the packets that have already arrived. | 2576 | * because of the packets that have already arrived. |
2567 | */ | 2577 | */ |
2568 | gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK); | 2578 | gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK); |
@@ -2579,7 +2589,7 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id) | |||
2579 | } | 2589 | } |
2580 | 2590 | ||
2581 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, | 2591 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, |
2582 | struct sk_buff *skb) | 2592 | struct sk_buff *skb) |
2583 | { | 2593 | { |
2584 | struct net_device *dev = rx_queue->dev; | 2594 | struct net_device *dev = rx_queue->dev; |
2585 | struct gfar_private *priv = netdev_priv(dev); | 2595 | struct gfar_private *priv = netdev_priv(dev); |
@@ -2590,7 +2600,7 @@ static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, | |||
2590 | gfar_init_rxbdp(rx_queue, bdp, buf); | 2600 | gfar_init_rxbdp(rx_queue, bdp, buf); |
2591 | } | 2601 | } |
2592 | 2602 | ||
2593 | static struct sk_buff * gfar_alloc_skb(struct net_device *dev) | 2603 | static struct sk_buff *gfar_alloc_skb(struct net_device *dev) |
2594 | { | 2604 | { |
2595 | struct gfar_private *priv = netdev_priv(dev); | 2605 | struct gfar_private *priv = netdev_priv(dev); |
2596 | struct sk_buff *skb = NULL; | 2606 | struct sk_buff *skb = NULL; |
@@ -2604,7 +2614,7 @@ static struct sk_buff * gfar_alloc_skb(struct net_device *dev) | |||
2604 | return skb; | 2614 | return skb; |
2605 | } | 2615 | } |
2606 | 2616 | ||
2607 | struct sk_buff * gfar_new_skb(struct net_device *dev) | 2617 | struct sk_buff *gfar_new_skb(struct net_device *dev) |
2608 | { | 2618 | { |
2609 | struct gfar_private *priv = netdev_priv(dev); | 2619 | struct gfar_private *priv = netdev_priv(dev); |
2610 | struct sk_buff *skb = NULL; | 2620 | struct sk_buff *skb = NULL; |
@@ -2622,8 +2632,7 @@ static inline void count_errors(unsigned short status, struct net_device *dev) | |||
2622 | struct net_device_stats *stats = &dev->stats; | 2632 | struct net_device_stats *stats = &dev->stats; |
2623 | struct gfar_extra_stats *estats = &priv->extra_stats; | 2633 | struct gfar_extra_stats *estats = &priv->extra_stats; |
2624 | 2634 | ||
2625 | /* If the packet was truncated, none of the other errors | 2635 | /* If the packet was truncated, none of the other errors matter */ |
2626 | * matter */ | ||
2627 | if (status & RXBD_TRUNCATED) { | 2636 | if (status & RXBD_TRUNCATED) { |
2628 | stats->rx_length_errors++; | 2637 | stats->rx_length_errors++; |
2629 | 2638 | ||
@@ -2664,7 +2673,8 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) | |||
2664 | { | 2673 | { |
2665 | /* If valid headers were found, and valid sums | 2674 | /* If valid headers were found, and valid sums |
2666 | * were verified, then we tell the kernel that no | 2675 | * were verified, then we tell the kernel that no |
2667 | * checksumming is necessary. Otherwise, it is */ | 2676 | * checksumming is necessary. Otherwise, it is [FIXME] |
2677 | */ | ||
2668 | if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) | 2678 | if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) |
2669 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 2679 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
2670 | else | 2680 | else |
@@ -2672,8 +2682,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) | |||
2672 | } | 2682 | } |
2673 | 2683 | ||
2674 | 2684 | ||
2675 | /* gfar_process_frame() -- handle one incoming packet if skb | 2685 | /* gfar_process_frame() -- handle one incoming packet if skb isn't NULL. */ |
2676 | * isn't NULL. */ | ||
2677 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | 2686 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, |
2678 | int amount_pull, struct napi_struct *napi) | 2687 | int amount_pull, struct napi_struct *napi) |
2679 | { | 2688 | { |
@@ -2685,8 +2694,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
2685 | /* fcb is at the beginning if exists */ | 2694 | /* fcb is at the beginning if exists */ |
2686 | fcb = (struct rxfcb *)skb->data; | 2695 | fcb = (struct rxfcb *)skb->data; |
2687 | 2696 | ||
2688 | /* Remove the FCB from the skb */ | 2697 | /* Remove the FCB from the skb |
2689 | /* Remove the padded bytes, if there are any */ | 2698 | * Remove the padded bytes, if there are any |
2699 | */ | ||
2690 | if (amount_pull) { | 2700 | if (amount_pull) { |
2691 | skb_record_rx_queue(skb, fcb->rq); | 2701 | skb_record_rx_queue(skb, fcb->rq); |
2692 | skb_pull(skb, amount_pull); | 2702 | skb_pull(skb, amount_pull); |
@@ -2696,6 +2706,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
2696 | if (priv->hwts_rx_en) { | 2706 | if (priv->hwts_rx_en) { |
2697 | struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); | 2707 | struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); |
2698 | u64 *ns = (u64 *) skb->data; | 2708 | u64 *ns = (u64 *) skb->data; |
2709 | |||
2699 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); | 2710 | memset(shhwtstamps, 0, sizeof(*shhwtstamps)); |
2700 | shhwtstamps->hwtstamp = ns_to_ktime(*ns); | 2711 | shhwtstamps->hwtstamp = ns_to_ktime(*ns); |
2701 | } | 2712 | } |
@@ -2709,8 +2720,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
2709 | /* Tell the skb what kind of packet this is */ | 2720 | /* Tell the skb what kind of packet this is */ |
2710 | skb->protocol = eth_type_trans(skb, dev); | 2721 | skb->protocol = eth_type_trans(skb, dev); |
2711 | 2722 | ||
2712 | /* | 2723 | /* There's need to check for NETIF_F_HW_VLAN_RX here. |
2713 | * There's need to check for NETIF_F_HW_VLAN_RX here. | ||
2714 | * Even if vlan rx accel is disabled, on some chips | 2724 | * Even if vlan rx accel is disabled, on some chips |
2715 | * RXFCB_VLN is pseudo randomly set. | 2725 | * RXFCB_VLN is pseudo randomly set. |
2716 | */ | 2726 | */ |
@@ -2728,8 +2738,8 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | |||
2728 | } | 2738 | } |
2729 | 2739 | ||
2730 | /* gfar_clean_rx_ring() -- Processes each frame in the rx ring | 2740 | /* gfar_clean_rx_ring() -- Processes each frame in the rx ring |
2731 | * until the budget/quota has been reached. Returns the number | 2741 | * until the budget/quota has been reached. Returns the number |
2732 | * of frames handled | 2742 | * of frames handled |
2733 | */ | 2743 | */ |
2734 | int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | 2744 | int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) |
2735 | { | 2745 | { |
@@ -2749,6 +2759,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2749 | 2759 | ||
2750 | while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { | 2760 | while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { |
2751 | struct sk_buff *newskb; | 2761 | struct sk_buff *newskb; |
2762 | |||
2752 | rmb(); | 2763 | rmb(); |
2753 | 2764 | ||
2754 | /* Add another skb for the future */ | 2765 | /* Add another skb for the future */ |
@@ -2757,15 +2768,15 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2757 | skb = rx_queue->rx_skbuff[rx_queue->skb_currx]; | 2768 | skb = rx_queue->rx_skbuff[rx_queue->skb_currx]; |
2758 | 2769 | ||
2759 | dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, | 2770 | dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, |
2760 | priv->rx_buffer_size, DMA_FROM_DEVICE); | 2771 | priv->rx_buffer_size, DMA_FROM_DEVICE); |
2761 | 2772 | ||
2762 | if (unlikely(!(bdp->status & RXBD_ERR) && | 2773 | if (unlikely(!(bdp->status & RXBD_ERR) && |
2763 | bdp->length > priv->rx_buffer_size)) | 2774 | bdp->length > priv->rx_buffer_size)) |
2764 | bdp->status = RXBD_LARGE; | 2775 | bdp->status = RXBD_LARGE; |
2765 | 2776 | ||
2766 | /* We drop the frame if we failed to allocate a new buffer */ | 2777 | /* We drop the frame if we failed to allocate a new buffer */ |
2767 | if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || | 2778 | if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || |
2768 | bdp->status & RXBD_ERR)) { | 2779 | bdp->status & RXBD_ERR)) { |
2769 | count_errors(bdp->status, dev); | 2780 | count_errors(bdp->status, dev); |
2770 | 2781 | ||
2771 | if (unlikely(!newskb)) | 2782 | if (unlikely(!newskb)) |
@@ -2784,7 +2795,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2784 | rx_queue->stats.rx_bytes += pkt_len; | 2795 | rx_queue->stats.rx_bytes += pkt_len; |
2785 | skb_record_rx_queue(skb, rx_queue->qindex); | 2796 | skb_record_rx_queue(skb, rx_queue->qindex); |
2786 | gfar_process_frame(dev, skb, amount_pull, | 2797 | gfar_process_frame(dev, skb, amount_pull, |
2787 | &rx_queue->grp->napi); | 2798 | &rx_queue->grp->napi); |
2788 | 2799 | ||
2789 | } else { | 2800 | } else { |
2790 | netif_warn(priv, rx_err, dev, "Missing skb!\n"); | 2801 | netif_warn(priv, rx_err, dev, "Missing skb!\n"); |
@@ -2803,9 +2814,8 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2803 | bdp = next_bd(bdp, base, rx_queue->rx_ring_size); | 2814 | bdp = next_bd(bdp, base, rx_queue->rx_ring_size); |
2804 | 2815 | ||
2805 | /* update to point at the next skb */ | 2816 | /* update to point at the next skb */ |
2806 | rx_queue->skb_currx = | 2817 | rx_queue->skb_currx = (rx_queue->skb_currx + 1) & |
2807 | (rx_queue->skb_currx + 1) & | 2818 | RX_RING_MOD_MASK(rx_queue->rx_ring_size); |
2808 | RX_RING_MOD_MASK(rx_queue->rx_ring_size); | ||
2809 | } | 2819 | } |
2810 | 2820 | ||
2811 | /* Update the current rxbd pointer to be the next one */ | 2821 | /* Update the current rxbd pointer to be the next one */ |
@@ -2816,8 +2826,8 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2816 | 2826 | ||
2817 | static int gfar_poll(struct napi_struct *napi, int budget) | 2827 | static int gfar_poll(struct napi_struct *napi, int budget) |
2818 | { | 2828 | { |
2819 | struct gfar_priv_grp *gfargrp = container_of(napi, | 2829 | struct gfar_priv_grp *gfargrp = |
2820 | struct gfar_priv_grp, napi); | 2830 | container_of(napi, struct gfar_priv_grp, napi); |
2821 | struct gfar_private *priv = gfargrp->priv; | 2831 | struct gfar_private *priv = gfargrp->priv; |
2822 | struct gfar __iomem *regs = gfargrp->regs; | 2832 | struct gfar __iomem *regs = gfargrp->regs; |
2823 | struct gfar_priv_tx_q *tx_queue = NULL; | 2833 | struct gfar_priv_tx_q *tx_queue = NULL; |
@@ -2831,11 +2841,11 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2831 | budget_per_queue = budget/num_queues; | 2841 | budget_per_queue = budget/num_queues; |
2832 | 2842 | ||
2833 | /* Clear IEVENT, so interrupts aren't called again | 2843 | /* Clear IEVENT, so interrupts aren't called again |
2834 | * because of the packets that have already arrived */ | 2844 | * because of the packets that have already arrived |
2845 | */ | ||
2835 | gfar_write(®s->ievent, IEVENT_RTX_MASK); | 2846 | gfar_write(®s->ievent, IEVENT_RTX_MASK); |
2836 | 2847 | ||
2837 | while (num_queues && left_over_budget) { | 2848 | while (num_queues && left_over_budget) { |
2838 | |||
2839 | budget_per_queue = left_over_budget/num_queues; | 2849 | budget_per_queue = left_over_budget/num_queues; |
2840 | left_over_budget = 0; | 2850 | left_over_budget = 0; |
2841 | 2851 | ||
@@ -2846,12 +2856,13 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2846 | tx_queue = priv->tx_queue[rx_queue->qindex]; | 2856 | tx_queue = priv->tx_queue[rx_queue->qindex]; |
2847 | 2857 | ||
2848 | tx_cleaned += gfar_clean_tx_ring(tx_queue); | 2858 | tx_cleaned += gfar_clean_tx_ring(tx_queue); |
2849 | rx_cleaned_per_queue = gfar_clean_rx_ring(rx_queue, | 2859 | rx_cleaned_per_queue = |
2850 | budget_per_queue); | 2860 | gfar_clean_rx_ring(rx_queue, budget_per_queue); |
2851 | rx_cleaned += rx_cleaned_per_queue; | 2861 | rx_cleaned += rx_cleaned_per_queue; |
2852 | if(rx_cleaned_per_queue < budget_per_queue) { | 2862 | if (rx_cleaned_per_queue < budget_per_queue) { |
2853 | left_over_budget = left_over_budget + | 2863 | left_over_budget = left_over_budget + |
2854 | (budget_per_queue - rx_cleaned_per_queue); | 2864 | (budget_per_queue - |
2865 | rx_cleaned_per_queue); | ||
2855 | set_bit(i, &serviced_queues); | 2866 | set_bit(i, &serviced_queues); |
2856 | num_queues--; | 2867 | num_queues--; |
2857 | } | 2868 | } |
@@ -2869,25 +2880,25 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2869 | 2880 | ||
2870 | gfar_write(®s->imask, IMASK_DEFAULT); | 2881 | gfar_write(®s->imask, IMASK_DEFAULT); |
2871 | 2882 | ||
2872 | /* If we are coalescing interrupts, update the timer */ | 2883 | /* If we are coalescing interrupts, update the timer |
2873 | /* Otherwise, clear it */ | 2884 | * Otherwise, clear it |
2874 | gfar_configure_coalescing(priv, | 2885 | */ |
2875 | gfargrp->rx_bit_map, gfargrp->tx_bit_map); | 2886 | gfar_configure_coalescing(priv, gfargrp->rx_bit_map, |
2887 | gfargrp->tx_bit_map); | ||
2876 | } | 2888 | } |
2877 | 2889 | ||
2878 | return rx_cleaned; | 2890 | return rx_cleaned; |
2879 | } | 2891 | } |
2880 | 2892 | ||
2881 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2893 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2882 | /* | 2894 | /* Polling 'interrupt' - used by things like netconsole to send skbs |
2883 | * Polling 'interrupt' - used by things like netconsole to send skbs | ||
2884 | * without having to re-enable interrupts. It's not called while | 2895 | * without having to re-enable interrupts. It's not called while |
2885 | * the interrupt routine is executing. | 2896 | * the interrupt routine is executing. |
2886 | */ | 2897 | */ |
2887 | static void gfar_netpoll(struct net_device *dev) | 2898 | static void gfar_netpoll(struct net_device *dev) |
2888 | { | 2899 | { |
2889 | struct gfar_private *priv = netdev_priv(dev); | 2900 | struct gfar_private *priv = netdev_priv(dev); |
2890 | int i = 0; | 2901 | int i; |
2891 | 2902 | ||
2892 | /* If the device has multiple interrupts, run tx/rx */ | 2903 | /* If the device has multiple interrupts, run tx/rx */ |
2893 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 2904 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
@@ -2896,7 +2907,7 @@ static void gfar_netpoll(struct net_device *dev) | |||
2896 | disable_irq(priv->gfargrp[i].interruptReceive); | 2907 | disable_irq(priv->gfargrp[i].interruptReceive); |
2897 | disable_irq(priv->gfargrp[i].interruptError); | 2908 | disable_irq(priv->gfargrp[i].interruptError); |
2898 | gfar_interrupt(priv->gfargrp[i].interruptTransmit, | 2909 | gfar_interrupt(priv->gfargrp[i].interruptTransmit, |
2899 | &priv->gfargrp[i]); | 2910 | &priv->gfargrp[i]); |
2900 | enable_irq(priv->gfargrp[i].interruptError); | 2911 | enable_irq(priv->gfargrp[i].interruptError); |
2901 | enable_irq(priv->gfargrp[i].interruptReceive); | 2912 | enable_irq(priv->gfargrp[i].interruptReceive); |
2902 | enable_irq(priv->gfargrp[i].interruptTransmit); | 2913 | enable_irq(priv->gfargrp[i].interruptTransmit); |
@@ -2905,7 +2916,7 @@ static void gfar_netpoll(struct net_device *dev) | |||
2905 | for (i = 0; i < priv->num_grps; i++) { | 2916 | for (i = 0; i < priv->num_grps; i++) { |
2906 | disable_irq(priv->gfargrp[i].interruptTransmit); | 2917 | disable_irq(priv->gfargrp[i].interruptTransmit); |
2907 | gfar_interrupt(priv->gfargrp[i].interruptTransmit, | 2918 | gfar_interrupt(priv->gfargrp[i].interruptTransmit, |
2908 | &priv->gfargrp[i]); | 2919 | &priv->gfargrp[i]); |
2909 | enable_irq(priv->gfargrp[i].interruptTransmit); | 2920 | enable_irq(priv->gfargrp[i].interruptTransmit); |
2910 | } | 2921 | } |
2911 | } | 2922 | } |
@@ -2957,7 +2968,8 @@ static void adjust_link(struct net_device *dev) | |||
2957 | u32 ecntrl = gfar_read(®s->ecntrl); | 2968 | u32 ecntrl = gfar_read(®s->ecntrl); |
2958 | 2969 | ||
2959 | /* Now we make sure that we can be in full duplex mode. | 2970 | /* Now we make sure that we can be in full duplex mode. |
2960 | * If not, we operate in half-duplex mode. */ | 2971 | * If not, we operate in half-duplex mode. |
2972 | */ | ||
2961 | if (phydev->duplex != priv->oldduplex) { | 2973 | if (phydev->duplex != priv->oldduplex) { |
2962 | new_state = 1; | 2974 | new_state = 1; |
2963 | if (!(phydev->duplex)) | 2975 | if (!(phydev->duplex)) |
@@ -2983,7 +2995,8 @@ static void adjust_link(struct net_device *dev) | |||
2983 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); | 2995 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); |
2984 | 2996 | ||
2985 | /* Reduced mode distinguishes | 2997 | /* Reduced mode distinguishes |
2986 | * between 10 and 100 */ | 2998 | * between 10 and 100 |
2999 | */ | ||
2987 | if (phydev->speed == SPEED_100) | 3000 | if (phydev->speed == SPEED_100) |
2988 | ecntrl |= ECNTRL_R100; | 3001 | ecntrl |= ECNTRL_R100; |
2989 | else | 3002 | else |
@@ -3022,7 +3035,8 @@ static void adjust_link(struct net_device *dev) | |||
3022 | /* Update the hash table based on the current list of multicast | 3035 | /* Update the hash table based on the current list of multicast |
3023 | * addresses we subscribe to. Also, change the promiscuity of | 3036 | * addresses we subscribe to. Also, change the promiscuity of |
3024 | * the device based on the flags (this function is called | 3037 | * the device based on the flags (this function is called |
3025 | * whenever dev->flags is changed */ | 3038 | * whenever dev->flags is changed |
3039 | */ | ||
3026 | static void gfar_set_multi(struct net_device *dev) | 3040 | static void gfar_set_multi(struct net_device *dev) |
3027 | { | 3041 | { |
3028 | struct netdev_hw_addr *ha; | 3042 | struct netdev_hw_addr *ha; |
@@ -3084,7 +3098,8 @@ static void gfar_set_multi(struct net_device *dev) | |||
3084 | 3098 | ||
3085 | /* If we have extended hash tables, we need to | 3099 | /* If we have extended hash tables, we need to |
3086 | * clear the exact match registers to prepare for | 3100 | * clear the exact match registers to prepare for |
3087 | * setting them */ | 3101 | * setting them |
3102 | */ | ||
3088 | if (priv->extended_hash) { | 3103 | if (priv->extended_hash) { |
3089 | em_num = GFAR_EM_NUM + 1; | 3104 | em_num = GFAR_EM_NUM + 1; |
3090 | gfar_clear_exact_match(dev); | 3105 | gfar_clear_exact_match(dev); |
@@ -3110,13 +3125,14 @@ static void gfar_set_multi(struct net_device *dev) | |||
3110 | 3125 | ||
3111 | 3126 | ||
3112 | /* Clears each of the exact match registers to zero, so they | 3127 | /* Clears each of the exact match registers to zero, so they |
3113 | * don't interfere with normal reception */ | 3128 | * don't interfere with normal reception |
3129 | */ | ||
3114 | static void gfar_clear_exact_match(struct net_device *dev) | 3130 | static void gfar_clear_exact_match(struct net_device *dev) |
3115 | { | 3131 | { |
3116 | int idx; | 3132 | int idx; |
3117 | static const u8 zero_arr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; | 3133 | static const u8 zero_arr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; |
3118 | 3134 | ||
3119 | for(idx = 1;idx < GFAR_EM_NUM + 1;idx++) | 3135 | for (idx = 1; idx < GFAR_EM_NUM + 1; idx++) |
3120 | gfar_set_mac_for_addr(dev, idx, zero_arr); | 3136 | gfar_set_mac_for_addr(dev, idx, zero_arr); |
3121 | } | 3137 | } |
3122 | 3138 | ||
@@ -3132,7 +3148,8 @@ static void gfar_clear_exact_match(struct net_device *dev) | |||
3132 | * hash index which gaddr register to use, and the 5 other bits | 3148 | * hash index which gaddr register to use, and the 5 other bits |
3133 | * indicate which bit (assuming an IBM numbering scheme, which | 3149 | * indicate which bit (assuming an IBM numbering scheme, which |
3134 | * for PowerPC (tm) is usually the case) in the register holds | 3150 | * for PowerPC (tm) is usually the case) in the register holds |
3135 | * the entry. */ | 3151 | * the entry. |
3152 | */ | ||
3136 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr) | 3153 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr) |
3137 | { | 3154 | { |
3138 | u32 tempval; | 3155 | u32 tempval; |
@@ -3164,8 +3181,9 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, | |||
3164 | 3181 | ||
3165 | macptr += num*2; | 3182 | macptr += num*2; |
3166 | 3183 | ||
3167 | /* Now copy it into the mac registers backwards, cuz */ | 3184 | /* Now copy it into the mac registers backwards, cuz |
3168 | /* little endian is silly */ | 3185 | * little endian is silly |
3186 | */ | ||
3169 | for (idx = 0; idx < ETH_ALEN; idx++) | 3187 | for (idx = 0; idx < ETH_ALEN; idx++) |
3170 | tmpbuf[ETH_ALEN - 1 - idx] = addr[idx]; | 3188 | tmpbuf[ETH_ALEN - 1 - idx] = addr[idx]; |
3171 | 3189 | ||
@@ -3197,7 +3215,8 @@ static irqreturn_t gfar_error(int irq, void *grp_id) | |||
3197 | 3215 | ||
3198 | /* Hmm... */ | 3216 | /* Hmm... */ |
3199 | if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) | 3217 | if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv)) |
3200 | netdev_dbg(dev, "error interrupt (ievent=0x%08x imask=0x%08x)\n", | 3218 | netdev_dbg(dev, |
3219 | "error interrupt (ievent=0x%08x imask=0x%08x)\n", | ||
3201 | events, gfar_read(®s->imask)); | 3220 | events, gfar_read(®s->imask)); |
3202 | 3221 | ||
3203 | /* Update the error counters */ | 3222 | /* Update the error counters */ |
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 8a025570d97e..8971921cc1c8 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c | |||
@@ -46,18 +46,24 @@ | |||
46 | #include "gianfar.h" | 46 | #include "gianfar.h" |
47 | 47 | ||
48 | extern void gfar_start(struct net_device *dev); | 48 | extern void gfar_start(struct net_device *dev); |
49 | extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); | 49 | extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, |
50 | int rx_work_limit); | ||
50 | 51 | ||
51 | #define GFAR_MAX_COAL_USECS 0xffff | 52 | #define GFAR_MAX_COAL_USECS 0xffff |
52 | #define GFAR_MAX_COAL_FRAMES 0xff | 53 | #define GFAR_MAX_COAL_FRAMES 0xff |
53 | static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, | 54 | static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, |
54 | u64 * buf); | 55 | u64 *buf); |
55 | static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); | 56 | static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); |
56 | static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); | 57 | static int gfar_gcoalesce(struct net_device *dev, |
57 | static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); | 58 | struct ethtool_coalesce *cvals); |
58 | static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals); | 59 | static int gfar_scoalesce(struct net_device *dev, |
59 | static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); | 60 | struct ethtool_coalesce *cvals); |
60 | static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); | 61 | static void gfar_gringparam(struct net_device *dev, |
62 | struct ethtool_ringparam *rvals); | ||
63 | static int gfar_sringparam(struct net_device *dev, | ||
64 | struct ethtool_ringparam *rvals); | ||
65 | static void gfar_gdrvinfo(struct net_device *dev, | ||
66 | struct ethtool_drvinfo *drvinfo); | ||
61 | 67 | ||
62 | static const char stat_gstrings[][ETH_GSTRING_LEN] = { | 68 | static const char stat_gstrings[][ETH_GSTRING_LEN] = { |
63 | "rx-dropped-by-kernel", | 69 | "rx-dropped-by-kernel", |
@@ -130,14 +136,15 @@ static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) | |||
130 | memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); | 136 | memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); |
131 | else | 137 | else |
132 | memcpy(buf, stat_gstrings, | 138 | memcpy(buf, stat_gstrings, |
133 | GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); | 139 | GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); |
134 | } | 140 | } |
135 | 141 | ||
136 | /* Fill in an array of 64-bit statistics from various sources. | 142 | /* Fill in an array of 64-bit statistics from various sources. |
137 | * This array will be appended to the end of the ethtool_stats | 143 | * This array will be appended to the end of the ethtool_stats |
138 | * structure, and returned to user space | 144 | * structure, and returned to user space |
139 | */ | 145 | */ |
140 | static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) | 146 | static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, |
147 | u64 *buf) | ||
141 | { | 148 | { |
142 | int i; | 149 | int i; |
143 | struct gfar_private *priv = netdev_priv(dev); | 150 | struct gfar_private *priv = netdev_priv(dev); |
@@ -174,8 +181,8 @@ static int gfar_sset_count(struct net_device *dev, int sset) | |||
174 | } | 181 | } |
175 | 182 | ||
176 | /* Fills in the drvinfo structure with some basic info */ | 183 | /* Fills in the drvinfo structure with some basic info */ |
177 | static void gfar_gdrvinfo(struct net_device *dev, struct | 184 | static void gfar_gdrvinfo(struct net_device *dev, |
178 | ethtool_drvinfo *drvinfo) | 185 | struct ethtool_drvinfo *drvinfo) |
179 | { | 186 | { |
180 | strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); | 187 | strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); |
181 | strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); | 188 | strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); |
@@ -226,7 +233,8 @@ static int gfar_reglen(struct net_device *dev) | |||
226 | } | 233 | } |
227 | 234 | ||
228 | /* Return a dump of the GFAR register space */ | 235 | /* Return a dump of the GFAR register space */ |
229 | static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) | 236 | static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
237 | void *regbuf) | ||
230 | { | 238 | { |
231 | int i; | 239 | int i; |
232 | struct gfar_private *priv = netdev_priv(dev); | 240 | struct gfar_private *priv = netdev_priv(dev); |
@@ -239,7 +247,8 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi | |||
239 | 247 | ||
240 | /* Convert microseconds to ethernet clock ticks, which changes | 248 | /* Convert microseconds to ethernet clock ticks, which changes |
241 | * depending on what speed the controller is running at */ | 249 | * depending on what speed the controller is running at */ |
242 | static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs) | 250 | static unsigned int gfar_usecs2ticks(struct gfar_private *priv, |
251 | unsigned int usecs) | ||
243 | { | 252 | { |
244 | unsigned int count; | 253 | unsigned int count; |
245 | 254 | ||
@@ -263,7 +272,8 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use | |||
263 | } | 272 | } |
264 | 273 | ||
265 | /* Convert ethernet clock ticks to microseconds */ | 274 | /* Convert ethernet clock ticks to microseconds */ |
266 | static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks) | 275 | static unsigned int gfar_ticks2usecs(struct gfar_private *priv, |
276 | unsigned int ticks) | ||
267 | { | 277 | { |
268 | unsigned int count; | 278 | unsigned int count; |
269 | 279 | ||
@@ -288,7 +298,8 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic | |||
288 | 298 | ||
289 | /* Get the coalescing parameters, and put them in the cvals | 299 | /* Get the coalescing parameters, and put them in the cvals |
290 | * structure. */ | 300 | * structure. */ |
291 | static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) | 301 | static int gfar_gcoalesce(struct net_device *dev, |
302 | struct ethtool_coalesce *cvals) | ||
292 | { | 303 | { |
293 | struct gfar_private *priv = netdev_priv(dev); | 304 | struct gfar_private *priv = netdev_priv(dev); |
294 | struct gfar_priv_rx_q *rx_queue = NULL; | 305 | struct gfar_priv_rx_q *rx_queue = NULL; |
@@ -353,7 +364,8 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals | |||
353 | * Both cvals->*_usecs and cvals->*_frames have to be > 0 | 364 | * Both cvals->*_usecs and cvals->*_frames have to be > 0 |
354 | * in order for coalescing to be active | 365 | * in order for coalescing to be active |
355 | */ | 366 | */ |
356 | static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) | 367 | static int gfar_scoalesce(struct net_device *dev, |
368 | struct ethtool_coalesce *cvals) | ||
357 | { | 369 | { |
358 | struct gfar_private *priv = netdev_priv(dev); | 370 | struct gfar_private *priv = netdev_priv(dev); |
359 | int i = 0; | 371 | int i = 0; |
@@ -364,7 +376,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals | |||
364 | /* Set up rx coalescing */ | 376 | /* Set up rx coalescing */ |
365 | /* As of now, we will enable/disable coalescing for all | 377 | /* As of now, we will enable/disable coalescing for all |
366 | * queues together in case of eTSEC2, this will be modified | 378 | * queues together in case of eTSEC2, this will be modified |
367 | * along with the ethtool interface */ | 379 | * along with the ethtool interface |
380 | */ | ||
368 | if ((cvals->rx_coalesce_usecs == 0) || | 381 | if ((cvals->rx_coalesce_usecs == 0) || |
369 | (cvals->rx_max_coalesced_frames == 0)) { | 382 | (cvals->rx_max_coalesced_frames == 0)) { |
370 | for (i = 0; i < priv->num_rx_queues; i++) | 383 | for (i = 0; i < priv->num_rx_queues; i++) |
@@ -433,7 +446,8 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals | |||
433 | /* Fills in rvals with the current ring parameters. Currently, | 446 | /* Fills in rvals with the current ring parameters. Currently, |
434 | * rx, rx_mini, and rx_jumbo rings are the same size, as mini and | 447 | * rx, rx_mini, and rx_jumbo rings are the same size, as mini and |
435 | * jumbo are ignored by the driver */ | 448 | * jumbo are ignored by the driver */ |
436 | static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) | 449 | static void gfar_gringparam(struct net_device *dev, |
450 | struct ethtool_ringparam *rvals) | ||
437 | { | 451 | { |
438 | struct gfar_private *priv = netdev_priv(dev); | 452 | struct gfar_private *priv = netdev_priv(dev); |
439 | struct gfar_priv_tx_q *tx_queue = NULL; | 453 | struct gfar_priv_tx_q *tx_queue = NULL; |
@@ -459,8 +473,10 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv | |||
459 | /* Change the current ring parameters, stopping the controller if | 473 | /* Change the current ring parameters, stopping the controller if |
460 | * necessary so that we don't mess things up while we're in | 474 | * necessary so that we don't mess things up while we're in |
461 | * motion. We wait for the ring to be clean before reallocating | 475 | * motion. We wait for the ring to be clean before reallocating |
462 | * the rings. */ | 476 | * the rings. |
463 | static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) | 477 | */ |
478 | static int gfar_sringparam(struct net_device *dev, | ||
479 | struct ethtool_ringparam *rvals) | ||
464 | { | 480 | { |
465 | struct gfar_private *priv = netdev_priv(dev); | 481 | struct gfar_private *priv = netdev_priv(dev); |
466 | int err = 0, i = 0; | 482 | int err = 0, i = 0; |
@@ -486,7 +502,8 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva | |||
486 | unsigned long flags; | 502 | unsigned long flags; |
487 | 503 | ||
488 | /* Halt TX and RX, and process the frames which | 504 | /* Halt TX and RX, and process the frames which |
489 | * have already been received */ | 505 | * have already been received |
506 | */ | ||
490 | local_irq_save(flags); | 507 | local_irq_save(flags); |
491 | lock_tx_qs(priv); | 508 | lock_tx_qs(priv); |
492 | lock_rx_qs(priv); | 509 | lock_rx_qs(priv); |
@@ -499,7 +516,7 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva | |||
499 | 516 | ||
500 | for (i = 0; i < priv->num_rx_queues; i++) | 517 | for (i = 0; i < priv->num_rx_queues; i++) |
501 | gfar_clean_rx_ring(priv->rx_queue[i], | 518 | gfar_clean_rx_ring(priv->rx_queue[i], |
502 | priv->rx_queue[i]->rx_ring_size); | 519 | priv->rx_queue[i]->rx_ring_size); |
503 | 520 | ||
504 | /* Now we take down the rings to rebuild them */ | 521 | /* Now we take down the rings to rebuild them */ |
505 | stop_gfar(dev); | 522 | stop_gfar(dev); |
@@ -509,7 +526,8 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva | |||
509 | for (i = 0; i < priv->num_rx_queues; i++) { | 526 | for (i = 0; i < priv->num_rx_queues; i++) { |
510 | priv->rx_queue[i]->rx_ring_size = rvals->rx_pending; | 527 | priv->rx_queue[i]->rx_ring_size = rvals->rx_pending; |
511 | priv->tx_queue[i]->tx_ring_size = rvals->tx_pending; | 528 | priv->tx_queue[i]->tx_ring_size = rvals->tx_pending; |
512 | priv->tx_queue[i]->num_txbdfree = priv->tx_queue[i]->tx_ring_size; | 529 | priv->tx_queue[i]->num_txbdfree = |
530 | priv->tx_queue[i]->tx_ring_size; | ||
513 | } | 531 | } |
514 | 532 | ||
515 | /* Rebuild the rings with the new size */ | 533 | /* Rebuild the rings with the new size */ |
@@ -535,7 +553,8 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) | |||
535 | 553 | ||
536 | if (dev->flags & IFF_UP) { | 554 | if (dev->flags & IFF_UP) { |
537 | /* Halt TX and RX, and process the frames which | 555 | /* Halt TX and RX, and process the frames which |
538 | * have already been received */ | 556 | * have already been received |
557 | */ | ||
539 | local_irq_save(flags); | 558 | local_irq_save(flags); |
540 | lock_tx_qs(priv); | 559 | lock_tx_qs(priv); |
541 | lock_rx_qs(priv); | 560 | lock_rx_qs(priv); |
@@ -548,7 +567,7 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) | |||
548 | 567 | ||
549 | for (i = 0; i < priv->num_rx_queues; i++) | 568 | for (i = 0; i < priv->num_rx_queues; i++) |
550 | gfar_clean_rx_ring(priv->rx_queue[i], | 569 | gfar_clean_rx_ring(priv->rx_queue[i], |
551 | priv->rx_queue[i]->rx_ring_size); | 570 | priv->rx_queue[i]->rx_ring_size); |
552 | 571 | ||
553 | /* Now we take down the rings to rebuild them */ | 572 | /* Now we take down the rings to rebuild them */ |
554 | stop_gfar(dev); | 573 | stop_gfar(dev); |
@@ -564,12 +583,14 @@ int gfar_set_features(struct net_device *dev, netdev_features_t features) | |||
564 | static uint32_t gfar_get_msglevel(struct net_device *dev) | 583 | static uint32_t gfar_get_msglevel(struct net_device *dev) |
565 | { | 584 | { |
566 | struct gfar_private *priv = netdev_priv(dev); | 585 | struct gfar_private *priv = netdev_priv(dev); |
586 | |||
567 | return priv->msg_enable; | 587 | return priv->msg_enable; |
568 | } | 588 | } |
569 | 589 | ||
570 | static void gfar_set_msglevel(struct net_device *dev, uint32_t data) | 590 | static void gfar_set_msglevel(struct net_device *dev, uint32_t data) |
571 | { | 591 | { |
572 | struct gfar_private *priv = netdev_priv(dev); | 592 | struct gfar_private *priv = netdev_priv(dev); |
593 | |||
573 | priv->msg_enable = data; | 594 | priv->msg_enable = data; |
574 | } | 595 | } |
575 | 596 | ||
@@ -614,14 +635,14 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
614 | 635 | ||
615 | if (ethflow & RXH_L2DA) { | 636 | if (ethflow & RXH_L2DA) { |
616 | fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | | 637 | fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | |
617 | RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; | 638 | RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; |
618 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 639 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
619 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 640 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
620 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 641 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
621 | priv->cur_filer_idx = priv->cur_filer_idx - 1; | 642 | priv->cur_filer_idx = priv->cur_filer_idx - 1; |
622 | 643 | ||
623 | fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | | 644 | fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | |
624 | RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; | 645 | RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; |
625 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 646 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
626 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 647 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
627 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 648 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -630,7 +651,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
630 | 651 | ||
631 | if (ethflow & RXH_VLAN) { | 652 | if (ethflow & RXH_VLAN) { |
632 | fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 653 | fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
633 | RQFCR_AND | RQFCR_HASHTBL_0; | 654 | RQFCR_AND | RQFCR_HASHTBL_0; |
634 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 655 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
635 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 656 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
636 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 657 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
@@ -639,7 +660,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
639 | 660 | ||
640 | if (ethflow & RXH_IP_SRC) { | 661 | if (ethflow & RXH_IP_SRC) { |
641 | fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 662 | fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
642 | RQFCR_AND | RQFCR_HASHTBL_0; | 663 | RQFCR_AND | RQFCR_HASHTBL_0; |
643 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 664 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
644 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 665 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
645 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 666 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -648,7 +669,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
648 | 669 | ||
649 | if (ethflow & (RXH_IP_DST)) { | 670 | if (ethflow & (RXH_IP_DST)) { |
650 | fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 671 | fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
651 | RQFCR_AND | RQFCR_HASHTBL_0; | 672 | RQFCR_AND | RQFCR_HASHTBL_0; |
652 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 673 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
653 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 674 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
654 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 675 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -657,7 +678,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
657 | 678 | ||
658 | if (ethflow & RXH_L3_PROTO) { | 679 | if (ethflow & RXH_L3_PROTO) { |
659 | fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 680 | fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
660 | RQFCR_AND | RQFCR_HASHTBL_0; | 681 | RQFCR_AND | RQFCR_HASHTBL_0; |
661 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 682 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
662 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 683 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
663 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 684 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -666,7 +687,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
666 | 687 | ||
667 | if (ethflow & RXH_L4_B_0_1) { | 688 | if (ethflow & RXH_L4_B_0_1) { |
668 | fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 689 | fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
669 | RQFCR_AND | RQFCR_HASHTBL_0; | 690 | RQFCR_AND | RQFCR_HASHTBL_0; |
670 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 691 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
671 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 692 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
672 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 693 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -675,7 +696,7 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
675 | 696 | ||
676 | if (ethflow & RXH_L4_B_2_3) { | 697 | if (ethflow & RXH_L4_B_2_3) { |
677 | fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | | 698 | fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | |
678 | RQFCR_AND | RQFCR_HASHTBL_0; | 699 | RQFCR_AND | RQFCR_HASHTBL_0; |
679 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; | 700 | priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; |
680 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; | 701 | priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; |
681 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); | 702 | gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); |
@@ -683,7 +704,8 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) | |||
683 | } | 704 | } |
684 | } | 705 | } |
685 | 706 | ||
686 | static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class) | 707 | static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, |
708 | u64 class) | ||
687 | { | 709 | { |
688 | unsigned int last_rule_idx = priv->cur_filer_idx; | 710 | unsigned int last_rule_idx = priv->cur_filer_idx; |
689 | unsigned int cmp_rqfpr; | 711 | unsigned int cmp_rqfpr; |
@@ -694,9 +716,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u | |||
694 | int ret = 1; | 716 | int ret = 1; |
695 | 717 | ||
696 | local_rqfpr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), | 718 | local_rqfpr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), |
697 | GFP_KERNEL); | 719 | GFP_KERNEL); |
698 | local_rqfcr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), | 720 | local_rqfcr = kmalloc(sizeof(unsigned int) * (MAX_FILER_IDX + 1), |
699 | GFP_KERNEL); | 721 | GFP_KERNEL); |
700 | if (!local_rqfpr || !local_rqfcr) { | 722 | if (!local_rqfpr || !local_rqfcr) { |
701 | pr_err("Out of memory\n"); | 723 | pr_err("Out of memory\n"); |
702 | ret = 0; | 724 | ret = 0; |
@@ -726,9 +748,9 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u | |||
726 | local_rqfpr[j] = priv->ftp_rqfpr[i]; | 748 | local_rqfpr[j] = priv->ftp_rqfpr[i]; |
727 | local_rqfcr[j] = priv->ftp_rqfcr[i]; | 749 | local_rqfcr[j] = priv->ftp_rqfcr[i]; |
728 | j--; | 750 | j--; |
729 | if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE | | 751 | if ((priv->ftp_rqfcr[i] == |
730 | RQFCR_CLE |RQFCR_AND)) && | 752 | (RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND)) && |
731 | (priv->ftp_rqfpr[i] == cmp_rqfpr)) | 753 | (priv->ftp_rqfpr[i] == cmp_rqfpr)) |
732 | break; | 754 | break; |
733 | } | 755 | } |
734 | 756 | ||
@@ -743,12 +765,12 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u | |||
743 | */ | 765 | */ |
744 | for (l = i+1; l < MAX_FILER_IDX; l++) { | 766 | for (l = i+1; l < MAX_FILER_IDX; l++) { |
745 | if ((priv->ftp_rqfcr[l] & RQFCR_CLE) && | 767 | if ((priv->ftp_rqfcr[l] & RQFCR_CLE) && |
746 | !(priv->ftp_rqfcr[l] & RQFCR_AND)) { | 768 | !(priv->ftp_rqfcr[l] & RQFCR_AND)) { |
747 | priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | | 769 | priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | |
748 | RQFCR_HASHTBL_0 | RQFCR_PID_MASK; | 770 | RQFCR_HASHTBL_0 | RQFCR_PID_MASK; |
749 | priv->ftp_rqfpr[l] = FPR_FILER_MASK; | 771 | priv->ftp_rqfpr[l] = FPR_FILER_MASK; |
750 | gfar_write_filer(priv, l, priv->ftp_rqfcr[l], | 772 | gfar_write_filer(priv, l, priv->ftp_rqfcr[l], |
751 | priv->ftp_rqfpr[l]); | 773 | priv->ftp_rqfpr[l]); |
752 | break; | 774 | break; |
753 | } | 775 | } |
754 | 776 | ||
@@ -773,7 +795,7 @@ static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u | |||
773 | priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; | 795 | priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; |
774 | priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; | 796 | priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; |
775 | gfar_write_filer(priv, priv->cur_filer_idx, | 797 | gfar_write_filer(priv, priv->cur_filer_idx, |
776 | local_rqfcr[k], local_rqfpr[k]); | 798 | local_rqfcr[k], local_rqfpr[k]); |
777 | if (!priv->cur_filer_idx) | 799 | if (!priv->cur_filer_idx) |
778 | break; | 800 | break; |
779 | priv->cur_filer_idx = priv->cur_filer_idx - 1; | 801 | priv->cur_filer_idx = priv->cur_filer_idx - 1; |
@@ -785,7 +807,8 @@ err: | |||
785 | return ret; | 807 | return ret; |
786 | } | 808 | } |
787 | 809 | ||
788 | static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) | 810 | static int gfar_set_hash_opts(struct gfar_private *priv, |
811 | struct ethtool_rxnfc *cmd) | ||
789 | { | 812 | { |
790 | /* write the filer rules here */ | 813 | /* write the filer rules here */ |
791 | if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) | 814 | if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) |
@@ -810,10 +833,10 @@ static int gfar_check_filer_hardware(struct gfar_private *priv) | |||
810 | i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM; | 833 | i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM; |
811 | if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) { | 834 | if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) { |
812 | netdev_info(priv->ndev, | 835 | netdev_info(priv->ndev, |
813 | "Receive Queue Filtering enabled\n"); | 836 | "Receive Queue Filtering enabled\n"); |
814 | } else { | 837 | } else { |
815 | netdev_warn(priv->ndev, | 838 | netdev_warn(priv->ndev, |
816 | "Receive Queue Filtering disabled\n"); | 839 | "Receive Queue Filtering disabled\n"); |
817 | return -EOPNOTSUPP; | 840 | return -EOPNOTSUPP; |
818 | } | 841 | } |
819 | } | 842 | } |
@@ -823,16 +846,17 @@ static int gfar_check_filer_hardware(struct gfar_private *priv) | |||
823 | i &= RCTRL_PRSDEP_MASK; | 846 | i &= RCTRL_PRSDEP_MASK; |
824 | if (i == RCTRL_PRSDEP_MASK) { | 847 | if (i == RCTRL_PRSDEP_MASK) { |
825 | netdev_info(priv->ndev, | 848 | netdev_info(priv->ndev, |
826 | "Receive Queue Filtering enabled\n"); | 849 | "Receive Queue Filtering enabled\n"); |
827 | } else { | 850 | } else { |
828 | netdev_warn(priv->ndev, | 851 | netdev_warn(priv->ndev, |
829 | "Receive Queue Filtering disabled\n"); | 852 | "Receive Queue Filtering disabled\n"); |
830 | return -EOPNOTSUPP; | 853 | return -EOPNOTSUPP; |
831 | } | 854 | } |
832 | } | 855 | } |
833 | 856 | ||
834 | /* Sets the properties for arbitrary filer rule | 857 | /* Sets the properties for arbitrary filer rule |
835 | * to the first 4 Layer 4 Bytes */ | 858 | * to the first 4 Layer 4 Bytes |
859 | */ | ||
836 | regs->rbifx = 0xC0C1C2C3; | 860 | regs->rbifx = 0xC0C1C2C3; |
837 | return 0; | 861 | return 0; |
838 | } | 862 | } |
@@ -870,14 +894,14 @@ static void gfar_set_mask(u32 mask, struct filer_table *tab) | |||
870 | static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab) | 894 | static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab) |
871 | { | 895 | { |
872 | gfar_set_mask(mask, tab); | 896 | gfar_set_mask(mask, tab); |
873 | tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | 897 | tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | |
874 | | RQFCR_AND; | 898 | RQFCR_AND; |
875 | tab->fe[tab->index].prop = value; | 899 | tab->fe[tab->index].prop = value; |
876 | tab->index++; | 900 | tab->index++; |
877 | } | 901 | } |
878 | 902 | ||
879 | static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, | 903 | static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, |
880 | struct filer_table *tab) | 904 | struct filer_table *tab) |
881 | { | 905 | { |
882 | gfar_set_mask(mask, tab); | 906 | gfar_set_mask(mask, tab); |
883 | tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag; | 907 | tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag; |
@@ -885,8 +909,7 @@ static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, | |||
885 | tab->index++; | 909 | tab->index++; |
886 | } | 910 | } |
887 | 911 | ||
888 | /* | 912 | /* For setting a tuple of value and mask of type flag |
889 | * For setting a tuple of value and mask of type flag | ||
890 | * Example: | 913 | * Example: |
891 | * IP-Src = 10.0.0.0/255.0.0.0 | 914 | * IP-Src = 10.0.0.0/255.0.0.0 |
892 | * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4 | 915 | * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4 |
@@ -901,7 +924,7 @@ static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag, | |||
901 | * Further the all masks are one-padded for better hardware efficiency. | 924 | * Further the all masks are one-padded for better hardware efficiency. |
902 | */ | 925 | */ |
903 | static void gfar_set_attribute(u32 value, u32 mask, u32 flag, | 926 | static void gfar_set_attribute(u32 value, u32 mask, u32 flag, |
904 | struct filer_table *tab) | 927 | struct filer_table *tab) |
905 | { | 928 | { |
906 | switch (flag) { | 929 | switch (flag) { |
907 | /* 3bit */ | 930 | /* 3bit */ |
@@ -959,7 +982,8 @@ static void gfar_set_attribute(u32 value, u32 mask, u32 flag, | |||
959 | 982 | ||
960 | /* Translates value and mask for UDP, TCP or SCTP */ | 983 | /* Translates value and mask for UDP, TCP or SCTP */ |
961 | static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, | 984 | static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, |
962 | struct ethtool_tcpip4_spec *mask, struct filer_table *tab) | 985 | struct ethtool_tcpip4_spec *mask, |
986 | struct filer_table *tab) | ||
963 | { | 987 | { |
964 | gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); | 988 | gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); |
965 | gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); | 989 | gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); |
@@ -970,97 +994,92 @@ static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value, | |||
970 | 994 | ||
971 | /* Translates value and mask for RAW-IP4 */ | 995 | /* Translates value and mask for RAW-IP4 */ |
972 | static void gfar_set_user_ip(struct ethtool_usrip4_spec *value, | 996 | static void gfar_set_user_ip(struct ethtool_usrip4_spec *value, |
973 | struct ethtool_usrip4_spec *mask, struct filer_table *tab) | 997 | struct ethtool_usrip4_spec *mask, |
998 | struct filer_table *tab) | ||
974 | { | 999 | { |
975 | gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); | 1000 | gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab); |
976 | gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); | 1001 | gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab); |
977 | gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); | 1002 | gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab); |
978 | gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab); | 1003 | gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab); |
979 | gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB, | 1004 | gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB, |
980 | tab); | 1005 | tab); |
981 | 1006 | ||
982 | } | 1007 | } |
983 | 1008 | ||
984 | /* Translates value and mask for ETHER spec */ | 1009 | /* Translates value and mask for ETHER spec */ |
985 | static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask, | 1010 | static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask, |
986 | struct filer_table *tab) | 1011 | struct filer_table *tab) |
987 | { | 1012 | { |
988 | u32 upper_temp_mask = 0; | 1013 | u32 upper_temp_mask = 0; |
989 | u32 lower_temp_mask = 0; | 1014 | u32 lower_temp_mask = 0; |
1015 | |||
990 | /* Source address */ | 1016 | /* Source address */ |
991 | if (!is_broadcast_ether_addr(mask->h_source)) { | 1017 | if (!is_broadcast_ether_addr(mask->h_source)) { |
992 | |||
993 | if (is_zero_ether_addr(mask->h_source)) { | 1018 | if (is_zero_ether_addr(mask->h_source)) { |
994 | upper_temp_mask = 0xFFFFFFFF; | 1019 | upper_temp_mask = 0xFFFFFFFF; |
995 | lower_temp_mask = 0xFFFFFFFF; | 1020 | lower_temp_mask = 0xFFFFFFFF; |
996 | } else { | 1021 | } else { |
997 | upper_temp_mask = mask->h_source[0] << 16 | 1022 | upper_temp_mask = mask->h_source[0] << 16 | |
998 | | mask->h_source[1] << 8 | 1023 | mask->h_source[1] << 8 | |
999 | | mask->h_source[2]; | 1024 | mask->h_source[2]; |
1000 | lower_temp_mask = mask->h_source[3] << 16 | 1025 | lower_temp_mask = mask->h_source[3] << 16 | |
1001 | | mask->h_source[4] << 8 | 1026 | mask->h_source[4] << 8 | |
1002 | | mask->h_source[5]; | 1027 | mask->h_source[5]; |
1003 | } | 1028 | } |
1004 | /* Upper 24bit */ | 1029 | /* Upper 24bit */ |
1005 | gfar_set_attribute( | 1030 | gfar_set_attribute(value->h_source[0] << 16 | |
1006 | value->h_source[0] << 16 | value->h_source[1] | 1031 | value->h_source[1] << 8 | |
1007 | << 8 | value->h_source[2], | 1032 | value->h_source[2], |
1008 | upper_temp_mask, RQFCR_PID_SAH, tab); | 1033 | upper_temp_mask, RQFCR_PID_SAH, tab); |
1009 | /* And the same for the lower part */ | 1034 | /* And the same for the lower part */ |
1010 | gfar_set_attribute( | 1035 | gfar_set_attribute(value->h_source[3] << 16 | |
1011 | value->h_source[3] << 16 | value->h_source[4] | 1036 | value->h_source[4] << 8 | |
1012 | << 8 | value->h_source[5], | 1037 | value->h_source[5], |
1013 | lower_temp_mask, RQFCR_PID_SAL, tab); | 1038 | lower_temp_mask, RQFCR_PID_SAL, tab); |
1014 | } | 1039 | } |
1015 | /* Destination address */ | 1040 | /* Destination address */ |
1016 | if (!is_broadcast_ether_addr(mask->h_dest)) { | 1041 | if (!is_broadcast_ether_addr(mask->h_dest)) { |
1017 | |||
1018 | /* Special for destination is limited broadcast */ | 1042 | /* Special for destination is limited broadcast */ |
1019 | if ((is_broadcast_ether_addr(value->h_dest) | 1043 | if ((is_broadcast_ether_addr(value->h_dest) && |
1020 | && is_zero_ether_addr(mask->h_dest))) { | 1044 | is_zero_ether_addr(mask->h_dest))) { |
1021 | gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab); | 1045 | gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab); |
1022 | } else { | 1046 | } else { |
1023 | |||
1024 | if (is_zero_ether_addr(mask->h_dest)) { | 1047 | if (is_zero_ether_addr(mask->h_dest)) { |
1025 | upper_temp_mask = 0xFFFFFFFF; | 1048 | upper_temp_mask = 0xFFFFFFFF; |
1026 | lower_temp_mask = 0xFFFFFFFF; | 1049 | lower_temp_mask = 0xFFFFFFFF; |
1027 | } else { | 1050 | } else { |
1028 | upper_temp_mask = mask->h_dest[0] << 16 | 1051 | upper_temp_mask = mask->h_dest[0] << 16 | |
1029 | | mask->h_dest[1] << 8 | 1052 | mask->h_dest[1] << 8 | |
1030 | | mask->h_dest[2]; | 1053 | mask->h_dest[2]; |
1031 | lower_temp_mask = mask->h_dest[3] << 16 | 1054 | lower_temp_mask = mask->h_dest[3] << 16 | |
1032 | | mask->h_dest[4] << 8 | 1055 | mask->h_dest[4] << 8 | |
1033 | | mask->h_dest[5]; | 1056 | mask->h_dest[5]; |
1034 | } | 1057 | } |
1035 | 1058 | ||
1036 | /* Upper 24bit */ | 1059 | /* Upper 24bit */ |
1037 | gfar_set_attribute( | 1060 | gfar_set_attribute(value->h_dest[0] << 16 | |
1038 | value->h_dest[0] << 16 | 1061 | value->h_dest[1] << 8 | |
1039 | | value->h_dest[1] << 8 | 1062 | value->h_dest[2], |
1040 | | value->h_dest[2], | 1063 | upper_temp_mask, RQFCR_PID_DAH, tab); |
1041 | upper_temp_mask, RQFCR_PID_DAH, tab); | ||
1042 | /* And the same for the lower part */ | 1064 | /* And the same for the lower part */ |
1043 | gfar_set_attribute( | 1065 | gfar_set_attribute(value->h_dest[3] << 16 | |
1044 | value->h_dest[3] << 16 | 1066 | value->h_dest[4] << 8 | |
1045 | | value->h_dest[4] << 8 | 1067 | value->h_dest[5], |
1046 | | value->h_dest[5], | 1068 | lower_temp_mask, RQFCR_PID_DAL, tab); |
1047 | lower_temp_mask, RQFCR_PID_DAL, tab); | ||
1048 | } | 1069 | } |
1049 | } | 1070 | } |
1050 | 1071 | ||
1051 | gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab); | 1072 | gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab); |
1052 | |||
1053 | } | 1073 | } |
1054 | 1074 | ||
1055 | /* Convert a rule to binary filter format of gianfar */ | 1075 | /* Convert a rule to binary filter format of gianfar */ |
1056 | static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, | 1076 | static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, |
1057 | struct filer_table *tab) | 1077 | struct filer_table *tab) |
1058 | { | 1078 | { |
1059 | u32 vlan = 0, vlan_mask = 0; | 1079 | u32 vlan = 0, vlan_mask = 0; |
1060 | u32 id = 0, id_mask = 0; | 1080 | u32 id = 0, id_mask = 0; |
1061 | u32 cfi = 0, cfi_mask = 0; | 1081 | u32 cfi = 0, cfi_mask = 0; |
1062 | u32 prio = 0, prio_mask = 0; | 1082 | u32 prio = 0, prio_mask = 0; |
1063 | |||
1064 | u32 old_index = tab->index; | 1083 | u32 old_index = tab->index; |
1065 | 1084 | ||
1066 | /* Check if vlan is wanted */ | 1085 | /* Check if vlan is wanted */ |
@@ -1076,13 +1095,16 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, | |||
1076 | id_mask = rule->m_ext.vlan_tci & VLAN_VID_MASK; | 1095 | id_mask = rule->m_ext.vlan_tci & VLAN_VID_MASK; |
1077 | cfi = rule->h_ext.vlan_tci & VLAN_CFI_MASK; | 1096 | cfi = rule->h_ext.vlan_tci & VLAN_CFI_MASK; |
1078 | cfi_mask = rule->m_ext.vlan_tci & VLAN_CFI_MASK; | 1097 | cfi_mask = rule->m_ext.vlan_tci & VLAN_CFI_MASK; |
1079 | prio = (rule->h_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; | 1098 | prio = (rule->h_ext.vlan_tci & VLAN_PRIO_MASK) >> |
1080 | prio_mask = (rule->m_ext.vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; | 1099 | VLAN_PRIO_SHIFT; |
1100 | prio_mask = (rule->m_ext.vlan_tci & VLAN_PRIO_MASK) >> | ||
1101 | VLAN_PRIO_SHIFT; | ||
1081 | 1102 | ||
1082 | if (cfi == VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { | 1103 | if (cfi == VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { |
1083 | vlan |= RQFPR_CFI; | 1104 | vlan |= RQFPR_CFI; |
1084 | vlan_mask |= RQFPR_CFI; | 1105 | vlan_mask |= RQFPR_CFI; |
1085 | } else if (cfi != VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { | 1106 | } else if (cfi != VLAN_TAG_PRESENT && |
1107 | cfi_mask == VLAN_TAG_PRESENT) { | ||
1086 | vlan_mask |= RQFPR_CFI; | 1108 | vlan_mask |= RQFPR_CFI; |
1087 | } | 1109 | } |
1088 | } | 1110 | } |
@@ -1090,34 +1112,36 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, | |||
1090 | switch (rule->flow_type & ~FLOW_EXT) { | 1112 | switch (rule->flow_type & ~FLOW_EXT) { |
1091 | case TCP_V4_FLOW: | 1113 | case TCP_V4_FLOW: |
1092 | gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, | 1114 | gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan, |
1093 | RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); | 1115 | RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab); |
1094 | gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec, | 1116 | gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec, |
1095 | &rule->m_u.tcp_ip4_spec, tab); | 1117 | &rule->m_u.tcp_ip4_spec, tab); |
1096 | break; | 1118 | break; |
1097 | case UDP_V4_FLOW: | 1119 | case UDP_V4_FLOW: |
1098 | gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, | 1120 | gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan, |
1099 | RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); | 1121 | RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab); |
1100 | gfar_set_basic_ip(&rule->h_u.udp_ip4_spec, | 1122 | gfar_set_basic_ip(&rule->h_u.udp_ip4_spec, |
1101 | &rule->m_u.udp_ip4_spec, tab); | 1123 | &rule->m_u.udp_ip4_spec, tab); |
1102 | break; | 1124 | break; |
1103 | case SCTP_V4_FLOW: | 1125 | case SCTP_V4_FLOW: |
1104 | gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, | 1126 | gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, |
1105 | tab); | 1127 | tab); |
1106 | gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab); | 1128 | gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab); |
1107 | gfar_set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u, | 1129 | gfar_set_basic_ip((struct ethtool_tcpip4_spec *)&rule->h_u, |
1108 | (struct ethtool_tcpip4_spec *) &rule->m_u, tab); | 1130 | (struct ethtool_tcpip4_spec *)&rule->m_u, |
1131 | tab); | ||
1109 | break; | 1132 | break; |
1110 | case IP_USER_FLOW: | 1133 | case IP_USER_FLOW: |
1111 | gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, | 1134 | gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask, |
1112 | tab); | 1135 | tab); |
1113 | gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u, | 1136 | gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u, |
1114 | (struct ethtool_usrip4_spec *) &rule->m_u, tab); | 1137 | (struct ethtool_usrip4_spec *) &rule->m_u, |
1138 | tab); | ||
1115 | break; | 1139 | break; |
1116 | case ETHER_FLOW: | 1140 | case ETHER_FLOW: |
1117 | if (vlan) | 1141 | if (vlan) |
1118 | gfar_set_parse_bits(vlan, vlan_mask, tab); | 1142 | gfar_set_parse_bits(vlan, vlan_mask, tab); |
1119 | gfar_set_ether((struct ethhdr *) &rule->h_u, | 1143 | gfar_set_ether((struct ethhdr *) &rule->h_u, |
1120 | (struct ethhdr *) &rule->m_u, tab); | 1144 | (struct ethhdr *) &rule->m_u, tab); |
1121 | break; | 1145 | break; |
1122 | default: | 1146 | default: |
1123 | return -1; | 1147 | return -1; |
@@ -1152,7 +1176,9 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, | |||
1152 | tab->fe[tab->index - 1].ctrl |= RQFCR_CLE; | 1176 | tab->fe[tab->index - 1].ctrl |= RQFCR_CLE; |
1153 | } | 1177 | } |
1154 | 1178 | ||
1155 | /* In rare cases the cache can be full while there is free space in hw */ | 1179 | /* In rare cases the cache can be full while there is |
1180 | * free space in hw | ||
1181 | */ | ||
1156 | if (tab->index > MAX_FILER_CACHE_IDX - 1) | 1182 | if (tab->index > MAX_FILER_CACHE_IDX - 1) |
1157 | return -EBUSY; | 1183 | return -EBUSY; |
1158 | 1184 | ||
@@ -1161,7 +1187,7 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule, | |||
1161 | 1187 | ||
1162 | /* Copy size filer entries */ | 1188 | /* Copy size filer entries */ |
1163 | static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], | 1189 | static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], |
1164 | struct gfar_filer_entry src[0], s32 size) | 1190 | struct gfar_filer_entry src[0], s32 size) |
1165 | { | 1191 | { |
1166 | while (size > 0) { | 1192 | while (size > 0) { |
1167 | size--; | 1193 | size--; |
@@ -1171,10 +1197,12 @@ static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0], | |||
1171 | } | 1197 | } |
1172 | 1198 | ||
1173 | /* Delete the contents of the filer-table between start and end | 1199 | /* Delete the contents of the filer-table between start and end |
1174 | * and collapse them */ | 1200 | * and collapse them |
1201 | */ | ||
1175 | static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) | 1202 | static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) |
1176 | { | 1203 | { |
1177 | int length; | 1204 | int length; |
1205 | |||
1178 | if (end > MAX_FILER_CACHE_IDX || end < begin) | 1206 | if (end > MAX_FILER_CACHE_IDX || end < begin) |
1179 | return -EINVAL; | 1207 | return -EINVAL; |
1180 | 1208 | ||
@@ -1200,14 +1228,14 @@ static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab) | |||
1200 | 1228 | ||
1201 | /* Make space on the wanted location */ | 1229 | /* Make space on the wanted location */ |
1202 | static int gfar_expand_filer_entries(u32 begin, u32 length, | 1230 | static int gfar_expand_filer_entries(u32 begin, u32 length, |
1203 | struct filer_table *tab) | 1231 | struct filer_table *tab) |
1204 | { | 1232 | { |
1205 | if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || begin | 1233 | if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || |
1206 | > MAX_FILER_CACHE_IDX) | 1234 | begin > MAX_FILER_CACHE_IDX) |
1207 | return -EINVAL; | 1235 | return -EINVAL; |
1208 | 1236 | ||
1209 | gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]), | 1237 | gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]), |
1210 | tab->index - length + 1); | 1238 | tab->index - length + 1); |
1211 | 1239 | ||
1212 | tab->index += length; | 1240 | tab->index += length; |
1213 | return 0; | 1241 | return 0; |
@@ -1215,9 +1243,10 @@ static int gfar_expand_filer_entries(u32 begin, u32 length, | |||
1215 | 1243 | ||
1216 | static int gfar_get_next_cluster_start(int start, struct filer_table *tab) | 1244 | static int gfar_get_next_cluster_start(int start, struct filer_table *tab) |
1217 | { | 1245 | { |
1218 | for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { | 1246 | for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); |
1219 | if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) | 1247 | start++) { |
1220 | == (RQFCR_AND | RQFCR_CLE)) | 1248 | if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) == |
1249 | (RQFCR_AND | RQFCR_CLE)) | ||
1221 | return start; | 1250 | return start; |
1222 | } | 1251 | } |
1223 | return -1; | 1252 | return -1; |
@@ -1225,16 +1254,16 @@ static int gfar_get_next_cluster_start(int start, struct filer_table *tab) | |||
1225 | 1254 | ||
1226 | static int gfar_get_next_cluster_end(int start, struct filer_table *tab) | 1255 | static int gfar_get_next_cluster_end(int start, struct filer_table *tab) |
1227 | { | 1256 | { |
1228 | for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) { | 1257 | for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); |
1229 | if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) | 1258 | start++) { |
1230 | == (RQFCR_CLE)) | 1259 | if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) == |
1260 | (RQFCR_CLE)) | ||
1231 | return start; | 1261 | return start; |
1232 | } | 1262 | } |
1233 | return -1; | 1263 | return -1; |
1234 | } | 1264 | } |
1235 | 1265 | ||
1236 | /* | 1266 | /* Uses hardwares clustering option to reduce |
1237 | * Uses hardwares clustering option to reduce | ||
1238 | * the number of filer table entries | 1267 | * the number of filer table entries |
1239 | */ | 1268 | */ |
1240 | static void gfar_cluster_filer(struct filer_table *tab) | 1269 | static void gfar_cluster_filer(struct filer_table *tab) |
@@ -1244,8 +1273,7 @@ static void gfar_cluster_filer(struct filer_table *tab) | |||
1244 | while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) { | 1273 | while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) { |
1245 | j = i; | 1274 | j = i; |
1246 | while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) { | 1275 | while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) { |
1247 | /* | 1276 | /* The cluster entries self and the previous one |
1248 | * The cluster entries self and the previous one | ||
1249 | * (a mask) must be identical! | 1277 | * (a mask) must be identical! |
1250 | */ | 1278 | */ |
1251 | if (tab->fe[i].ctrl != tab->fe[j].ctrl) | 1279 | if (tab->fe[i].ctrl != tab->fe[j].ctrl) |
@@ -1260,21 +1288,21 @@ static void gfar_cluster_filer(struct filer_table *tab) | |||
1260 | jend = gfar_get_next_cluster_end(j, tab); | 1288 | jend = gfar_get_next_cluster_end(j, tab); |
1261 | if (jend == -1 || iend == -1) | 1289 | if (jend == -1 || iend == -1) |
1262 | break; | 1290 | break; |
1263 | /* | 1291 | |
1264 | * First we make some free space, where our cluster | 1292 | /* First we make some free space, where our cluster |
1265 | * element should be. Then we copy it there and finally | 1293 | * element should be. Then we copy it there and finally |
1266 | * delete in from its old location. | 1294 | * delete in from its old location. |
1267 | */ | 1295 | */ |
1268 | 1296 | if (gfar_expand_filer_entries(iend, (jend - j), tab) == | |
1269 | if (gfar_expand_filer_entries(iend, (jend - j), tab) | 1297 | -EINVAL) |
1270 | == -EINVAL) | ||
1271 | break; | 1298 | break; |
1272 | 1299 | ||
1273 | gfar_copy_filer_entries(&(tab->fe[iend + 1]), | 1300 | gfar_copy_filer_entries(&(tab->fe[iend + 1]), |
1274 | &(tab->fe[jend + 1]), jend - j); | 1301 | &(tab->fe[jend + 1]), jend - j); |
1275 | 1302 | ||
1276 | if (gfar_trim_filer_entries(jend - 1, | 1303 | if (gfar_trim_filer_entries(jend - 1, |
1277 | jend + (jend - j), tab) == -EINVAL) | 1304 | jend + (jend - j), |
1305 | tab) == -EINVAL) | ||
1278 | return; | 1306 | return; |
1279 | 1307 | ||
1280 | /* Mask out cluster bit */ | 1308 | /* Mask out cluster bit */ |
@@ -1285,8 +1313,9 @@ static void gfar_cluster_filer(struct filer_table *tab) | |||
1285 | 1313 | ||
1286 | /* Swaps the masked bits of a1<>a2 and b1<>b2 */ | 1314 | /* Swaps the masked bits of a1<>a2 and b1<>b2 */ |
1287 | static void gfar_swap_bits(struct gfar_filer_entry *a1, | 1315 | static void gfar_swap_bits(struct gfar_filer_entry *a1, |
1288 | struct gfar_filer_entry *a2, struct gfar_filer_entry *b1, | 1316 | struct gfar_filer_entry *a2, |
1289 | struct gfar_filer_entry *b2, u32 mask) | 1317 | struct gfar_filer_entry *b1, |
1318 | struct gfar_filer_entry *b2, u32 mask) | ||
1290 | { | 1319 | { |
1291 | u32 temp[4]; | 1320 | u32 temp[4]; |
1292 | temp[0] = a1->ctrl & mask; | 1321 | temp[0] = a1->ctrl & mask; |
@@ -1305,13 +1334,12 @@ static void gfar_swap_bits(struct gfar_filer_entry *a1, | |||
1305 | b2->ctrl |= temp[2]; | 1334 | b2->ctrl |= temp[2]; |
1306 | } | 1335 | } |
1307 | 1336 | ||
1308 | /* | 1337 | /* Generate a list consisting of masks values with their start and |
1309 | * Generate a list consisting of masks values with their start and | ||
1310 | * end of validity and block as indicator for parts belonging | 1338 | * end of validity and block as indicator for parts belonging |
1311 | * together (glued by ANDs) in mask_table | 1339 | * together (glued by ANDs) in mask_table |
1312 | */ | 1340 | */ |
1313 | static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, | 1341 | static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, |
1314 | struct filer_table *tab) | 1342 | struct filer_table *tab) |
1315 | { | 1343 | { |
1316 | u32 i, and_index = 0, block_index = 1; | 1344 | u32 i, and_index = 0, block_index = 1; |
1317 | 1345 | ||
@@ -1327,13 +1355,13 @@ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, | |||
1327 | and_index++; | 1355 | and_index++; |
1328 | } | 1356 | } |
1329 | /* cluster starts and ends will be separated because they should | 1357 | /* cluster starts and ends will be separated because they should |
1330 | * hold their position */ | 1358 | * hold their position |
1359 | */ | ||
1331 | if (tab->fe[i].ctrl & RQFCR_CLE) | 1360 | if (tab->fe[i].ctrl & RQFCR_CLE) |
1332 | block_index++; | 1361 | block_index++; |
1333 | /* A not set AND indicates the end of a depended block */ | 1362 | /* A not set AND indicates the end of a depended block */ |
1334 | if (!(tab->fe[i].ctrl & RQFCR_AND)) | 1363 | if (!(tab->fe[i].ctrl & RQFCR_AND)) |
1335 | block_index++; | 1364 | block_index++; |
1336 | |||
1337 | } | 1365 | } |
1338 | 1366 | ||
1339 | mask_table[and_index - 1].end = i - 1; | 1367 | mask_table[and_index - 1].end = i - 1; |
@@ -1341,14 +1369,13 @@ static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table, | |||
1341 | return and_index; | 1369 | return and_index; |
1342 | } | 1370 | } |
1343 | 1371 | ||
1344 | /* | 1372 | /* Sorts the entries of mask_table by the values of the masks. |
1345 | * Sorts the entries of mask_table by the values of the masks. | ||
1346 | * Important: The 0xFF80 flags of the first and last entry of a | 1373 | * Important: The 0xFF80 flags of the first and last entry of a |
1347 | * block must hold their position (which queue, CLusterEnable, ReJEct, | 1374 | * block must hold their position (which queue, CLusterEnable, ReJEct, |
1348 | * AND) | 1375 | * AND) |
1349 | */ | 1376 | */ |
1350 | static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, | 1377 | static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, |
1351 | struct filer_table *temp_table, u32 and_index) | 1378 | struct filer_table *temp_table, u32 and_index) |
1352 | { | 1379 | { |
1353 | /* Pointer to compare function (_asc or _desc) */ | 1380 | /* Pointer to compare function (_asc or _desc) */ |
1354 | int (*gfar_comp)(const void *, const void *); | 1381 | int (*gfar_comp)(const void *, const void *); |
@@ -1359,16 +1386,16 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, | |||
1359 | gfar_comp = &gfar_comp_desc; | 1386 | gfar_comp = &gfar_comp_desc; |
1360 | 1387 | ||
1361 | for (i = 0; i < and_index; i++) { | 1388 | for (i = 0; i < and_index; i++) { |
1362 | |||
1363 | if (prev != mask_table[i].block) { | 1389 | if (prev != mask_table[i].block) { |
1364 | old_first = mask_table[start].start + 1; | 1390 | old_first = mask_table[start].start + 1; |
1365 | old_last = mask_table[i - 1].end; | 1391 | old_last = mask_table[i - 1].end; |
1366 | sort(mask_table + start, size, | 1392 | sort(mask_table + start, size, |
1367 | sizeof(struct gfar_mask_entry), | 1393 | sizeof(struct gfar_mask_entry), |
1368 | gfar_comp, &gfar_swap); | 1394 | gfar_comp, &gfar_swap); |
1369 | 1395 | ||
1370 | /* Toggle order for every block. This makes the | 1396 | /* Toggle order for every block. This makes the |
1371 | * thing more efficient! */ | 1397 | * thing more efficient! |
1398 | */ | ||
1372 | if (gfar_comp == gfar_comp_desc) | 1399 | if (gfar_comp == gfar_comp_desc) |
1373 | gfar_comp = &gfar_comp_asc; | 1400 | gfar_comp = &gfar_comp_asc; |
1374 | else | 1401 | else |
@@ -1378,12 +1405,11 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, | |||
1378 | new_last = mask_table[i - 1].end; | 1405 | new_last = mask_table[i - 1].end; |
1379 | 1406 | ||
1380 | gfar_swap_bits(&temp_table->fe[new_first], | 1407 | gfar_swap_bits(&temp_table->fe[new_first], |
1381 | &temp_table->fe[old_first], | 1408 | &temp_table->fe[old_first], |
1382 | &temp_table->fe[new_last], | 1409 | &temp_table->fe[new_last], |
1383 | &temp_table->fe[old_last], | 1410 | &temp_table->fe[old_last], |
1384 | RQFCR_QUEUE | RQFCR_CLE | | 1411 | RQFCR_QUEUE | RQFCR_CLE | |
1385 | RQFCR_RJE | RQFCR_AND | 1412 | RQFCR_RJE | RQFCR_AND); |
1386 | ); | ||
1387 | 1413 | ||
1388 | start = i; | 1414 | start = i; |
1389 | size = 0; | 1415 | size = 0; |
@@ -1391,11 +1417,9 @@ static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table, | |||
1391 | size++; | 1417 | size++; |
1392 | prev = mask_table[i].block; | 1418 | prev = mask_table[i].block; |
1393 | } | 1419 | } |
1394 | |||
1395 | } | 1420 | } |
1396 | 1421 | ||
1397 | /* | 1422 | /* Reduces the number of masks needed in the filer table to save entries |
1398 | * Reduces the number of masks needed in the filer table to save entries | ||
1399 | * This is done by sorting the masks of a depended block. A depended block is | 1423 | * This is done by sorting the masks of a depended block. A depended block is |
1400 | * identified by gluing ANDs or CLE. The sorting order toggles after every | 1424 | * identified by gluing ANDs or CLE. The sorting order toggles after every |
1401 | * block. Of course entries in scope of a mask must change their location with | 1425 | * block. Of course entries in scope of a mask must change their location with |
@@ -1410,13 +1434,14 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) | |||
1410 | s32 ret = 0; | 1434 | s32 ret = 0; |
1411 | 1435 | ||
1412 | /* We need a copy of the filer table because | 1436 | /* We need a copy of the filer table because |
1413 | * we want to change its order */ | 1437 | * we want to change its order |
1438 | */ | ||
1414 | temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL); | 1439 | temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL); |
1415 | if (temp_table == NULL) | 1440 | if (temp_table == NULL) |
1416 | return -ENOMEM; | 1441 | return -ENOMEM; |
1417 | 1442 | ||
1418 | mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, | 1443 | mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1, |
1419 | sizeof(struct gfar_mask_entry), GFP_KERNEL); | 1444 | sizeof(struct gfar_mask_entry), GFP_KERNEL); |
1420 | 1445 | ||
1421 | if (mask_table == NULL) { | 1446 | if (mask_table == NULL) { |
1422 | ret = -ENOMEM; | 1447 | ret = -ENOMEM; |
@@ -1428,7 +1453,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) | |||
1428 | gfar_sort_mask_table(mask_table, temp_table, and_index); | 1453 | gfar_sort_mask_table(mask_table, temp_table, and_index); |
1429 | 1454 | ||
1430 | /* Now we can copy the data from our duplicated filer table to | 1455 | /* Now we can copy the data from our duplicated filer table to |
1431 | * the real one in the order the mask table says */ | 1456 | * the real one in the order the mask table says |
1457 | */ | ||
1432 | for (i = 0; i < and_index; i++) { | 1458 | for (i = 0; i < and_index; i++) { |
1433 | size = mask_table[i].end - mask_table[i].start + 1; | 1459 | size = mask_table[i].end - mask_table[i].start + 1; |
1434 | gfar_copy_filer_entries(&(tab->fe[j]), | 1460 | gfar_copy_filer_entries(&(tab->fe[j]), |
@@ -1437,7 +1463,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) | |||
1437 | } | 1463 | } |
1438 | 1464 | ||
1439 | /* And finally we just have to check for duplicated masks and drop the | 1465 | /* And finally we just have to check for duplicated masks and drop the |
1440 | * second ones */ | 1466 | * second ones |
1467 | */ | ||
1441 | for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { | 1468 | for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) { |
1442 | if (tab->fe[i].ctrl == 0x80) { | 1469 | if (tab->fe[i].ctrl == 0x80) { |
1443 | previous_mask = i++; | 1470 | previous_mask = i++; |
@@ -1448,7 +1475,8 @@ static int gfar_optimize_filer_masks(struct filer_table *tab) | |||
1448 | if (tab->fe[i].ctrl == 0x80) { | 1475 | if (tab->fe[i].ctrl == 0x80) { |
1449 | if (tab->fe[i].prop == tab->fe[previous_mask].prop) { | 1476 | if (tab->fe[i].prop == tab->fe[previous_mask].prop) { |
1450 | /* Two identical ones found! | 1477 | /* Two identical ones found! |
1451 | * So drop the second one! */ | 1478 | * So drop the second one! |
1479 | */ | ||
1452 | gfar_trim_filer_entries(i, i, tab); | 1480 | gfar_trim_filer_entries(i, i, tab); |
1453 | } else | 1481 | } else |
1454 | /* Not identical! */ | 1482 | /* Not identical! */ |
@@ -1463,7 +1491,7 @@ end: kfree(temp_table); | |||
1463 | 1491 | ||
1464 | /* Write the bit-pattern from software's buffer to hardware registers */ | 1492 | /* Write the bit-pattern from software's buffer to hardware registers */ |
1465 | static int gfar_write_filer_table(struct gfar_private *priv, | 1493 | static int gfar_write_filer_table(struct gfar_private *priv, |
1466 | struct filer_table *tab) | 1494 | struct filer_table *tab) |
1467 | { | 1495 | { |
1468 | u32 i = 0; | 1496 | u32 i = 0; |
1469 | if (tab->index > MAX_FILER_IDX - 1) | 1497 | if (tab->index > MAX_FILER_IDX - 1) |
@@ -1473,13 +1501,15 @@ static int gfar_write_filer_table(struct gfar_private *priv, | |||
1473 | lock_rx_qs(priv); | 1501 | lock_rx_qs(priv); |
1474 | 1502 | ||
1475 | /* Fill regular entries */ | 1503 | /* Fill regular entries */ |
1476 | for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); i++) | 1504 | for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); |
1505 | i++) | ||
1477 | gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop); | 1506 | gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop); |
1478 | /* Fill the rest with fall-troughs */ | 1507 | /* Fill the rest with fall-troughs */ |
1479 | for (; i < MAX_FILER_IDX - 1; i++) | 1508 | for (; i < MAX_FILER_IDX - 1; i++) |
1480 | gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF); | 1509 | gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF); |
1481 | /* Last entry must be default accept | 1510 | /* Last entry must be default accept |
1482 | * because that's what people expect */ | 1511 | * because that's what people expect |
1512 | */ | ||
1483 | gfar_write_filer(priv, i, 0x20, 0x0); | 1513 | gfar_write_filer(priv, i, 0x20, 0x0); |
1484 | 1514 | ||
1485 | unlock_rx_qs(priv); | 1515 | unlock_rx_qs(priv); |
@@ -1488,21 +1518,21 @@ static int gfar_write_filer_table(struct gfar_private *priv, | |||
1488 | } | 1518 | } |
1489 | 1519 | ||
1490 | static int gfar_check_capability(struct ethtool_rx_flow_spec *flow, | 1520 | static int gfar_check_capability(struct ethtool_rx_flow_spec *flow, |
1491 | struct gfar_private *priv) | 1521 | struct gfar_private *priv) |
1492 | { | 1522 | { |
1493 | 1523 | ||
1494 | if (flow->flow_type & FLOW_EXT) { | 1524 | if (flow->flow_type & FLOW_EXT) { |
1495 | if (~flow->m_ext.data[0] || ~flow->m_ext.data[1]) | 1525 | if (~flow->m_ext.data[0] || ~flow->m_ext.data[1]) |
1496 | netdev_warn(priv->ndev, | 1526 | netdev_warn(priv->ndev, |
1497 | "User-specific data not supported!\n"); | 1527 | "User-specific data not supported!\n"); |
1498 | if (~flow->m_ext.vlan_etype) | 1528 | if (~flow->m_ext.vlan_etype) |
1499 | netdev_warn(priv->ndev, | 1529 | netdev_warn(priv->ndev, |
1500 | "VLAN-etype not supported!\n"); | 1530 | "VLAN-etype not supported!\n"); |
1501 | } | 1531 | } |
1502 | if (flow->flow_type == IP_USER_FLOW) | 1532 | if (flow->flow_type == IP_USER_FLOW) |
1503 | if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4) | 1533 | if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4) |
1504 | netdev_warn(priv->ndev, | 1534 | netdev_warn(priv->ndev, |
1505 | "IP-Version differing from IPv4 not supported!\n"); | 1535 | "IP-Version differing from IPv4 not supported!\n"); |
1506 | 1536 | ||
1507 | return 0; | 1537 | return 0; |
1508 | } | 1538 | } |
@@ -1520,15 +1550,18 @@ static int gfar_process_filer_changes(struct gfar_private *priv) | |||
1520 | return -ENOMEM; | 1550 | return -ENOMEM; |
1521 | 1551 | ||
1522 | /* Now convert the existing filer data from flow_spec into | 1552 | /* Now convert the existing filer data from flow_spec into |
1523 | * filer tables binary format */ | 1553 | * filer tables binary format |
1554 | */ | ||
1524 | list_for_each_entry(j, &priv->rx_list.list, list) { | 1555 | list_for_each_entry(j, &priv->rx_list.list, list) { |
1525 | ret = gfar_convert_to_filer(&j->fs, tab); | 1556 | ret = gfar_convert_to_filer(&j->fs, tab); |
1526 | if (ret == -EBUSY) { | 1557 | if (ret == -EBUSY) { |
1527 | netdev_err(priv->ndev, "Rule not added: No free space!\n"); | 1558 | netdev_err(priv->ndev, |
1559 | "Rule not added: No free space!\n"); | ||
1528 | goto end; | 1560 | goto end; |
1529 | } | 1561 | } |
1530 | if (ret == -1) { | 1562 | if (ret == -1) { |
1531 | netdev_err(priv->ndev, "Rule not added: Unsupported Flow-type!\n"); | 1563 | netdev_err(priv->ndev, |
1564 | "Rule not added: Unsupported Flow-type!\n"); | ||
1532 | goto end; | 1565 | goto end; |
1533 | } | 1566 | } |
1534 | } | 1567 | } |
@@ -1540,9 +1573,9 @@ static int gfar_process_filer_changes(struct gfar_private *priv) | |||
1540 | gfar_optimize_filer_masks(tab); | 1573 | gfar_optimize_filer_masks(tab); |
1541 | 1574 | ||
1542 | pr_debug("\n\tSummary:\n" | 1575 | pr_debug("\n\tSummary:\n" |
1543 | "\tData on hardware: %d\n" | 1576 | "\tData on hardware: %d\n" |
1544 | "\tCompression rate: %d%%\n", | 1577 | "\tCompression rate: %d%%\n", |
1545 | tab->index, 100 - (100 * tab->index) / i); | 1578 | tab->index, 100 - (100 * tab->index) / i); |
1546 | 1579 | ||
1547 | /* Write everything to hardware */ | 1580 | /* Write everything to hardware */ |
1548 | ret = gfar_write_filer_table(priv, tab); | 1581 | ret = gfar_write_filer_table(priv, tab); |
@@ -1551,7 +1584,8 @@ static int gfar_process_filer_changes(struct gfar_private *priv) | |||
1551 | goto end; | 1584 | goto end; |
1552 | } | 1585 | } |
1553 | 1586 | ||
1554 | end: kfree(tab); | 1587 | end: |
1588 | kfree(tab); | ||
1555 | return ret; | 1589 | return ret; |
1556 | } | 1590 | } |
1557 | 1591 | ||
@@ -1569,7 +1603,7 @@ static void gfar_invert_masks(struct ethtool_rx_flow_spec *flow) | |||
1569 | } | 1603 | } |
1570 | 1604 | ||
1571 | static int gfar_add_cls(struct gfar_private *priv, | 1605 | static int gfar_add_cls(struct gfar_private *priv, |
1572 | struct ethtool_rx_flow_spec *flow) | 1606 | struct ethtool_rx_flow_spec *flow) |
1573 | { | 1607 | { |
1574 | struct ethtool_flow_spec_container *temp, *comp; | 1608 | struct ethtool_flow_spec_container *temp, *comp; |
1575 | int ret = 0; | 1609 | int ret = 0; |
@@ -1591,7 +1625,6 @@ static int gfar_add_cls(struct gfar_private *priv, | |||
1591 | list_add(&temp->list, &priv->rx_list.list); | 1625 | list_add(&temp->list, &priv->rx_list.list); |
1592 | goto process; | 1626 | goto process; |
1593 | } else { | 1627 | } else { |
1594 | |||
1595 | list_for_each_entry(comp, &priv->rx_list.list, list) { | 1628 | list_for_each_entry(comp, &priv->rx_list.list, list) { |
1596 | if (comp->fs.location > flow->location) { | 1629 | if (comp->fs.location > flow->location) { |
1597 | list_add_tail(&temp->list, &comp->list); | 1630 | list_add_tail(&temp->list, &comp->list); |
@@ -1599,8 +1632,8 @@ static int gfar_add_cls(struct gfar_private *priv, | |||
1599 | } | 1632 | } |
1600 | if (comp->fs.location == flow->location) { | 1633 | if (comp->fs.location == flow->location) { |
1601 | netdev_err(priv->ndev, | 1634 | netdev_err(priv->ndev, |
1602 | "Rule not added: ID %d not free!\n", | 1635 | "Rule not added: ID %d not free!\n", |
1603 | flow->location); | 1636 | flow->location); |
1604 | ret = -EBUSY; | 1637 | ret = -EBUSY; |
1605 | goto clean_mem; | 1638 | goto clean_mem; |
1606 | } | 1639 | } |
@@ -1642,7 +1675,6 @@ static int gfar_del_cls(struct gfar_private *priv, u32 loc) | |||
1642 | } | 1675 | } |
1643 | 1676 | ||
1644 | return ret; | 1677 | return ret; |
1645 | |||
1646 | } | 1678 | } |
1647 | 1679 | ||
1648 | static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) | 1680 | static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) |
@@ -1663,7 +1695,7 @@ static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd) | |||
1663 | } | 1695 | } |
1664 | 1696 | ||
1665 | static int gfar_get_cls_all(struct gfar_private *priv, | 1697 | static int gfar_get_cls_all(struct gfar_private *priv, |
1666 | struct ethtool_rxnfc *cmd, u32 *rule_locs) | 1698 | struct ethtool_rxnfc *cmd, u32 *rule_locs) |
1667 | { | 1699 | { |
1668 | struct ethtool_flow_spec_container *comp; | 1700 | struct ethtool_flow_spec_container *comp; |
1669 | u32 i = 0; | 1701 | u32 i = 0; |
@@ -1714,7 +1746,7 @@ static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) | |||
1714 | } | 1746 | } |
1715 | 1747 | ||
1716 | static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | 1748 | static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, |
1717 | u32 *rule_locs) | 1749 | u32 *rule_locs) |
1718 | { | 1750 | { |
1719 | struct gfar_private *priv = netdev_priv(dev); | 1751 | struct gfar_private *priv = netdev_priv(dev); |
1720 | int ret = 0; | 1752 | int ret = 0; |
@@ -1748,23 +1780,19 @@ static int gfar_get_ts_info(struct net_device *dev, | |||
1748 | struct gfar_private *priv = netdev_priv(dev); | 1780 | struct gfar_private *priv = netdev_priv(dev); |
1749 | 1781 | ||
1750 | if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)) { | 1782 | if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)) { |
1751 | info->so_timestamping = | 1783 | info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | |
1752 | SOF_TIMESTAMPING_RX_SOFTWARE | | 1784 | SOF_TIMESTAMPING_SOFTWARE; |
1753 | SOF_TIMESTAMPING_SOFTWARE; | ||
1754 | info->phc_index = -1; | 1785 | info->phc_index = -1; |
1755 | return 0; | 1786 | return 0; |
1756 | } | 1787 | } |
1757 | info->so_timestamping = | 1788 | info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | |
1758 | SOF_TIMESTAMPING_TX_HARDWARE | | 1789 | SOF_TIMESTAMPING_RX_HARDWARE | |
1759 | SOF_TIMESTAMPING_RX_HARDWARE | | 1790 | SOF_TIMESTAMPING_RAW_HARDWARE; |
1760 | SOF_TIMESTAMPING_RAW_HARDWARE; | ||
1761 | info->phc_index = gfar_phc_index; | 1791 | info->phc_index = gfar_phc_index; |
1762 | info->tx_types = | 1792 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | |
1763 | (1 << HWTSTAMP_TX_OFF) | | 1793 | (1 << HWTSTAMP_TX_ON); |
1764 | (1 << HWTSTAMP_TX_ON); | 1794 | info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | |
1765 | info->rx_filters = | 1795 | (1 << HWTSTAMP_FILTER_ALL); |
1766 | (1 << HWTSTAMP_FILTER_NONE) | | ||
1767 | (1 << HWTSTAMP_FILTER_ALL); | ||
1768 | return 0; | 1796 | return 0; |
1769 | } | 1797 | } |
1770 | 1798 | ||
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 9ac14f804851..21c6574c5f15 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c | |||
@@ -185,7 +185,7 @@ static void mem_disp(u8 *addr, int size) | |||
185 | for (; (u32) i < (u32) addr + size4Aling; i += 4) | 185 | for (; (u32) i < (u32) addr + size4Aling; i += 4) |
186 | printk("%08x ", *((u32 *) (i))); | 186 | printk("%08x ", *((u32 *) (i))); |
187 | for (; (u32) i < (u32) addr + size; i++) | 187 | for (; (u32) i < (u32) addr + size; i++) |
188 | printk("%02x", *((u8 *) (i))); | 188 | printk("%02x", *((i))); |
189 | if (notAlign == 1) | 189 | if (notAlign == 1) |
190 | printk("\r\n"); | 190 | printk("\r\n"); |
191 | } | 191 | } |
diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index d496673f0908..3f4391bede81 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c | |||
@@ -1217,7 +1217,7 @@ static int hp100_init_rxpdl(struct net_device *dev, | |||
1217 | 1217 | ||
1218 | ringptr->pdl = pdlptr + 1; | 1218 | ringptr->pdl = pdlptr + 1; |
1219 | ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1); | 1219 | ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1); |
1220 | ringptr->skb = (void *) NULL; | 1220 | ringptr->skb = NULL; |
1221 | 1221 | ||
1222 | /* | 1222 | /* |
1223 | * Write address and length of first PDL Fragment (which is used for | 1223 | * Write address and length of first PDL Fragment (which is used for |
@@ -1243,7 +1243,7 @@ static int hp100_init_txpdl(struct net_device *dev, | |||
1243 | 1243 | ||
1244 | ringptr->pdl = pdlptr; /* +1; */ | 1244 | ringptr->pdl = pdlptr; /* +1; */ |
1245 | ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */ | 1245 | ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr); /* +1 */ |
1246 | ringptr->skb = (void *) NULL; | 1246 | ringptr->skb = NULL; |
1247 | 1247 | ||
1248 | return roundup(MAX_TX_FRAG * 2 + 2, 4); | 1248 | return roundup(MAX_TX_FRAG * 2 + 2, 4); |
1249 | } | 1249 | } |
@@ -1628,7 +1628,7 @@ static void hp100_clean_txring(struct net_device *dev) | |||
1628 | /* Conversion to new PCI API : NOP */ | 1628 | /* Conversion to new PCI API : NOP */ |
1629 | pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE); | 1629 | pci_unmap_single(lp->pci_dev, (dma_addr_t) lp->txrhead->pdl[1], lp->txrhead->pdl[2], PCI_DMA_TODEVICE); |
1630 | dev_kfree_skb_any(lp->txrhead->skb); | 1630 | dev_kfree_skb_any(lp->txrhead->skb); |
1631 | lp->txrhead->skb = (void *) NULL; | 1631 | lp->txrhead->skb = NULL; |
1632 | lp->txrhead = lp->txrhead->next; | 1632 | lp->txrhead = lp->txrhead->next; |
1633 | lp->txrcommit--; | 1633 | lp->txrcommit--; |
1634 | } | 1634 | } |
diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 6c2952c8ea15..3735bfa53600 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c | |||
@@ -629,10 +629,10 @@ init_i596(struct net_device *dev) { | |||
629 | 629 | ||
630 | memcpy ((void *)lp->eth_addr, dev->dev_addr, 6); | 630 | memcpy ((void *)lp->eth_addr, dev->dev_addr, 6); |
631 | lp->set_add.command = CmdIASetup; | 631 | lp->set_add.command = CmdIASetup; |
632 | i596_add_cmd(dev, (struct i596_cmd *)&lp->set_add); | 632 | i596_add_cmd(dev, &lp->set_add); |
633 | 633 | ||
634 | lp->tdr.command = CmdTDR; | 634 | lp->tdr.command = CmdTDR; |
635 | i596_add_cmd(dev, (struct i596_cmd *)&lp->tdr); | 635 | i596_add_cmd(dev, &lp->tdr); |
636 | 636 | ||
637 | if (lp->scb.command && i596_timeout(dev, "i82596 init", 200)) | 637 | if (lp->scb.command && i596_timeout(dev, "i82596 init", 200)) |
638 | return 1; | 638 | return 1; |
@@ -737,7 +737,7 @@ i596_cleanup_cmd(struct net_device *dev) { | |||
737 | 737 | ||
738 | lp = netdev_priv(dev); | 738 | lp = netdev_priv(dev); |
739 | while (lp->cmd_head) { | 739 | while (lp->cmd_head) { |
740 | cmd = (struct i596_cmd *)lp->cmd_head; | 740 | cmd = lp->cmd_head; |
741 | 741 | ||
742 | lp->cmd_head = pa_to_va(lp->cmd_head->pa_next); | 742 | lp->cmd_head = pa_to_va(lp->cmd_head->pa_next); |
743 | lp->cmd_backlog--; | 743 | lp->cmd_backlog--; |
@@ -1281,7 +1281,7 @@ static void set_multicast_list(struct net_device *dev) { | |||
1281 | lp->i596_config[8] |= 0x01; | 1281 | lp->i596_config[8] |= 0x01; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | i596_add_cmd(dev, (struct i596_cmd *) &lp->set_conf); | 1284 | i596_add_cmd(dev, &lp->set_conf); |
1285 | } | 1285 | } |
1286 | } | 1286 | } |
1287 | 1287 | ||
diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index cae17f4bc93e..353f57f675d0 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c | |||
@@ -571,7 +571,7 @@ static int init586(struct net_device *dev) | |||
571 | } | 571 | } |
572 | #endif | 572 | #endif |
573 | 573 | ||
574 | ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ | 574 | ptr = alloc_rfa(dev,ptr); /* init receive-frame-area */ |
575 | 575 | ||
576 | /* | 576 | /* |
577 | * alloc xmit-buffs / init xmit_cmds | 577 | * alloc xmit-buffs / init xmit_cmds |
@@ -584,7 +584,7 @@ static int init586(struct net_device *dev) | |||
584 | ptr = (char *) ptr + XMIT_BUFF_SIZE; | 584 | ptr = (char *) ptr + XMIT_BUFF_SIZE; |
585 | p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ | 585 | p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */ |
586 | ptr = (char *) ptr + sizeof(struct tbd_struct); | 586 | ptr = (char *) ptr + sizeof(struct tbd_struct); |
587 | if((void *)ptr > (void *)dev->mem_end) | 587 | if(ptr > (void *)dev->mem_end) |
588 | { | 588 | { |
589 | printk("%s: not enough shared-mem for your configuration!\n",dev->name); | 589 | printk("%s: not enough shared-mem for your configuration!\n",dev->name); |
590 | return 1; | 590 | return 1; |
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index f0f06b2bc28b..770ee557924c 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -1896,7 +1896,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) | |||
1896 | goto out_free; | 1896 | goto out_free; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | rx_desc = (struct rx_desc *)rxq->rx_desc_area; | 1899 | rx_desc = rxq->rx_desc_area; |
1900 | for (i = 0; i < rxq->rx_ring_size; i++) { | 1900 | for (i = 0; i < rxq->rx_ring_size; i++) { |
1901 | int nexti; | 1901 | int nexti; |
1902 | 1902 | ||
@@ -2001,7 +2001,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
2001 | 2001 | ||
2002 | txq->tx_desc_area_size = size; | 2002 | txq->tx_desc_area_size = size; |
2003 | 2003 | ||
2004 | tx_desc = (struct tx_desc *)txq->tx_desc_area; | 2004 | tx_desc = txq->tx_desc_area; |
2005 | for (i = 0; i < txq->tx_ring_size; i++) { | 2005 | for (i = 0; i < txq->tx_ring_size; i++) { |
2006 | struct tx_desc *txd = tx_desc + i; | 2006 | struct tx_desc *txd = tx_desc + i; |
2007 | int nexti; | 2007 | int nexti; |
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 1db023b075a1..59489722e898 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c | |||
@@ -1032,7 +1032,7 @@ static int rxq_init(struct net_device *dev) | |||
1032 | } | 1032 | } |
1033 | memset((void *)pep->p_rx_desc_area, 0, size); | 1033 | memset((void *)pep->p_rx_desc_area, 0, size); |
1034 | /* initialize the next_desc_ptr links in the Rx descriptors ring */ | 1034 | /* initialize the next_desc_ptr links in the Rx descriptors ring */ |
1035 | p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area; | 1035 | p_rx_desc = pep->p_rx_desc_area; |
1036 | for (i = 0; i < rx_desc_num; i++) { | 1036 | for (i = 0; i < rx_desc_num; i++) { |
1037 | p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma + | 1037 | p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma + |
1038 | ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); | 1038 | ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); |
@@ -1095,7 +1095,7 @@ static int txq_init(struct net_device *dev) | |||
1095 | } | 1095 | } |
1096 | memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); | 1096 | memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); |
1097 | /* Initialize the next_desc_ptr links in the Tx descriptors ring */ | 1097 | /* Initialize the next_desc_ptr links in the Tx descriptors ring */ |
1098 | p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area; | 1098 | p_tx_desc = pep->p_tx_desc_area; |
1099 | for (i = 0; i < tx_desc_num; i++) { | 1099 | for (i = 0; i < tx_desc_num; i++) { |
1100 | p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma + | 1100 | p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma + |
1101 | ((i + 1) % tx_desc_num) * sizeof(struct tx_desc); | 1101 | ((i + 1) % tx_desc_num) * sizeof(struct tx_desc); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index b45d0e7f6ab0..766b8c5a235e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -779,7 +779,7 @@ static int qp_res_start_move_to(struct mlx4_dev *dev, int slave, int qpn, | |||
779 | r->com.to_state = state; | 779 | r->com.to_state = state; |
780 | r->com.state = RES_QP_BUSY; | 780 | r->com.state = RES_QP_BUSY; |
781 | if (qp) | 781 | if (qp) |
782 | *qp = (struct res_qp *)r; | 782 | *qp = r; |
783 | } | 783 | } |
784 | } | 784 | } |
785 | 785 | ||
@@ -832,7 +832,7 @@ static int mr_res_start_move_to(struct mlx4_dev *dev, int slave, int index, | |||
832 | r->com.to_state = state; | 832 | r->com.to_state = state; |
833 | r->com.state = RES_MPT_BUSY; | 833 | r->com.state = RES_MPT_BUSY; |
834 | if (mpt) | 834 | if (mpt) |
835 | *mpt = (struct res_mpt *)r; | 835 | *mpt = r; |
836 | } | 836 | } |
837 | } | 837 | } |
838 | 838 | ||
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 5ffde23ac8fb..875dd5e264eb 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <asm/io.h> | 38 | #include <linux/ks8851_mll.h> |
39 | 39 | ||
40 | #define DRV_NAME "ks8851_mll" | 40 | #define DRV_NAME "ks8851_mll" |
41 | 41 | ||
@@ -1515,6 +1515,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1515 | struct net_device *netdev; | 1515 | struct net_device *netdev; |
1516 | struct ks_net *ks; | 1516 | struct ks_net *ks; |
1517 | u16 id, data; | 1517 | u16 id, data; |
1518 | struct ks8851_mll_platform_data *pdata; | ||
1518 | 1519 | ||
1519 | io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1520 | io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1520 | io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1521 | io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
@@ -1596,17 +1597,27 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1596 | ks_disable_qmu(ks); | 1597 | ks_disable_qmu(ks); |
1597 | ks_setup(ks); | 1598 | ks_setup(ks); |
1598 | ks_setup_int(ks); | 1599 | ks_setup_int(ks); |
1599 | memcpy(netdev->dev_addr, ks->mac_addr, 6); | ||
1600 | 1600 | ||
1601 | data = ks_rdreg16(ks, KS_OBCR); | 1601 | data = ks_rdreg16(ks, KS_OBCR); |
1602 | ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA); | 1602 | ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA); |
1603 | 1603 | ||
1604 | /** | 1604 | /* overwriting the default MAC address */ |
1605 | * If you want to use the default MAC addr, | 1605 | pdata = pdev->dev.platform_data; |
1606 | * comment out the 2 functions below. | 1606 | if (!pdata) { |
1607 | */ | 1607 | netdev_err(netdev, "No platform data\n"); |
1608 | err = -ENODEV; | ||
1609 | goto err_pdata; | ||
1610 | } | ||
1611 | memcpy(ks->mac_addr, pdata->mac_addr, 6); | ||
1612 | if (!is_valid_ether_addr(ks->mac_addr)) { | ||
1613 | /* Use random MAC address if none passed */ | ||
1614 | random_ether_addr(ks->mac_addr); | ||
1615 | netdev_info(netdev, "Using random mac address\n"); | ||
1616 | } | ||
1617 | netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr); | ||
1618 | |||
1619 | memcpy(netdev->dev_addr, ks->mac_addr, 6); | ||
1608 | 1620 | ||
1609 | random_ether_addr(netdev->dev_addr); | ||
1610 | ks_set_mac(ks, netdev->dev_addr); | 1621 | ks_set_mac(ks, netdev->dev_addr); |
1611 | 1622 | ||
1612 | id = ks_rdreg16(ks, KS_CIDER); | 1623 | id = ks_rdreg16(ks, KS_CIDER); |
@@ -1615,6 +1626,8 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1615 | (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); | 1626 | (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7); |
1616 | return 0; | 1627 | return 0; |
1617 | 1628 | ||
1629 | err_pdata: | ||
1630 | unregister_netdev(netdev); | ||
1618 | err_register: | 1631 | err_register: |
1619 | err_get_irq: | 1632 | err_get_irq: |
1620 | iounmap(ks->hw_addr_cmd); | 1633 | iounmap(ks->hw_addr_cmd); |
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index bb367582c1e8..e7cd587d8ae7 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c | |||
@@ -6946,9 +6946,9 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) | |||
6946 | if (sp->rxd_mode == RXD_MODE_3B) | 6946 | if (sp->rxd_mode == RXD_MODE_3B) |
6947 | ba = &ring->ba[j][k]; | 6947 | ba = &ring->ba[j][k]; |
6948 | if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb, | 6948 | if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb, |
6949 | (u64 *)&temp0_64, | 6949 | &temp0_64, |
6950 | (u64 *)&temp1_64, | 6950 | &temp1_64, |
6951 | (u64 *)&temp2_64, | 6951 | &temp2_64, |
6952 | size) == -ENOMEM) { | 6952 | size) == -ENOMEM) { |
6953 | return 0; | 6953 | return 0; |
6954 | } | 6954 | } |
@@ -7149,7 +7149,7 @@ static int s2io_card_up(struct s2io_nic *sp) | |||
7149 | int i, ret = 0; | 7149 | int i, ret = 0; |
7150 | struct config_param *config; | 7150 | struct config_param *config; |
7151 | struct mac_info *mac_control; | 7151 | struct mac_info *mac_control; |
7152 | struct net_device *dev = (struct net_device *)sp->dev; | 7152 | struct net_device *dev = sp->dev; |
7153 | u16 interruptible; | 7153 | u16 interruptible; |
7154 | 7154 | ||
7155 | /* Initialize the H/W I/O registers */ | 7155 | /* Initialize the H/W I/O registers */ |
@@ -7325,7 +7325,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
7325 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) | 7325 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) |
7326 | { | 7326 | { |
7327 | struct s2io_nic *sp = ring_data->nic; | 7327 | struct s2io_nic *sp = ring_data->nic; |
7328 | struct net_device *dev = (struct net_device *)ring_data->dev; | 7328 | struct net_device *dev = ring_data->dev; |
7329 | struct sk_buff *skb = (struct sk_buff *) | 7329 | struct sk_buff *skb = (struct sk_buff *) |
7330 | ((unsigned long)rxdp->Host_Control); | 7330 | ((unsigned long)rxdp->Host_Control); |
7331 | int ring_no = ring_data->ring_no; | 7331 | int ring_no = ring_data->ring_no; |
@@ -7508,7 +7508,7 @@ aggregate: | |||
7508 | 7508 | ||
7509 | static void s2io_link(struct s2io_nic *sp, int link) | 7509 | static void s2io_link(struct s2io_nic *sp, int link) |
7510 | { | 7510 | { |
7511 | struct net_device *dev = (struct net_device *)sp->dev; | 7511 | struct net_device *dev = sp->dev; |
7512 | struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; | 7512 | struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; |
7513 | 7513 | ||
7514 | if (link != sp->last_link_state) { | 7514 | if (link != sp->last_link_state) { |
@@ -8280,7 +8280,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, | |||
8280 | return -1; | 8280 | return -1; |
8281 | } | 8281 | } |
8282 | 8282 | ||
8283 | *ip = (struct iphdr *)((u8 *)buffer + ip_off); | 8283 | *ip = (struct iphdr *)(buffer + ip_off); |
8284 | ip_len = (u8)((*ip)->ihl); | 8284 | ip_len = (u8)((*ip)->ihl); |
8285 | ip_len <<= 2; | 8285 | ip_len <<= 2; |
8286 | *tcp = (struct tcphdr *)((unsigned long)*ip + ip_len); | 8286 | *tcp = (struct tcphdr *)((unsigned long)*ip + ip_len); |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.c b/drivers/net/ethernet/neterion/vxge/vxge-config.c index 98e2c10ae08b..32d06824fe3e 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-config.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-config.c | |||
@@ -2346,7 +2346,7 @@ void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool) | |||
2346 | 2346 | ||
2347 | for (i = 0; i < nreq; i++) | 2347 | for (i = 0; i < nreq; i++) |
2348 | vxge_os_dma_malloc_async( | 2348 | vxge_os_dma_malloc_async( |
2349 | ((struct __vxge_hw_device *)blockpool->hldev)->pdev, | 2349 | (blockpool->hldev)->pdev, |
2350 | blockpool->hldev, VXGE_HW_BLOCK_SIZE); | 2350 | blockpool->hldev, VXGE_HW_BLOCK_SIZE); |
2351 | } | 2351 | } |
2352 | 2352 | ||
@@ -2428,13 +2428,13 @@ __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool) | |||
2428 | break; | 2428 | break; |
2429 | 2429 | ||
2430 | pci_unmap_single( | 2430 | pci_unmap_single( |
2431 | ((struct __vxge_hw_device *)blockpool->hldev)->pdev, | 2431 | (blockpool->hldev)->pdev, |
2432 | ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, | 2432 | ((struct __vxge_hw_blockpool_entry *)p)->dma_addr, |
2433 | ((struct __vxge_hw_blockpool_entry *)p)->length, | 2433 | ((struct __vxge_hw_blockpool_entry *)p)->length, |
2434 | PCI_DMA_BIDIRECTIONAL); | 2434 | PCI_DMA_BIDIRECTIONAL); |
2435 | 2435 | ||
2436 | vxge_os_dma_free( | 2436 | vxge_os_dma_free( |
2437 | ((struct __vxge_hw_device *)blockpool->hldev)->pdev, | 2437 | (blockpool->hldev)->pdev, |
2438 | ((struct __vxge_hw_blockpool_entry *)p)->memblock, | 2438 | ((struct __vxge_hw_blockpool_entry *)p)->memblock, |
2439 | &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); | 2439 | &((struct __vxge_hw_blockpool_entry *)p)->acc_handle); |
2440 | 2440 | ||
@@ -4059,7 +4059,7 @@ __vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id) | |||
4059 | enum vxge_hw_status status = VXGE_HW_OK; | 4059 | enum vxge_hw_status status = VXGE_HW_OK; |
4060 | struct __vxge_hw_virtualpath *vpath; | 4060 | struct __vxge_hw_virtualpath *vpath; |
4061 | 4061 | ||
4062 | vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id]; | 4062 | vpath = &hldev->virtual_paths[vp_id]; |
4063 | 4063 | ||
4064 | if (vpath->ringh) { | 4064 | if (vpath->ringh) { |
4065 | status = __vxge_hw_ring_reset(vpath->ringh); | 4065 | status = __vxge_hw_ring_reset(vpath->ringh); |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-config.h b/drivers/net/ethernet/neterion/vxge/vxge-config.h index 5046a64f0fe8..9e0c1eed5dc5 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-config.h +++ b/drivers/net/ethernet/neterion/vxge/vxge-config.h | |||
@@ -1922,7 +1922,7 @@ realloc: | |||
1922 | /* misaligned, free current one and try allocating | 1922 | /* misaligned, free current one and try allocating |
1923 | * size + VXGE_CACHE_LINE_SIZE memory | 1923 | * size + VXGE_CACHE_LINE_SIZE memory |
1924 | */ | 1924 | */ |
1925 | kfree((void *) vaddr); | 1925 | kfree(vaddr); |
1926 | size += VXGE_CACHE_LINE_SIZE; | 1926 | size += VXGE_CACHE_LINE_SIZE; |
1927 | realloc_flag = 1; | 1927 | realloc_flag = 1; |
1928 | goto realloc; | 1928 | goto realloc; |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 51387c31914b..2578eb1f025d 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c | |||
@@ -1134,7 +1134,7 @@ static void vxge_set_multicast(struct net_device *dev) | |||
1134 | "%s:%d", __func__, __LINE__); | 1134 | "%s:%d", __func__, __LINE__); |
1135 | 1135 | ||
1136 | vdev = netdev_priv(dev); | 1136 | vdev = netdev_priv(dev); |
1137 | hldev = (struct __vxge_hw_device *)vdev->devh; | 1137 | hldev = vdev->devh; |
1138 | 1138 | ||
1139 | if (unlikely(!is_vxge_card_up(vdev))) | 1139 | if (unlikely(!is_vxge_card_up(vdev))) |
1140 | return; | 1140 | return; |
@@ -3989,16 +3989,16 @@ static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask) | |||
3989 | continue; | 3989 | continue; |
3990 | vxge_debug_ll_config(VXGE_TRACE, | 3990 | vxge_debug_ll_config(VXGE_TRACE, |
3991 | "%s: MTU size - %d", vdev->ndev->name, | 3991 | "%s: MTU size - %d", vdev->ndev->name, |
3992 | ((struct __vxge_hw_device *)(vdev->devh))-> | 3992 | ((vdev->devh))-> |
3993 | config.vp_config[i].mtu); | 3993 | config.vp_config[i].mtu); |
3994 | vxge_debug_init(VXGE_TRACE, | 3994 | vxge_debug_init(VXGE_TRACE, |
3995 | "%s: VLAN tag stripping %s", vdev->ndev->name, | 3995 | "%s: VLAN tag stripping %s", vdev->ndev->name, |
3996 | ((struct __vxge_hw_device *)(vdev->devh))-> | 3996 | ((vdev->devh))-> |
3997 | config.vp_config[i].rpa_strip_vlan_tag | 3997 | config.vp_config[i].rpa_strip_vlan_tag |
3998 | ? "Enabled" : "Disabled"); | 3998 | ? "Enabled" : "Disabled"); |
3999 | vxge_debug_ll_config(VXGE_TRACE, | 3999 | vxge_debug_ll_config(VXGE_TRACE, |
4000 | "%s: Max frags : %d", vdev->ndev->name, | 4000 | "%s: Max frags : %d", vdev->ndev->name, |
4001 | ((struct __vxge_hw_device *)(vdev->devh))-> | 4001 | ((vdev->devh))-> |
4002 | config.vp_config[i].fifo.max_frags); | 4002 | config.vp_config[i].fifo.max_frags); |
4003 | break; | 4003 | break; |
4004 | } | 4004 | } |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c index 5954fa264da1..99749bd07d72 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-traffic.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-traffic.c | |||
@@ -533,8 +533,7 @@ __vxge_hw_device_handle_error(struct __vxge_hw_device *hldev, u32 vp_id, | |||
533 | 533 | ||
534 | /* notify driver */ | 534 | /* notify driver */ |
535 | if (hldev->uld_callbacks->crit_err) | 535 | if (hldev->uld_callbacks->crit_err) |
536 | hldev->uld_callbacks->crit_err( | 536 | hldev->uld_callbacks->crit_err(hldev, |
537 | (struct __vxge_hw_device *)hldev, | ||
538 | type, vp_id); | 537 | type, vp_id); |
539 | out: | 538 | out: |
540 | 539 | ||
@@ -1322,7 +1321,7 @@ enum vxge_hw_status vxge_hw_ring_rxd_next_completed( | |||
1322 | /* check whether it is not the end */ | 1321 | /* check whether it is not the end */ |
1323 | if (!own || *t_code == VXGE_HW_RING_T_CODE_FRM_DROP) { | 1322 | if (!own || *t_code == VXGE_HW_RING_T_CODE_FRM_DROP) { |
1324 | 1323 | ||
1325 | vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control != | 1324 | vxge_assert((rxdp)->host_control != |
1326 | 0); | 1325 | 0); |
1327 | 1326 | ||
1328 | ++ring->cmpl_cnt; | 1327 | ++ring->cmpl_cnt; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 8680a5dae4a2..eaa1db9fec32 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -36,8 +36,8 @@ | |||
36 | 36 | ||
37 | #define _QLCNIC_LINUX_MAJOR 5 | 37 | #define _QLCNIC_LINUX_MAJOR 5 |
38 | #define _QLCNIC_LINUX_MINOR 0 | 38 | #define _QLCNIC_LINUX_MINOR 0 |
39 | #define _QLCNIC_LINUX_SUBVERSION 28 | 39 | #define _QLCNIC_LINUX_SUBVERSION 29 |
40 | #define QLCNIC_LINUX_VERSIONID "5.0.28" | 40 | #define QLCNIC_LINUX_VERSIONID "5.0.29" |
41 | #define QLCNIC_DRV_IDC_VER 0x01 | 41 | #define QLCNIC_DRV_IDC_VER 0x01 |
42 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 42 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
43 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 43 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -258,6 +258,8 @@ struct rcv_desc { | |||
258 | (((sts_data) >> 52) & 0x1) | 258 | (((sts_data) >> 52) & 0x1) |
259 | #define qlcnic_get_lro_sts_seq_number(sts_data) \ | 259 | #define qlcnic_get_lro_sts_seq_number(sts_data) \ |
260 | ((sts_data) & 0x0FFFFFFFF) | 260 | ((sts_data) & 0x0FFFFFFFF) |
261 | #define qlcnic_get_lro_sts_mss(sts_data1) \ | ||
262 | ((sts_data1 >> 32) & 0x0FFFF) | ||
261 | 263 | ||
262 | 264 | ||
263 | struct status_desc { | 265 | struct status_desc { |
@@ -610,7 +612,11 @@ struct qlcnic_recv_context { | |||
610 | #define QLCNIC_CDRP_CMD_GET_MAC_STATS 0x00000037 | 612 | #define QLCNIC_CDRP_CMD_GET_MAC_STATS 0x00000037 |
611 | 613 | ||
612 | #define QLCNIC_RCODE_SUCCESS 0 | 614 | #define QLCNIC_RCODE_SUCCESS 0 |
615 | #define QLCNIC_RCODE_INVALID_ARGS 6 | ||
613 | #define QLCNIC_RCODE_NOT_SUPPORTED 9 | 616 | #define QLCNIC_RCODE_NOT_SUPPORTED 9 |
617 | #define QLCNIC_RCODE_NOT_PERMITTED 10 | ||
618 | #define QLCNIC_RCODE_NOT_IMPL 15 | ||
619 | #define QLCNIC_RCODE_INVALID 16 | ||
614 | #define QLCNIC_RCODE_TIMEOUT 17 | 620 | #define QLCNIC_RCODE_TIMEOUT 17 |
615 | #define QLCNIC_DESTROY_CTX_RESET 0 | 621 | #define QLCNIC_DESTROY_CTX_RESET 0 |
616 | 622 | ||
@@ -623,6 +629,7 @@ struct qlcnic_recv_context { | |||
623 | #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) | 629 | #define QLCNIC_CAP0_JUMBO_CONTIGUOUS (1 << 7) |
624 | #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) | 630 | #define QLCNIC_CAP0_LRO_CONTIGUOUS (1 << 8) |
625 | #define QLCNIC_CAP0_VALIDOFF (1 << 11) | 631 | #define QLCNIC_CAP0_VALIDOFF (1 << 11) |
632 | #define QLCNIC_CAP0_LRO_MSS (1 << 21) | ||
626 | 633 | ||
627 | /* | 634 | /* |
628 | * Context state | 635 | * Context state |
@@ -829,6 +836,9 @@ struct qlcnic_mac_list_s { | |||
829 | #define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9 | 836 | #define QLCNIC_FW_CAPABILITY_FVLANTX BIT_9 |
830 | #define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10 | 837 | #define QLCNIC_FW_CAPABILITY_HW_LRO BIT_10 |
831 | #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27 | 838 | #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK BIT_27 |
839 | #define QLCNIC_FW_CAPABILITY_MORE_CAPS BIT_31 | ||
840 | |||
841 | #define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG BIT_2 | ||
832 | 842 | ||
833 | /* module types */ | 843 | /* module types */ |
834 | #define LINKEVENT_MODULE_NOT_PRESENT 1 | 844 | #define LINKEVENT_MODULE_NOT_PRESENT 1 |
@@ -918,6 +928,7 @@ struct qlcnic_ipaddr { | |||
918 | #define QLCNIC_NEED_FLR 0x1000 | 928 | #define QLCNIC_NEED_FLR 0x1000 |
919 | #define QLCNIC_FW_RESET_OWNER 0x2000 | 929 | #define QLCNIC_FW_RESET_OWNER 0x2000 |
920 | #define QLCNIC_FW_HANG 0x4000 | 930 | #define QLCNIC_FW_HANG 0x4000 |
931 | #define QLCNIC_FW_LRO_MSS_CAP 0x8000 | ||
921 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ | 932 | #define QLCNIC_IS_MSI_FAMILY(adapter) \ |
922 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) | 933 | ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) |
923 | 934 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 8db85244e8ad..b8ead696141e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | |||
@@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd) | |||
53 | rsp = qlcnic_poll_rsp(adapter); | 53 | rsp = qlcnic_poll_rsp(adapter); |
54 | 54 | ||
55 | if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { | 55 | if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) { |
56 | dev_err(&pdev->dev, "card response timeout.\n"); | 56 | dev_err(&pdev->dev, "CDRP response timeout.\n"); |
57 | cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT; | 57 | cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT; |
58 | } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { | 58 | } else if (rsp == QLCNIC_CDRP_RSP_FAIL) { |
59 | cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); | 59 | cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); |
60 | dev_err(&pdev->dev, "failed card response code:0x%x\n", | 60 | switch (cmd->rsp.cmd) { |
61 | case QLCNIC_RCODE_INVALID_ARGS: | ||
62 | dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n", | ||
61 | cmd->rsp.cmd); | 63 | cmd->rsp.cmd); |
64 | break; | ||
65 | case QLCNIC_RCODE_NOT_SUPPORTED: | ||
66 | case QLCNIC_RCODE_NOT_IMPL: | ||
67 | dev_err(&pdev->dev, | ||
68 | "CDRP command not supported: 0x%x.\n", | ||
69 | cmd->rsp.cmd); | ||
70 | break; | ||
71 | case QLCNIC_RCODE_NOT_PERMITTED: | ||
72 | dev_err(&pdev->dev, | ||
73 | "CDRP requested action not permitted: 0x%x.\n", | ||
74 | cmd->rsp.cmd); | ||
75 | break; | ||
76 | case QLCNIC_RCODE_INVALID: | ||
77 | dev_err(&pdev->dev, | ||
78 | "CDRP invalid or unknown cmd received: 0x%x.\n", | ||
79 | cmd->rsp.cmd); | ||
80 | break; | ||
81 | case QLCNIC_RCODE_TIMEOUT: | ||
82 | dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n", | ||
83 | cmd->rsp.cmd); | ||
84 | break; | ||
85 | default: | ||
86 | dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n", | ||
87 | cmd->rsp.cmd); | ||
88 | } | ||
62 | } else if (rsp == QLCNIC_CDRP_RSP_OK) { | 89 | } else if (rsp == QLCNIC_CDRP_RSP_OK) { |
63 | cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS; | 90 | cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS; |
64 | if (cmd->rsp.arg2) | 91 | if (cmd->rsp.arg2) |
@@ -237,6 +264,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) | |||
237 | | QLCNIC_CAP0_VALIDOFF); | 264 | | QLCNIC_CAP0_VALIDOFF); |
238 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); | 265 | cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS); |
239 | 266 | ||
267 | if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) | ||
268 | cap |= QLCNIC_CAP0_LRO_MSS; | ||
269 | |||
240 | prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, | 270 | prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx, |
241 | msix_handler); | 271 | msix_handler); |
242 | prq->txrx_sds_binding = nsds_rings - 1; | 272 | prq->txrx_sds_binding = nsds_rings - 1; |
@@ -954,9 +984,6 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter, | |||
954 | mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber); | 984 | mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber); |
955 | mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped); | 985 | mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped); |
956 | mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); | 986 | mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error); |
957 | } else { | ||
958 | dev_info(&adapter->pdev->dev, | ||
959 | "%s: Get mac stats failed =%d.\n", __func__, err); | ||
960 | } | 987 | } |
961 | 988 | ||
962 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, | 989 | dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr, |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index 6ced3195aad3..28a6b28192e3 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | |||
@@ -588,6 +588,7 @@ enum { | |||
588 | #define CRB_DRIVER_VERSION (QLCNIC_REG(0x2a0)) | 588 | #define CRB_DRIVER_VERSION (QLCNIC_REG(0x2a0)) |
589 | 589 | ||
590 | #define CRB_FW_CAPABILITIES_1 (QLCNIC_CAM_RAM(0x128)) | 590 | #define CRB_FW_CAPABILITIES_1 (QLCNIC_CAM_RAM(0x128)) |
591 | #define CRB_FW_CAPABILITIES_2 (QLCNIC_CAM_RAM(0x12c)) | ||
591 | #define CRB_MAC_BLOCK_START (QLCNIC_CAM_RAM(0x1c0)) | 592 | #define CRB_MAC_BLOCK_START (QLCNIC_CAM_RAM(0x1c0)) |
592 | 593 | ||
593 | /* | 594 | /* |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 799fd40ed03a..8620b696aca8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c | |||
@@ -1653,6 +1653,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, | |||
1653 | 1653 | ||
1654 | length = skb->len; | 1654 | length = skb->len; |
1655 | 1655 | ||
1656 | if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP) | ||
1657 | skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1); | ||
1658 | |||
1656 | if (vid != 0xffff) | 1659 | if (vid != 0xffff) |
1657 | __vlan_hwaccel_put_tag(skb, vid); | 1660 | __vlan_hwaccel_put_tag(skb, vid); |
1658 | netif_receive_skb(skb); | 1661 | netif_receive_skb(skb); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c5121..33c3e46e59c4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -1136,6 +1136,8 @@ static int | |||
1136 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | 1136 | __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) |
1137 | { | 1137 | { |
1138 | int ring; | 1138 | int ring; |
1139 | u32 capab2; | ||
1140 | |||
1139 | struct qlcnic_host_rds_ring *rds_ring; | 1141 | struct qlcnic_host_rds_ring *rds_ring; |
1140 | 1142 | ||
1141 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | 1143 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) |
@@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1146 | if (qlcnic_set_eswitch_port_config(adapter)) | 1148 | if (qlcnic_set_eswitch_port_config(adapter)) |
1147 | return -EIO; | 1149 | return -EIO; |
1148 | 1150 | ||
1151 | if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) { | ||
1152 | capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2); | ||
1153 | if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG) | ||
1154 | adapter->flags |= QLCNIC_FW_LRO_MSS_CAP; | ||
1155 | } | ||
1156 | |||
1149 | if (qlcnic_fw_create_ctx(adapter)) | 1157 | if (qlcnic_fw_create_ctx(adapter)) |
1150 | return -EIO; | 1158 | return -EIO; |
1151 | 1159 | ||
@@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) | |||
1215 | qlcnic_napi_disable(adapter); | 1223 | qlcnic_napi_disable(adapter); |
1216 | 1224 | ||
1217 | qlcnic_fw_destroy_ctx(adapter); | 1225 | qlcnic_fw_destroy_ctx(adapter); |
1226 | adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP; | ||
1218 | 1227 | ||
1219 | qlcnic_reset_rx_buffers_list(adapter); | 1228 | qlcnic_reset_rx_buffers_list(adapter); |
1220 | qlcnic_release_tx_buffers(adapter); | 1229 | qlcnic_release_tx_buffers(adapter); |
@@ -2024,6 +2033,7 @@ qlcnic_tx_pkt(struct qlcnic_adapter *adapter, | |||
2024 | vh = (struct vlan_ethhdr *)skb->data; | 2033 | vh = (struct vlan_ethhdr *)skb->data; |
2025 | flags = FLAGS_VLAN_TAGGED; | 2034 | flags = FLAGS_VLAN_TAGGED; |
2026 | vlan_tci = vh->h_vlan_TCI; | 2035 | vlan_tci = vh->h_vlan_TCI; |
2036 | protocol = ntohs(vh->h_vlan_encapsulated_proto); | ||
2027 | } else if (vlan_tx_tag_present(skb)) { | 2037 | } else if (vlan_tx_tag_present(skb)) { |
2028 | flags = FLAGS_VLAN_OOB; | 2038 | flags = FLAGS_VLAN_OOB; |
2029 | vlan_tci = vlan_tx_tag_get(skb); | 2039 | vlan_tci = vlan_tx_tag_get(skb); |
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index ac149d99f78f..b5ba3084c7fc 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c | |||
@@ -583,7 +583,7 @@ static inline void ioc3_rx(struct net_device *dev) | |||
583 | unsigned long *rxr; | 583 | unsigned long *rxr; |
584 | u32 w0, err; | 584 | u32 w0, err; |
585 | 585 | ||
586 | rxr = (unsigned long *) ip->rxr; /* Ring base */ | 586 | rxr = ip->rxr; /* Ring base */ |
587 | rx_entry = ip->rx_ci; /* RX consume index */ | 587 | rx_entry = ip->rx_ci; /* RX consume index */ |
588 | n_entry = ip->rx_pi; | 588 | n_entry = ip->rx_pi; |
589 | 589 | ||
@@ -903,7 +903,7 @@ static void ioc3_alloc_rings(struct net_device *dev) | |||
903 | if (ip->rxr == NULL) { | 903 | if (ip->rxr == NULL) { |
904 | /* Allocate and initialize rx ring. 4kb = 512 entries */ | 904 | /* Allocate and initialize rx ring. 4kb = 512 entries */ |
905 | ip->rxr = (unsigned long *) get_zeroed_page(GFP_ATOMIC); | 905 | ip->rxr = (unsigned long *) get_zeroed_page(GFP_ATOMIC); |
906 | rxr = (unsigned long *) ip->rxr; | 906 | rxr = ip->rxr; |
907 | if (!rxr) | 907 | if (!rxr) |
908 | printk("ioc3_alloc_rings(): get_zeroed_page() failed!\n"); | 908 | printk("ioc3_alloc_rings(): get_zeroed_page() failed!\n"); |
909 | 909 | ||
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index fd33b21f6c96..1fcd914ec39b 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c | |||
@@ -1640,8 +1640,7 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1640 | goto out_free_io_4; | 1640 | goto out_free_io_4; |
1641 | 1641 | ||
1642 | /* descriptors are aligned due to the nature of pci_alloc_consistent */ | 1642 | /* descriptors are aligned due to the nature of pci_alloc_consistent */ |
1643 | pd->tx_ring = (struct smsc9420_dma_desc *) | 1643 | pd->tx_ring = (pd->rx_ring + RX_RING_SIZE); |
1644 | (pd->rx_ring + RX_RING_SIZE); | ||
1645 | pd->tx_dma_addr = pd->rx_dma_addr + | 1644 | pd->tx_dma_addr = pd->rx_dma_addr + |
1646 | sizeof(struct smsc9420_dma_desc) * RX_RING_SIZE; | 1645 | sizeof(struct smsc9420_dma_desc) * RX_RING_SIZE; |
1647 | 1646 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 51b3b68528ee..590e95b4cbfa 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -677,7 +677,7 @@ static void stmmac_tx(struct stmmac_priv *priv) | |||
677 | 677 | ||
678 | priv->hw->desc->release_tx_desc(p); | 678 | priv->hw->desc->release_tx_desc(p); |
679 | 679 | ||
680 | entry = (++priv->dirty_tx) % txsize; | 680 | priv->dirty_tx++; |
681 | } | 681 | } |
682 | if (unlikely(netif_queue_stopped(priv->dev) && | 682 | if (unlikely(netif_queue_stopped(priv->dev) && |
683 | stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { | 683 | stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) { |
@@ -1308,7 +1308,6 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) | |||
1308 | display_ring(priv->dma_rx, rxsize); | 1308 | display_ring(priv->dma_rx, rxsize); |
1309 | } | 1309 | } |
1310 | #endif | 1310 | #endif |
1311 | count = 0; | ||
1312 | while (!priv->hw->desc->get_rx_owner(p)) { | 1311 | while (!priv->hw->desc->get_rx_owner(p)) { |
1313 | int status; | 1312 | int status; |
1314 | 1313 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 680d2b8dfe27..20eb5026c49c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -190,7 +190,7 @@ static int stmmac_pltfr_remove(struct platform_device *pdev) | |||
190 | 190 | ||
191 | platform_set_drvdata(pdev, NULL); | 191 | platform_set_drvdata(pdev, NULL); |
192 | 192 | ||
193 | iounmap((void *)priv->ioaddr); | 193 | iounmap((void __force __iomem *)priv->ioaddr); |
194 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 194 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
195 | release_mem_region(res->start, resource_size(res)); | 195 | release_mem_region(res->start, resource_size(res)); |
196 | 196 | ||
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 7d4a040d84a2..aeded7ff1c8f 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c | |||
@@ -441,7 +441,7 @@ static void qe_rx(struct sunqe *qep) | |||
441 | } else { | 441 | } else { |
442 | skb_reserve(skb, 2); | 442 | skb_reserve(skb, 2); |
443 | skb_put(skb, len); | 443 | skb_put(skb, len); |
444 | skb_copy_to_linear_data(skb, (unsigned char *) this_qbuf, | 444 | skb_copy_to_linear_data(skb, this_qbuf, |
445 | len); | 445 | len); |
446 | skb->protocol = eth_type_trans(skb, qep->dev); | 446 | skb->protocol = eth_type_trans(skb, qep->dev); |
447 | netif_rx(skb); | 447 | netif_rx(skb); |
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index ea3e0a21ba74..a46c19859683 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c | |||
@@ -486,7 +486,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, | |||
486 | velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); | 486 | velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname); |
487 | velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname); | 487 | velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname); |
488 | velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname); | 488 | velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname); |
489 | velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); | 489 | velocity_set_int_opt(&opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); |
490 | opts->numrx = (opts->numrx & ~3); | 490 | opts->numrx = (opts->numrx & ~3); |
491 | } | 491 | } |
492 | 492 | ||
diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c index 4ad80f771099..6695a1dadf4e 100644 --- a/drivers/net/fddi/defxx.c +++ b/drivers/net/fddi/defxx.c | |||
@@ -2962,7 +2962,7 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers) | |||
2962 | bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP | | 2962 | bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP | |
2963 | ((PI_RCV_DATA_K_SIZE_MAX / PI_ALIGN_K_RCV_DATA_BUFF) << PI_RCV_DESCR_V_SEG_LEN)); | 2963 | ((PI_RCV_DATA_K_SIZE_MAX / PI_ALIGN_K_RCV_DATA_BUFF) << PI_RCV_DESCR_V_SEG_LEN)); |
2964 | bp->descr_block_virt->rcv_data[i+j].long_1 = (u32) (bp->rcv_block_phys + (i * PI_RCV_DATA_K_SIZE_MAX)); | 2964 | bp->descr_block_virt->rcv_data[i+j].long_1 = (u32) (bp->rcv_block_phys + (i * PI_RCV_DATA_K_SIZE_MAX)); |
2965 | bp->p_rcv_buff_va[i+j] = (char *) (bp->rcv_block_virt + (i * PI_RCV_DATA_K_SIZE_MAX)); | 2965 | bp->p_rcv_buff_va[i+j] = (bp->rcv_block_virt + (i * PI_RCV_DATA_K_SIZE_MAX)); |
2966 | } | 2966 | } |
2967 | #endif | 2967 | #endif |
2968 | } | 2968 | } |
@@ -3030,7 +3030,7 @@ static void dfx_rcv_queue_process( | |||
3030 | #ifdef DYNAMIC_BUFFERS | 3030 | #ifdef DYNAMIC_BUFFERS |
3031 | p_buff = (char *) (((struct sk_buff *)bp->p_rcv_buff_va[entry])->data); | 3031 | p_buff = (char *) (((struct sk_buff *)bp->p_rcv_buff_va[entry])->data); |
3032 | #else | 3032 | #else |
3033 | p_buff = (char *) bp->p_rcv_buff_va[entry]; | 3033 | p_buff = bp->p_rcv_buff_va[entry]; |
3034 | #endif | 3034 | #endif |
3035 | memcpy(&descr, p_buff + RCV_BUFF_K_DESCR, sizeof(u32)); | 3035 | memcpy(&descr, p_buff + RCV_BUFF_K_DESCR, sizeof(u32)); |
3036 | 3036 | ||
diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 9ac4665d7411..24d8566cfd8b 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c | |||
@@ -1242,7 +1242,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, | |||
1242 | if (len < 8) | 1242 | if (len < 8) |
1243 | goto len_error ; | 1243 | goto len_error ; |
1244 | if (set) | 1244 | if (set) |
1245 | memcpy((char *) to,(char *) from+2,6) ; | 1245 | memcpy(to,from+2,6) ; |
1246 | to += 8 ; | 1246 | to += 8 ; |
1247 | from += 8 ; | 1247 | from += 8 ; |
1248 | len -= 8 ; | 1248 | len -= 8 ; |
@@ -1251,7 +1251,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, | |||
1251 | if (len < 4) | 1251 | if (len < 4) |
1252 | goto len_error ; | 1252 | goto len_error ; |
1253 | if (set) | 1253 | if (set) |
1254 | memcpy((char *) to,(char *) from,4) ; | 1254 | memcpy(to,from,4) ; |
1255 | to += 4 ; | 1255 | to += 4 ; |
1256 | from += 4 ; | 1256 | from += 4 ; |
1257 | len -= 4 ; | 1257 | len -= 4 ; |
@@ -1260,7 +1260,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, | |||
1260 | if (len < 8) | 1260 | if (len < 8) |
1261 | goto len_error ; | 1261 | goto len_error ; |
1262 | if (set) | 1262 | if (set) |
1263 | memcpy((char *) to,(char *) from,8) ; | 1263 | memcpy(to,from,8) ; |
1264 | to += 8 ; | 1264 | to += 8 ; |
1265 | from += 8 ; | 1265 | from += 8 ; |
1266 | len -= 8 ; | 1266 | len -= 8 ; |
@@ -1269,7 +1269,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, | |||
1269 | if (len < 32) | 1269 | if (len < 32) |
1270 | goto len_error ; | 1270 | goto len_error ; |
1271 | if (set) | 1271 | if (set) |
1272 | memcpy((char *) to,(char *) from,32) ; | 1272 | memcpy(to,from,32) ; |
1273 | to += 32 ; | 1273 | to += 32 ; |
1274 | from += 32 ; | 1274 | from += 32 ; |
1275 | len -= 32 ; | 1275 | len -= 32 ; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index aed1a6105b24..2c0894a92abd 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -485,7 +485,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) | |||
485 | 485 | ||
486 | return; | 486 | return; |
487 | default: | 487 | default: |
488 | count = kiss_esc(p, (unsigned char *)ax->xbuff, len); | 488 | count = kiss_esc(p, ax->xbuff, len); |
489 | } | 489 | } |
490 | } else { | 490 | } else { |
491 | unsigned short crc; | 491 | unsigned short crc; |
@@ -497,7 +497,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) | |||
497 | case CRC_MODE_SMACK: | 497 | case CRC_MODE_SMACK: |
498 | *p |= 0x80; | 498 | *p |= 0x80; |
499 | crc = swab16(crc16(0, p, len)); | 499 | crc = swab16(crc16(0, p, len)); |
500 | count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2); | 500 | count = kiss_esc_crc(p, ax->xbuff, crc, len+2); |
501 | break; | 501 | break; |
502 | case CRC_MODE_FLEX_TEST: | 502 | case CRC_MODE_FLEX_TEST: |
503 | ax->crcmode = CRC_MODE_NONE; | 503 | ax->crcmode = CRC_MODE_NONE; |
@@ -506,11 +506,11 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) | |||
506 | case CRC_MODE_FLEX: | 506 | case CRC_MODE_FLEX: |
507 | *p |= 0x20; | 507 | *p |= 0x20; |
508 | crc = calc_crc_flex(p, len); | 508 | crc = calc_crc_flex(p, len); |
509 | count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2); | 509 | count = kiss_esc_crc(p, ax->xbuff, crc, len+2); |
510 | break; | 510 | break; |
511 | 511 | ||
512 | default: | 512 | default: |
513 | count = kiss_esc(p, (unsigned char *)ax->xbuff, len); | 513 | count = kiss_esc(p, ax->xbuff, len); |
514 | } | 514 | } |
515 | } | 515 | } |
516 | spin_unlock_bh(&ax->buflock); | 516 | spin_unlock_bh(&ax->buflock); |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 0c569831db5a..6cee2917eb02 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -614,7 +614,7 @@ retry_send_cmplt: | |||
614 | static void netvsc_receive_completion(void *context) | 614 | static void netvsc_receive_completion(void *context) |
615 | { | 615 | { |
616 | struct hv_netvsc_packet *packet = context; | 616 | struct hv_netvsc_packet *packet = context; |
617 | struct hv_device *device = (struct hv_device *)packet->device; | 617 | struct hv_device *device = packet->device; |
618 | struct netvsc_device *net_device; | 618 | struct netvsc_device *net_device; |
619 | u64 transaction_id = 0; | 619 | u64 transaction_id = 0; |
620 | bool fsend_receive_comp = false; | 620 | bool fsend_receive_comp = false; |
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c index dcc80d652b78..84872043b5c6 100644 --- a/drivers/net/irda/ali-ircc.c +++ b/drivers/net/irda/ali-ircc.c | |||
@@ -1017,7 +1017,7 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) | |||
1017 | { | 1017 | { |
1018 | 1018 | ||
1019 | int iobase; | 1019 | int iobase; |
1020 | struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; | 1020 | struct ali_ircc_cb *self = priv; |
1021 | struct net_device *dev; | 1021 | struct net_device *dev; |
1022 | 1022 | ||
1023 | IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); | 1023 | IRDA_DEBUG(1, "%s(), ---------------- Start ----------------\n", __func__ ); |
@@ -1052,7 +1052,7 @@ static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 baud) | |||
1052 | */ | 1052 | */ |
1053 | static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) | 1053 | static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) |
1054 | { | 1054 | { |
1055 | struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; | 1055 | struct ali_ircc_cb *self = priv; |
1056 | unsigned long flags; | 1056 | unsigned long flags; |
1057 | int iobase; | 1057 | int iobase; |
1058 | int fcr; /* FIFO control reg */ | 1058 | int fcr; /* FIFO control reg */ |
@@ -1121,7 +1121,7 @@ static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed) | |||
1121 | static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed) | 1121 | static void ali_ircc_change_dongle_speed(struct ali_ircc_cb *priv, int speed) |
1122 | { | 1122 | { |
1123 | 1123 | ||
1124 | struct ali_ircc_cb *self = (struct ali_ircc_cb *) priv; | 1124 | struct ali_ircc_cb *self = priv; |
1125 | int iobase,dongle_id; | 1125 | int iobase,dongle_id; |
1126 | int tmp = 0; | 1126 | int tmp = 0; |
1127 | 1127 | ||
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index fc503aa5288e..e09417df8f39 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c | |||
@@ -794,7 +794,7 @@ static int __devinit au1k_irda_net_init(struct net_device *dev) | |||
794 | 794 | ||
795 | /* allocate the data buffers */ | 795 | /* allocate the data buffers */ |
796 | aup->db[0].vaddr = | 796 | aup->db[0].vaddr = |
797 | (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); | 797 | dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); |
798 | if (!aup->db[0].vaddr) | 798 | if (!aup->db[0].vaddr) |
799 | goto out3; | 799 | goto out3; |
800 | 800 | ||
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 2ee56de7b0ca..0737bd4d1669 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -847,13 +847,12 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, | |||
847 | const struct iovec *iv, unsigned long len, | 847 | const struct iovec *iv, unsigned long len, |
848 | int noblock) | 848 | int noblock) |
849 | { | 849 | { |
850 | DECLARE_WAITQUEUE(wait, current); | 850 | DEFINE_WAIT(wait); |
851 | struct sk_buff *skb; | 851 | struct sk_buff *skb; |
852 | ssize_t ret = 0; | 852 | ssize_t ret = 0; |
853 | 853 | ||
854 | add_wait_queue(sk_sleep(&q->sk), &wait); | ||
855 | while (len) { | 854 | while (len) { |
856 | current->state = TASK_INTERRUPTIBLE; | 855 | prepare_to_wait(sk_sleep(&q->sk), &wait, TASK_INTERRUPTIBLE); |
857 | 856 | ||
858 | /* Read frames from the queue */ | 857 | /* Read frames from the queue */ |
859 | skb = skb_dequeue(&q->sk.sk_receive_queue); | 858 | skb = skb_dequeue(&q->sk.sk_receive_queue); |
@@ -875,8 +874,7 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb, | |||
875 | break; | 874 | break; |
876 | } | 875 | } |
877 | 876 | ||
878 | current->state = TASK_RUNNING; | 877 | finish_wait(sk_sleep(&q->sk), &wait); |
879 | remove_wait_queue(sk_sleep(&q->sk), &wait); | ||
880 | return ret; | 878 | return ret; |
881 | } | 879 | } |
882 | 880 | ||
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 940b29022d0c..b0da0226661f 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
@@ -17,6 +17,9 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
20 | #include <linux/ethtool.h> | 23 | #include <linux/ethtool.h> |
21 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
22 | #include <linux/list.h> | 25 | #include <linux/list.h> |
@@ -453,16 +456,16 @@ static void enable_status_frames(struct phy_device *phydev, bool on) | |||
453 | ext_write(0, phydev, PAGE6, PSF_CFG1, ver); | 456 | ext_write(0, phydev, PAGE6, PSF_CFG1, ver); |
454 | 457 | ||
455 | if (!phydev->attached_dev) { | 458 | if (!phydev->attached_dev) { |
456 | pr_warning("dp83640: expected to find an attached netdevice\n"); | 459 | pr_warn("expected to find an attached netdevice\n"); |
457 | return; | 460 | return; |
458 | } | 461 | } |
459 | 462 | ||
460 | if (on) { | 463 | if (on) { |
461 | if (dev_mc_add(phydev->attached_dev, status_frame_dst)) | 464 | if (dev_mc_add(phydev->attached_dev, status_frame_dst)) |
462 | pr_warning("dp83640: failed to add mc address\n"); | 465 | pr_warn("failed to add mc address\n"); |
463 | } else { | 466 | } else { |
464 | if (dev_mc_del(phydev->attached_dev, status_frame_dst)) | 467 | if (dev_mc_del(phydev->attached_dev, status_frame_dst)) |
465 | pr_warning("dp83640: failed to delete mc address\n"); | 468 | pr_warn("failed to delete mc address\n"); |
466 | } | 469 | } |
467 | } | 470 | } |
468 | 471 | ||
@@ -582,9 +585,9 @@ static void recalibrate(struct dp83640_clock *clock) | |||
582 | * read out and correct offsets | 585 | * read out and correct offsets |
583 | */ | 586 | */ |
584 | val = ext_read(master, PAGE4, PTP_STS); | 587 | val = ext_read(master, PAGE4, PTP_STS); |
585 | pr_info("master PTP_STS 0x%04hx", val); | 588 | pr_info("master PTP_STS 0x%04hx\n", val); |
586 | val = ext_read(master, PAGE4, PTP_ESTS); | 589 | val = ext_read(master, PAGE4, PTP_ESTS); |
587 | pr_info("master PTP_ESTS 0x%04hx", val); | 590 | pr_info("master PTP_ESTS 0x%04hx\n", val); |
588 | event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA); | 591 | event_ts.ns_lo = ext_read(master, PAGE4, PTP_EDATA); |
589 | event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA); | 592 | event_ts.ns_hi = ext_read(master, PAGE4, PTP_EDATA); |
590 | event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA); | 593 | event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA); |
@@ -594,9 +597,9 @@ static void recalibrate(struct dp83640_clock *clock) | |||
594 | list_for_each(this, &clock->phylist) { | 597 | list_for_each(this, &clock->phylist) { |
595 | tmp = list_entry(this, struct dp83640_private, list); | 598 | tmp = list_entry(this, struct dp83640_private, list); |
596 | val = ext_read(tmp->phydev, PAGE4, PTP_STS); | 599 | val = ext_read(tmp->phydev, PAGE4, PTP_STS); |
597 | pr_info("slave PTP_STS 0x%04hx", val); | 600 | pr_info("slave PTP_STS 0x%04hx\n", val); |
598 | val = ext_read(tmp->phydev, PAGE4, PTP_ESTS); | 601 | val = ext_read(tmp->phydev, PAGE4, PTP_ESTS); |
599 | pr_info("slave PTP_ESTS 0x%04hx", val); | 602 | pr_info("slave PTP_ESTS 0x%04hx\n", val); |
600 | event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); | 603 | event_ts.ns_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); |
601 | event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); | 604 | event_ts.ns_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA); |
602 | event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); | 605 | event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA); |
@@ -686,7 +689,7 @@ static void decode_rxts(struct dp83640_private *dp83640, | |||
686 | prune_rx_ts(dp83640); | 689 | prune_rx_ts(dp83640); |
687 | 690 | ||
688 | if (list_empty(&dp83640->rxpool)) { | 691 | if (list_empty(&dp83640->rxpool)) { |
689 | pr_debug("dp83640: rx timestamp pool is empty\n"); | 692 | pr_debug("rx timestamp pool is empty\n"); |
690 | goto out; | 693 | goto out; |
691 | } | 694 | } |
692 | rxts = list_first_entry(&dp83640->rxpool, struct rxts, list); | 695 | rxts = list_first_entry(&dp83640->rxpool, struct rxts, list); |
@@ -709,7 +712,7 @@ static void decode_txts(struct dp83640_private *dp83640, | |||
709 | skb = skb_dequeue(&dp83640->tx_queue); | 712 | skb = skb_dequeue(&dp83640->tx_queue); |
710 | 713 | ||
711 | if (!skb) { | 714 | if (!skb) { |
712 | pr_debug("dp83640: have timestamp but tx_queue empty\n"); | 715 | pr_debug("have timestamp but tx_queue empty\n"); |
713 | return; | 716 | return; |
714 | } | 717 | } |
715 | ns = phy2txts(phy_txts); | 718 | ns = phy2txts(phy_txts); |
@@ -847,7 +850,7 @@ static void dp83640_free_clocks(void) | |||
847 | list_for_each_safe(this, next, &phyter_clocks) { | 850 | list_for_each_safe(this, next, &phyter_clocks) { |
848 | clock = list_entry(this, struct dp83640_clock, list); | 851 | clock = list_entry(this, struct dp83640_clock, list); |
849 | if (!list_empty(&clock->phylist)) { | 852 | if (!list_empty(&clock->phylist)) { |
850 | pr_warning("phy list non-empty while unloading"); | 853 | pr_warn("phy list non-empty while unloading\n"); |
851 | BUG(); | 854 | BUG(); |
852 | } | 855 | } |
853 | list_del(&clock->list); | 856 | list_del(&clock->list); |
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 633680d0828e..ba55adfc7aae 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c | |||
@@ -70,7 +70,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp) | |||
70 | lpa |= LPA_10FULL; | 70 | lpa |= LPA_10FULL; |
71 | break; | 71 | break; |
72 | default: | 72 | default: |
73 | printk(KERN_WARNING "fixed phy: unknown speed\n"); | 73 | pr_warn("fixed phy: unknown speed\n"); |
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | } | 75 | } |
76 | } else { | 76 | } else { |
@@ -90,7 +90,7 @@ static int fixed_phy_update_regs(struct fixed_phy *fp) | |||
90 | lpa |= LPA_10HALF; | 90 | lpa |= LPA_10HALF; |
91 | break; | 91 | break; |
92 | default: | 92 | default: |
93 | printk(KERN_WARNING "fixed phy: unknown speed\n"); | 93 | pr_warn("fixed phy: unknown speed\n"); |
94 | return -EINVAL; | 94 | return -EINVAL; |
95 | } | 95 | } |
96 | } | 96 | } |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 5061608f408c..31470b0d0c32 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -13,6 +13,9 @@ | |||
13 | * option) any later version. | 13 | * option) any later version. |
14 | * | 14 | * |
15 | */ | 15 | */ |
16 | |||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
16 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
17 | #include <linux/string.h> | 20 | #include <linux/string.h> |
18 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
@@ -148,7 +151,7 @@ int mdiobus_register(struct mii_bus *bus) | |||
148 | 151 | ||
149 | err = device_register(&bus->dev); | 152 | err = device_register(&bus->dev); |
150 | if (err) { | 153 | if (err) { |
151 | printk(KERN_ERR "mii_bus %s failed to register\n", bus->id); | 154 | pr_err("mii_bus %s failed to register\n", bus->id); |
152 | return -EINVAL; | 155 | return -EINVAL; |
153 | } | 156 | } |
154 | 157 | ||
diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index 04bb8fcc0cb5..9a5f234d95b0 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c | |||
@@ -15,6 +15,8 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
18 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 21 | #include <linux/module.h> |
20 | #include <linux/mii.h> | 22 | #include <linux/mii.h> |
@@ -22,6 +24,8 @@ | |||
22 | #include <linux/phy.h> | 24 | #include <linux/phy.h> |
23 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
24 | 26 | ||
27 | #define DEBUG | ||
28 | |||
25 | /* DP83865 phy identifier values */ | 29 | /* DP83865 phy identifier values */ |
26 | #define DP83865_PHY_ID 0x20005c7a | 30 | #define DP83865_PHY_ID 0x20005c7a |
27 | 31 | ||
@@ -112,8 +116,8 @@ static void ns_10_base_t_hdx_loopack(struct phy_device *phydev, int disable) | |||
112 | ns_exp_write(phydev, 0x1c0, | 116 | ns_exp_write(phydev, 0x1c0, |
113 | ns_exp_read(phydev, 0x1c0) & 0xfffe); | 117 | ns_exp_read(phydev, 0x1c0) & 0xfffe); |
114 | 118 | ||
115 | printk(KERN_DEBUG "DP83865 PHY: 10BASE-T HDX loopback %s\n", | 119 | pr_debug("10BASE-T HDX loopback %s\n", |
116 | (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); | 120 | (ns_exp_read(phydev, 0x1c0) & 0x0001) ? "off" : "on"); |
117 | } | 121 | } |
118 | 122 | ||
119 | static int ns_config_init(struct phy_device *phydev) | 123 | static int ns_config_init(struct phy_device *phydev) |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 3cbda0851f83..2e1c23731ded 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -15,6 +15,9 @@ | |||
15 | * option) any later version. | 15 | * option) any later version. |
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
18 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
19 | #include <linux/string.h> | 22 | #include <linux/string.h> |
20 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
@@ -44,18 +47,16 @@ | |||
44 | */ | 47 | */ |
45 | void phy_print_status(struct phy_device *phydev) | 48 | void phy_print_status(struct phy_device *phydev) |
46 | { | 49 | { |
47 | pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev), | ||
48 | phydev->link ? "Up" : "Down"); | ||
49 | if (phydev->link) | 50 | if (phydev->link) |
50 | printk(KERN_CONT " - %d/%s", phydev->speed, | 51 | pr_info("%s - Link is Up - %d/%s\n", |
51 | DUPLEX_FULL == phydev->duplex ? | 52 | dev_name(&phydev->dev), |
52 | "Full" : "Half"); | 53 | phydev->speed, |
53 | 54 | DUPLEX_FULL == phydev->duplex ? "Full" : "Half"); | |
54 | printk(KERN_CONT "\n"); | 55 | else |
56 | pr_info("%s - Link is Down\n", dev_name(&phydev->dev)); | ||
55 | } | 57 | } |
56 | EXPORT_SYMBOL(phy_print_status); | 58 | EXPORT_SYMBOL(phy_print_status); |
57 | 59 | ||
58 | |||
59 | /** | 60 | /** |
60 | * phy_clear_interrupt - Ack the phy device's interrupt | 61 | * phy_clear_interrupt - Ack the phy device's interrupt |
61 | * @phydev: the phy_device struct | 62 | * @phydev: the phy_device struct |
@@ -482,9 +483,8 @@ static void phy_force_reduction(struct phy_device *phydev) | |||
482 | phydev->speed = settings[idx].speed; | 483 | phydev->speed = settings[idx].speed; |
483 | phydev->duplex = settings[idx].duplex; | 484 | phydev->duplex = settings[idx].duplex; |
484 | 485 | ||
485 | pr_info("Trying %d/%s\n", phydev->speed, | 486 | pr_info("Trying %d/%s\n", |
486 | DUPLEX_FULL == phydev->duplex ? | 487 | phydev->speed, DUPLEX_FULL == phydev->duplex ? "FULL" : "HALF"); |
487 | "FULL" : "HALF"); | ||
488 | } | 488 | } |
489 | 489 | ||
490 | 490 | ||
@@ -598,9 +598,8 @@ int phy_start_interrupts(struct phy_device *phydev) | |||
598 | IRQF_SHARED, | 598 | IRQF_SHARED, |
599 | "phy_interrupt", | 599 | "phy_interrupt", |
600 | phydev) < 0) { | 600 | phydev) < 0) { |
601 | printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", | 601 | pr_warn("%s: Can't get IRQ %d (PHY)\n", |
602 | phydev->bus->name, | 602 | phydev->bus->name, phydev->irq); |
603 | phydev->irq); | ||
604 | phydev->irq = PHY_POLL; | 603 | phydev->irq = PHY_POLL; |
605 | return 0; | 604 | return 0; |
606 | } | 605 | } |
@@ -838,10 +837,10 @@ void phy_state_machine(struct work_struct *work) | |||
838 | 837 | ||
839 | phydev->autoneg = AUTONEG_DISABLE; | 838 | phydev->autoneg = AUTONEG_DISABLE; |
840 | 839 | ||
841 | pr_info("Trying %d/%s\n", phydev->speed, | 840 | pr_info("Trying %d/%s\n", |
842 | DUPLEX_FULL == | 841 | phydev->speed, |
843 | phydev->duplex ? | 842 | DUPLEX_FULL == phydev->duplex ? |
844 | "FULL" : "HALF"); | 843 | "FULL" : "HALF"); |
845 | } | 844 | } |
846 | break; | 845 | break; |
847 | case PHY_NOLINK: | 846 | case PHY_NOLINK: |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index de86a5582224..18ab0daf4490 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -14,6 +14,9 @@ | |||
14 | * option) any later version. | 14 | * option) any later version. |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | |||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
19 | |||
17 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
18 | #include <linux/string.h> | 21 | #include <linux/string.h> |
19 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
@@ -975,8 +978,8 @@ int phy_driver_register(struct phy_driver *new_driver) | |||
975 | retval = driver_register(&new_driver->driver); | 978 | retval = driver_register(&new_driver->driver); |
976 | 979 | ||
977 | if (retval) { | 980 | if (retval) { |
978 | printk(KERN_ERR "%s: Error %d in registering driver\n", | 981 | pr_err("%s: Error %d in registering driver\n", |
979 | new_driver->name, retval); | 982 | new_driver->name, retval); |
980 | 983 | ||
981 | return retval; | 984 | return retval; |
982 | } | 985 | } |
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 4eb98bc52a0a..1c3abce78b6a 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c | |||
@@ -11,6 +11,8 @@ | |||
11 | * by the Free Software Foundation. | 11 | * by the Free Software Foundation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
15 | |||
14 | #include <linux/types.h> | 16 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
@@ -356,7 +358,7 @@ static struct spi_driver ks8995_driver = { | |||
356 | 358 | ||
357 | static int __init ks8995_init(void) | 359 | static int __init ks8995_init(void) |
358 | { | 360 | { |
359 | printk(KERN_INFO DRV_DESC " version " DRV_VERSION"\n"); | 361 | pr_info(DRV_DESC " version " DRV_VERSION "\n"); |
360 | 362 | ||
361 | return spi_register_driver(&ks8995_driver); | 363 | return spi_register_driver(&ks8995_driver); |
362 | } | 364 | } |
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index d4c9db3da22a..a34d6bf5e43b 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c | |||
@@ -390,10 +390,10 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) | |||
390 | #endif | 390 | #endif |
391 | #ifdef CONFIG_SLIP_MODE_SLIP6 | 391 | #ifdef CONFIG_SLIP_MODE_SLIP6 |
392 | if (sl->mode & SL_MODE_SLIP6) | 392 | if (sl->mode & SL_MODE_SLIP6) |
393 | count = slip_esc6(p, (unsigned char *) sl->xbuff, len); | 393 | count = slip_esc6(p, sl->xbuff, len); |
394 | else | 394 | else |
395 | #endif | 395 | #endif |
396 | count = slip_esc(p, (unsigned char *) sl->xbuff, len); | 396 | count = slip_esc(p, sl->xbuff, len); |
397 | 397 | ||
398 | /* Order of next two lines is *very* important. | 398 | /* Order of next two lines is *very* important. |
399 | * When we are sending a little amount of data, | 399 | * When we are sending a little amount of data, |
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index d848d4dd5754..187c144c5e5b 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -394,7 +394,7 @@ int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
394 | SET_NETDEV_DEV(dev, &intf->dev); | 394 | SET_NETDEV_DEV(dev, &intf->dev); |
395 | 395 | ||
396 | pnd->dev = dev; | 396 | pnd->dev = dev; |
397 | pnd->usb = usb_get_dev(usbdev); | 397 | pnd->usb = usbdev; |
398 | pnd->intf = intf; | 398 | pnd->intf = intf; |
399 | pnd->data_intf = data_intf; | 399 | pnd->data_intf = data_intf; |
400 | spin_lock_init(&pnd->tx_lock); | 400 | spin_lock_init(&pnd->tx_lock); |
@@ -440,7 +440,6 @@ out: | |||
440 | static void usbpn_disconnect(struct usb_interface *intf) | 440 | static void usbpn_disconnect(struct usb_interface *intf) |
441 | { | 441 | { |
442 | struct usbpn_dev *pnd = usb_get_intfdata(intf); | 442 | struct usbpn_dev *pnd = usb_get_intfdata(intf); |
443 | struct usb_device *usb = pnd->usb; | ||
444 | 443 | ||
445 | if (pnd->disconnected) | 444 | if (pnd->disconnected) |
446 | return; | 445 | return; |
@@ -449,7 +448,6 @@ static void usbpn_disconnect(struct usb_interface *intf) | |||
449 | usb_driver_release_interface(&usbpn_driver, | 448 | usb_driver_release_interface(&usbpn_driver, |
450 | (pnd->intf == intf) ? pnd->data_intf : pnd->intf); | 449 | (pnd->intf == intf) ? pnd->data_intf : pnd->intf); |
451 | unregister_netdev(pnd->dev); | 450 | unregister_netdev(pnd->dev); |
452 | usb_put_dev(usb); | ||
453 | } | 451 | } |
454 | 452 | ||
455 | static struct usb_driver usbpn_driver = { | 453 | static struct usb_driver usbpn_driver = { |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 7023220456c5..a0b5807b30d4 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -1329,8 +1329,6 @@ static int pegasus_probe(struct usb_interface *intf, | |||
1329 | } | 1329 | } |
1330 | pegasus_count++; | 1330 | pegasus_count++; |
1331 | 1331 | ||
1332 | usb_get_dev(dev); | ||
1333 | |||
1334 | net = alloc_etherdev(sizeof(struct pegasus)); | 1332 | net = alloc_etherdev(sizeof(struct pegasus)); |
1335 | if (!net) | 1333 | if (!net) |
1336 | goto out; | 1334 | goto out; |
@@ -1407,7 +1405,6 @@ out2: | |||
1407 | out1: | 1405 | out1: |
1408 | free_netdev(net); | 1406 | free_netdev(net); |
1409 | out: | 1407 | out: |
1410 | usb_put_dev(dev); | ||
1411 | pegasus_dec_workqueue(); | 1408 | pegasus_dec_workqueue(); |
1412 | return res; | 1409 | return res; |
1413 | } | 1410 | } |
@@ -1425,7 +1422,6 @@ static void pegasus_disconnect(struct usb_interface *intf) | |||
1425 | pegasus->flags |= PEGASUS_UNPLUG; | 1422 | pegasus->flags |= PEGASUS_UNPLUG; |
1426 | cancel_delayed_work(&pegasus->carrier_check); | 1423 | cancel_delayed_work(&pegasus->carrier_check); |
1427 | unregister_netdev(pegasus->net); | 1424 | unregister_netdev(pegasus->net); |
1428 | usb_put_dev(interface_to_usbdev(intf)); | ||
1429 | unlink_all_urbs(pegasus); | 1425 | unlink_all_urbs(pegasus); |
1430 | free_all_urbs(pegasus); | 1426 | free_all_urbs(pegasus); |
1431 | free_skb_pool(pegasus); | 1427 | free_skb_pool(pegasus); |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9f58330f1312..ac2e4936b421 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -180,7 +180,40 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) | |||
180 | } | 180 | } |
181 | EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); | 181 | EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); |
182 | 182 | ||
183 | static void intr_complete (struct urb *urb); | 183 | static void intr_complete (struct urb *urb) |
184 | { | ||
185 | struct usbnet *dev = urb->context; | ||
186 | int status = urb->status; | ||
187 | |||
188 | switch (status) { | ||
189 | /* success */ | ||
190 | case 0: | ||
191 | dev->driver_info->status(dev, urb); | ||
192 | break; | ||
193 | |||
194 | /* software-driven interface shutdown */ | ||
195 | case -ENOENT: /* urb killed */ | ||
196 | case -ESHUTDOWN: /* hardware gone */ | ||
197 | netif_dbg(dev, ifdown, dev->net, | ||
198 | "intr shutdown, code %d\n", status); | ||
199 | return; | ||
200 | |||
201 | /* NOTE: not throttling like RX/TX, since this endpoint | ||
202 | * already polls infrequently | ||
203 | */ | ||
204 | default: | ||
205 | netdev_dbg(dev->net, "intr status %d\n", status); | ||
206 | break; | ||
207 | } | ||
208 | |||
209 | if (!netif_running (dev->net)) | ||
210 | return; | ||
211 | |||
212 | status = usb_submit_urb (urb, GFP_ATOMIC); | ||
213 | if (status != 0) | ||
214 | netif_err(dev, timer, dev->net, | ||
215 | "intr resubmit --> %d\n", status); | ||
216 | } | ||
184 | 217 | ||
185 | static int init_status (struct usbnet *dev, struct usb_interface *intf) | 218 | static int init_status (struct usbnet *dev, struct usb_interface *intf) |
186 | { | 219 | { |
@@ -519,42 +552,6 @@ block: | |||
519 | netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n"); | 552 | netif_dbg(dev, rx_err, dev->net, "no read resubmitted\n"); |
520 | } | 553 | } |
521 | 554 | ||
522 | static void intr_complete (struct urb *urb) | ||
523 | { | ||
524 | struct usbnet *dev = urb->context; | ||
525 | int status = urb->status; | ||
526 | |||
527 | switch (status) { | ||
528 | /* success */ | ||
529 | case 0: | ||
530 | dev->driver_info->status(dev, urb); | ||
531 | break; | ||
532 | |||
533 | /* software-driven interface shutdown */ | ||
534 | case -ENOENT: /* urb killed */ | ||
535 | case -ESHUTDOWN: /* hardware gone */ | ||
536 | netif_dbg(dev, ifdown, dev->net, | ||
537 | "intr shutdown, code %d\n", status); | ||
538 | return; | ||
539 | |||
540 | /* NOTE: not throttling like RX/TX, since this endpoint | ||
541 | * already polls infrequently | ||
542 | */ | ||
543 | default: | ||
544 | netdev_dbg(dev->net, "intr status %d\n", status); | ||
545 | break; | ||
546 | } | ||
547 | |||
548 | if (!netif_running (dev->net)) | ||
549 | return; | ||
550 | |||
551 | memset(urb->transfer_buffer, 0, urb->transfer_buffer_length); | ||
552 | status = usb_submit_urb (urb, GFP_ATOMIC); | ||
553 | if (status != 0) | ||
554 | netif_err(dev, timer, dev->net, | ||
555 | "intr resubmit --> %d\n", status); | ||
556 | } | ||
557 | |||
558 | /*-------------------------------------------------------------------------*/ | 555 | /*-------------------------------------------------------------------------*/ |
559 | void usbnet_pause_rx(struct usbnet *dev) | 556 | void usbnet_pause_rx(struct usbnet *dev) |
560 | { | 557 | { |
@@ -1307,7 +1304,6 @@ void usbnet_disconnect (struct usb_interface *intf) | |||
1307 | usb_free_urb(dev->interrupt); | 1304 | usb_free_urb(dev->interrupt); |
1308 | 1305 | ||
1309 | free_netdev(net); | 1306 | free_netdev(net); |
1310 | usb_put_dev (xdev); | ||
1311 | } | 1307 | } |
1312 | EXPORT_SYMBOL_GPL(usbnet_disconnect); | 1308 | EXPORT_SYMBOL_GPL(usbnet_disconnect); |
1313 | 1309 | ||
@@ -1363,8 +1359,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1363 | xdev = interface_to_usbdev (udev); | 1359 | xdev = interface_to_usbdev (udev); |
1364 | interface = udev->cur_altsetting; | 1360 | interface = udev->cur_altsetting; |
1365 | 1361 | ||
1366 | usb_get_dev (xdev); | ||
1367 | |||
1368 | status = -ENOMEM; | 1362 | status = -ENOMEM; |
1369 | 1363 | ||
1370 | // set up our own records | 1364 | // set up our own records |
@@ -1493,7 +1487,6 @@ out3: | |||
1493 | out1: | 1487 | out1: |
1494 | free_netdev(net); | 1488 | free_netdev(net); |
1495 | out: | 1489 | out: |
1496 | usb_put_dev(xdev); | ||
1497 | return status; | 1490 | return status; |
1498 | } | 1491 | } |
1499 | EXPORT_SYMBOL_GPL(usbnet_probe); | 1492 | EXPORT_SYMBOL_GPL(usbnet_probe); |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3f04ba0a5454..93e0cfb739b8 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -1037,7 +1037,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
1037 | #endif | 1037 | #endif |
1038 | dev_dbg(&adapter->netdev->dev, | 1038 | dev_dbg(&adapter->netdev->dev, |
1039 | "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n", | 1039 | "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n", |
1040 | (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd - | 1040 | (u32)(ctx.sop_txd - |
1041 | tq->tx_ring.base), le64_to_cpu(gdesc->txd.addr), | 1041 | tq->tx_ring.base), le64_to_cpu(gdesc->txd.addr), |
1042 | le32_to_cpu(gdesc->dword[2]), le32_to_cpu(gdesc->dword[3])); | 1042 | le32_to_cpu(gdesc->dword[2]), le32_to_cpu(gdesc->dword[3])); |
1043 | 1043 | ||
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index d7a65e141d1a..44db8b75a531 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -231,7 +231,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len) | |||
231 | } | 231 | } |
232 | 232 | ||
233 | p = icp; | 233 | p = icp; |
234 | count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len); | 234 | count = x25_asy_esc(p, sl->xbuff, len); |
235 | 235 | ||
236 | /* Order of next two lines is *very* important. | 236 | /* Order of next two lines is *very* important. |
237 | * When we are sending a little amount of data, | 237 | * When we are sending a little amount of data, |
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 7cbd7d231e11..d09e44970e63 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c | |||
@@ -1268,7 +1268,7 @@ int i2400m_fw_check(struct i2400m *i2400m, const void *bcf, size_t bcf_size) | |||
1268 | size_t leftover, offset, header_len, size; | 1268 | size_t leftover, offset, header_len, size; |
1269 | 1269 | ||
1270 | leftover = top - itr; | 1270 | leftover = top - itr; |
1271 | offset = itr - (const void *) bcf; | 1271 | offset = itr - bcf; |
1272 | if (leftover <= sizeof(*bcf_hdr)) { | 1272 | if (leftover <= sizeof(*bcf_hdr)) { |
1273 | dev_err(dev, "firmware %s: %zu B left at @%zx, " | 1273 | dev_err(dev, "firmware %s: %zu B left at @%zx, " |
1274 | "not enough for BCF header\n", | 1274 | "not enough for BCF header\n", |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 0ac09a2bd144..97afcec24759 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -1738,8 +1738,7 @@ static int adm8211_alloc_rings(struct ieee80211_hw *dev) | |||
1738 | return -ENOMEM; | 1738 | return -ENOMEM; |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | priv->tx_ring = (struct adm8211_desc *)(priv->rx_ring + | 1741 | priv->tx_ring = priv->rx_ring + priv->rx_ring_size; |
1742 | priv->rx_ring_size); | ||
1743 | priv->tx_ring_dma = priv->rx_ring_dma + | 1742 | priv->tx_ring_dma = priv->rx_ring_dma + |
1744 | sizeof(struct adm8211_desc) * priv->rx_ring_size; | 1743 | sizeof(struct adm8211_desc) * priv->rx_ring_size; |
1745 | 1744 | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 520a4b2eb9cc..252c2c2d76c1 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -1997,7 +1997,7 @@ static int mpi_send_packet (struct net_device *dev) | |||
1997 | * ------------------------------------------------ | 1997 | * ------------------------------------------------ |
1998 | */ | 1998 | */ |
1999 | 1999 | ||
2000 | memcpy((char *)ai->txfids[0].virtual_host_addr, | 2000 | memcpy(ai->txfids[0].virtual_host_addr, |
2001 | (char *)&wifictlhdr8023, sizeof(wifictlhdr8023)); | 2001 | (char *)&wifictlhdr8023, sizeof(wifictlhdr8023)); |
2002 | 2002 | ||
2003 | payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr + | 2003 | payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr + |
@@ -4212,7 +4212,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid, | |||
4212 | airo_print_err(ai->dev->name, "%s: len=%d", __func__, len); | 4212 | airo_print_err(ai->dev->name, "%s: len=%d", __func__, len); |
4213 | rc = -1; | 4213 | rc = -1; |
4214 | } else { | 4214 | } else { |
4215 | memcpy((char *)ai->config_desc.virtual_host_addr, | 4215 | memcpy(ai->config_desc.virtual_host_addr, |
4216 | pBuf, len); | 4216 | pBuf, len); |
4217 | 4217 | ||
4218 | rc = issuecommand(ai, &cmd, &rsp); | 4218 | rc = issuecommand(ai, &cmd, &rsp); |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index b869a358ce43..f27e9732951d 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -2585,35 +2585,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, | |||
2585 | return 0; | 2585 | return 0; |
2586 | } | 2586 | } |
2587 | 2587 | ||
2588 | static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, | ||
2589 | struct ieee80211_channel *chan, | ||
2590 | enum nl80211_channel_type channel_type) | ||
2591 | { | ||
2592 | struct ath6kl_vif *vif; | ||
2593 | |||
2594 | /* | ||
2595 | * 'dev' could be NULL if a channel change is required for the hardware | ||
2596 | * device itself, instead of a particular VIF. | ||
2597 | * | ||
2598 | * FIXME: To be handled properly when monitor mode is supported. | ||
2599 | */ | ||
2600 | if (!dev) | ||
2601 | return -EBUSY; | ||
2602 | |||
2603 | vif = netdev_priv(dev); | ||
2604 | |||
2605 | if (!ath6kl_cfg80211_ready(vif)) | ||
2606 | return -EIO; | ||
2607 | |||
2608 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n", | ||
2609 | __func__, chan->center_freq, chan->hw_value); | ||
2610 | vif->next_chan = chan->center_freq; | ||
2611 | vif->next_ch_type = channel_type; | ||
2612 | vif->next_ch_band = chan->band; | ||
2613 | |||
2614 | return 0; | ||
2615 | } | ||
2616 | |||
2617 | static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, | 2588 | static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, |
2618 | u8 *rsn_capab) | 2589 | u8 *rsn_capab) |
2619 | { | 2590 | { |
@@ -2791,7 +2762,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2791 | p.ssid_len = vif->ssid_len; | 2762 | p.ssid_len = vif->ssid_len; |
2792 | memcpy(p.ssid, vif->ssid, vif->ssid_len); | 2763 | memcpy(p.ssid, vif->ssid, vif->ssid_len); |
2793 | p.dot11_auth_mode = vif->dot11_auth_mode; | 2764 | p.dot11_auth_mode = vif->dot11_auth_mode; |
2794 | p.ch = cpu_to_le16(vif->next_chan); | 2765 | p.ch = cpu_to_le16(info->channel->center_freq); |
2795 | 2766 | ||
2796 | /* Enable uAPSD support by default */ | 2767 | /* Enable uAPSD support by default */ |
2797 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); | 2768 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); |
@@ -2815,8 +2786,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2815 | return res; | 2786 | return res; |
2816 | } | 2787 | } |
2817 | 2788 | ||
2818 | if (ath6kl_set_htcap(vif, vif->next_ch_band, | 2789 | if (ath6kl_set_htcap(vif, info->channel->band, |
2819 | vif->next_ch_type != NL80211_CHAN_NO_HT)) | 2790 | info->channel_type != NL80211_CHAN_NO_HT)) |
2820 | return -EIO; | 2791 | return -EIO; |
2821 | 2792 | ||
2822 | /* | 2793 | /* |
@@ -3271,7 +3242,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { | |||
3271 | .suspend = __ath6kl_cfg80211_suspend, | 3242 | .suspend = __ath6kl_cfg80211_suspend, |
3272 | .resume = __ath6kl_cfg80211_resume, | 3243 | .resume = __ath6kl_cfg80211_resume, |
3273 | #endif | 3244 | #endif |
3274 | .set_channel = ath6kl_set_channel, | ||
3275 | .start_ap = ath6kl_start_ap, | 3245 | .start_ap = ath6kl_start_ap, |
3276 | .change_beacon = ath6kl_change_beacon, | 3246 | .change_beacon = ath6kl_change_beacon, |
3277 | .stop_ap = ath6kl_stop_ap, | 3247 | .stop_ap = ath6kl_stop_ap, |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 4d9c6f142698..8443b2a4133e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -553,9 +553,6 @@ struct ath6kl_vif { | |||
553 | u32 last_cancel_roc_id; | 553 | u32 last_cancel_roc_id; |
554 | u32 send_action_id; | 554 | u32 send_action_id; |
555 | bool probe_req_report; | 555 | bool probe_req_report; |
556 | u16 next_chan; | ||
557 | enum nl80211_channel_type next_ch_type; | ||
558 | enum ieee80211_band next_ch_band; | ||
559 | u16 assoc_bss_beacon_int; | 556 | u16 assoc_bss_beacon_int; |
560 | u16 listen_intvl_t; | 557 | u16 listen_intvl_t; |
561 | u16 bmiss_time_t; | 558 | u16 bmiss_time_t; |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index e5524470529c..b836f2795114 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -598,7 +598,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) | |||
598 | 598 | ||
599 | struct ath6kl *ar = vif->ar; | 599 | struct ath6kl *ar = vif->ar; |
600 | 600 | ||
601 | vif->next_chan = channel; | ||
602 | vif->profile.ch = cpu_to_le16(channel); | 601 | vif->profile.ch = cpu_to_le16(channel); |
603 | 602 | ||
604 | switch (vif->nw_type) { | 603 | switch (vif->nw_type) { |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 3f0b84723789..9c41232b0cd0 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -3,7 +3,9 @@ ath9k-y += beacon.o \ | |||
3 | init.o \ | 3 | init.o \ |
4 | main.o \ | 4 | main.o \ |
5 | recv.o \ | 5 | recv.o \ |
6 | xmit.o | 6 | xmit.o \ |
7 | link.o \ | ||
8 | antenna.o | ||
7 | 9 | ||
8 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o | 10 | ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o |
9 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 11 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 5e47ca6d16a8..4a4e8a2b9d2c 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -126,7 +126,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
126 | sc->irq = irq; | 126 | sc->irq = irq; |
127 | 127 | ||
128 | /* Will be cleared in ath9k_start() */ | 128 | /* Will be cleared in ath9k_start() */ |
129 | sc->sc_flags |= SC_OP_INVALID; | 129 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
130 | 130 | ||
131 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 131 | ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
132 | if (ret) { | 132 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c new file mode 100644 index 000000000000..bbcfeb3b2a60 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/antenna.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | ||
20 | int mindelta, int main_rssi_avg, | ||
21 | int alt_rssi_avg, int pkt_count) | ||
22 | { | ||
23 | return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
24 | (alt_rssi_avg > main_rssi_avg + maxdelta)) || | ||
25 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | ||
26 | } | ||
27 | |||
28 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
29 | int curr_main_set, int curr_alt_set, | ||
30 | int alt_rssi_avg, int main_rssi_avg) | ||
31 | { | ||
32 | bool result = false; | ||
33 | switch (div_group) { | ||
34 | case 0: | ||
35 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
36 | result = true; | ||
37 | break; | ||
38 | case 1: | ||
39 | case 2: | ||
40 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
41 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
42 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
43 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
44 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
45 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
46 | (alt_rssi_avg >= 4)) | ||
47 | result = true; | ||
48 | else | ||
49 | result = false; | ||
50 | break; | ||
51 | } | ||
52 | |||
53 | return result; | ||
54 | } | ||
55 | |||
56 | static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | ||
57 | struct ath_hw_antcomb_conf ant_conf, | ||
58 | int main_rssi_avg) | ||
59 | { | ||
60 | antcomb->quick_scan_cnt = 0; | ||
61 | |||
62 | if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) | ||
63 | antcomb->rssi_lna2 = main_rssi_avg; | ||
64 | else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) | ||
65 | antcomb->rssi_lna1 = main_rssi_avg; | ||
66 | |||
67 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | ||
68 | case 0x10: /* LNA2 A-B */ | ||
69 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
70 | antcomb->first_quick_scan_conf = | ||
71 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
72 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
73 | break; | ||
74 | case 0x20: /* LNA1 A-B */ | ||
75 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
76 | antcomb->first_quick_scan_conf = | ||
77 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
78 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
79 | break; | ||
80 | case 0x21: /* LNA1 LNA2 */ | ||
81 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | ||
82 | antcomb->first_quick_scan_conf = | ||
83 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
84 | antcomb->second_quick_scan_conf = | ||
85 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
86 | break; | ||
87 | case 0x12: /* LNA2 LNA1 */ | ||
88 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | ||
89 | antcomb->first_quick_scan_conf = | ||
90 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
91 | antcomb->second_quick_scan_conf = | ||
92 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
93 | break; | ||
94 | case 0x13: /* LNA2 A+B */ | ||
95 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
96 | antcomb->first_quick_scan_conf = | ||
97 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
98 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
99 | break; | ||
100 | case 0x23: /* LNA1 A+B */ | ||
101 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
102 | antcomb->first_quick_scan_conf = | ||
103 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
104 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
105 | break; | ||
106 | default: | ||
107 | break; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | ||
112 | struct ath_hw_antcomb_conf *div_ant_conf, | ||
113 | int main_rssi_avg, int alt_rssi_avg, | ||
114 | int alt_ratio) | ||
115 | { | ||
116 | /* alt_good */ | ||
117 | switch (antcomb->quick_scan_cnt) { | ||
118 | case 0: | ||
119 | /* set alt to main, and alt to first conf */ | ||
120 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
121 | div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; | ||
122 | break; | ||
123 | case 1: | ||
124 | /* set alt to main, and alt to first conf */ | ||
125 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
126 | div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; | ||
127 | antcomb->rssi_first = main_rssi_avg; | ||
128 | antcomb->rssi_second = alt_rssi_avg; | ||
129 | |||
130 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
131 | /* main is LNA1 */ | ||
132 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
133 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
134 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
135 | main_rssi_avg, alt_rssi_avg, | ||
136 | antcomb->total_pkt_count)) | ||
137 | antcomb->first_ratio = true; | ||
138 | else | ||
139 | antcomb->first_ratio = false; | ||
140 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
141 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
142 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
143 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
144 | main_rssi_avg, alt_rssi_avg, | ||
145 | antcomb->total_pkt_count)) | ||
146 | antcomb->first_ratio = true; | ||
147 | else | ||
148 | antcomb->first_ratio = false; | ||
149 | } else { | ||
150 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
151 | (alt_rssi_avg > main_rssi_avg + | ||
152 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
153 | (alt_rssi_avg > main_rssi_avg)) && | ||
154 | (antcomb->total_pkt_count > 50)) | ||
155 | antcomb->first_ratio = true; | ||
156 | else | ||
157 | antcomb->first_ratio = false; | ||
158 | } | ||
159 | break; | ||
160 | case 2: | ||
161 | antcomb->alt_good = false; | ||
162 | antcomb->scan_not_start = false; | ||
163 | antcomb->scan = false; | ||
164 | antcomb->rssi_first = main_rssi_avg; | ||
165 | antcomb->rssi_third = alt_rssi_avg; | ||
166 | |||
167 | if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) | ||
168 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
169 | else if (antcomb->second_quick_scan_conf == | ||
170 | ATH_ANT_DIV_COMB_LNA2) | ||
171 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
172 | else if (antcomb->second_quick_scan_conf == | ||
173 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { | ||
174 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) | ||
175 | antcomb->rssi_lna2 = main_rssi_avg; | ||
176 | else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) | ||
177 | antcomb->rssi_lna1 = main_rssi_avg; | ||
178 | } | ||
179 | |||
180 | if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + | ||
181 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) | ||
182 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
183 | else | ||
184 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
185 | |||
186 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
187 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
188 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
189 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
190 | main_rssi_avg, alt_rssi_avg, | ||
191 | antcomb->total_pkt_count)) | ||
192 | antcomb->second_ratio = true; | ||
193 | else | ||
194 | antcomb->second_ratio = false; | ||
195 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
196 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
197 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
198 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
199 | main_rssi_avg, alt_rssi_avg, | ||
200 | antcomb->total_pkt_count)) | ||
201 | antcomb->second_ratio = true; | ||
202 | else | ||
203 | antcomb->second_ratio = false; | ||
204 | } else { | ||
205 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
206 | (alt_rssi_avg > main_rssi_avg + | ||
207 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
208 | (alt_rssi_avg > main_rssi_avg)) && | ||
209 | (antcomb->total_pkt_count > 50)) | ||
210 | antcomb->second_ratio = true; | ||
211 | else | ||
212 | antcomb->second_ratio = false; | ||
213 | } | ||
214 | |||
215 | /* set alt to the conf with maximun ratio */ | ||
216 | if (antcomb->first_ratio && antcomb->second_ratio) { | ||
217 | if (antcomb->rssi_second > antcomb->rssi_third) { | ||
218 | /* first alt*/ | ||
219 | if ((antcomb->first_quick_scan_conf == | ||
220 | ATH_ANT_DIV_COMB_LNA1) || | ||
221 | (antcomb->first_quick_scan_conf == | ||
222 | ATH_ANT_DIV_COMB_LNA2)) | ||
223 | /* Set alt LNA1 or LNA2*/ | ||
224 | if (div_ant_conf->main_lna_conf == | ||
225 | ATH_ANT_DIV_COMB_LNA2) | ||
226 | div_ant_conf->alt_lna_conf = | ||
227 | ATH_ANT_DIV_COMB_LNA1; | ||
228 | else | ||
229 | div_ant_conf->alt_lna_conf = | ||
230 | ATH_ANT_DIV_COMB_LNA2; | ||
231 | else | ||
232 | /* Set alt to A+B or A-B */ | ||
233 | div_ant_conf->alt_lna_conf = | ||
234 | antcomb->first_quick_scan_conf; | ||
235 | } else if ((antcomb->second_quick_scan_conf == | ||
236 | ATH_ANT_DIV_COMB_LNA1) || | ||
237 | (antcomb->second_quick_scan_conf == | ||
238 | ATH_ANT_DIV_COMB_LNA2)) { | ||
239 | /* Set alt LNA1 or LNA2 */ | ||
240 | if (div_ant_conf->main_lna_conf == | ||
241 | ATH_ANT_DIV_COMB_LNA2) | ||
242 | div_ant_conf->alt_lna_conf = | ||
243 | ATH_ANT_DIV_COMB_LNA1; | ||
244 | else | ||
245 | div_ant_conf->alt_lna_conf = | ||
246 | ATH_ANT_DIV_COMB_LNA2; | ||
247 | } else { | ||
248 | /* Set alt to A+B or A-B */ | ||
249 | div_ant_conf->alt_lna_conf = | ||
250 | antcomb->second_quick_scan_conf; | ||
251 | } | ||
252 | } else if (antcomb->first_ratio) { | ||
253 | /* first alt */ | ||
254 | if ((antcomb->first_quick_scan_conf == | ||
255 | ATH_ANT_DIV_COMB_LNA1) || | ||
256 | (antcomb->first_quick_scan_conf == | ||
257 | ATH_ANT_DIV_COMB_LNA2)) | ||
258 | /* Set alt LNA1 or LNA2 */ | ||
259 | if (div_ant_conf->main_lna_conf == | ||
260 | ATH_ANT_DIV_COMB_LNA2) | ||
261 | div_ant_conf->alt_lna_conf = | ||
262 | ATH_ANT_DIV_COMB_LNA1; | ||
263 | else | ||
264 | div_ant_conf->alt_lna_conf = | ||
265 | ATH_ANT_DIV_COMB_LNA2; | ||
266 | else | ||
267 | /* Set alt to A+B or A-B */ | ||
268 | div_ant_conf->alt_lna_conf = | ||
269 | antcomb->first_quick_scan_conf; | ||
270 | } else if (antcomb->second_ratio) { | ||
271 | /* second alt */ | ||
272 | if ((antcomb->second_quick_scan_conf == | ||
273 | ATH_ANT_DIV_COMB_LNA1) || | ||
274 | (antcomb->second_quick_scan_conf == | ||
275 | ATH_ANT_DIV_COMB_LNA2)) | ||
276 | /* Set alt LNA1 or LNA2 */ | ||
277 | if (div_ant_conf->main_lna_conf == | ||
278 | ATH_ANT_DIV_COMB_LNA2) | ||
279 | div_ant_conf->alt_lna_conf = | ||
280 | ATH_ANT_DIV_COMB_LNA1; | ||
281 | else | ||
282 | div_ant_conf->alt_lna_conf = | ||
283 | ATH_ANT_DIV_COMB_LNA2; | ||
284 | else | ||
285 | /* Set alt to A+B or A-B */ | ||
286 | div_ant_conf->alt_lna_conf = | ||
287 | antcomb->second_quick_scan_conf; | ||
288 | } else { | ||
289 | /* main is largest */ | ||
290 | if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || | ||
291 | (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) | ||
292 | /* Set alt LNA1 or LNA2 */ | ||
293 | if (div_ant_conf->main_lna_conf == | ||
294 | ATH_ANT_DIV_COMB_LNA2) | ||
295 | div_ant_conf->alt_lna_conf = | ||
296 | ATH_ANT_DIV_COMB_LNA1; | ||
297 | else | ||
298 | div_ant_conf->alt_lna_conf = | ||
299 | ATH_ANT_DIV_COMB_LNA2; | ||
300 | else | ||
301 | /* Set alt to A+B or A-B */ | ||
302 | div_ant_conf->alt_lna_conf = antcomb->main_conf; | ||
303 | } | ||
304 | break; | ||
305 | default: | ||
306 | break; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | ||
311 | struct ath_ant_comb *antcomb, | ||
312 | int alt_ratio) | ||
313 | { | ||
314 | if (ant_conf->div_group == 0) { | ||
315 | /* Adjust the fast_div_bias based on main and alt lna conf */ | ||
316 | switch ((ant_conf->main_lna_conf << 4) | | ||
317 | ant_conf->alt_lna_conf) { | ||
318 | case 0x01: /* A-B LNA2 */ | ||
319 | ant_conf->fast_div_bias = 0x3b; | ||
320 | break; | ||
321 | case 0x02: /* A-B LNA1 */ | ||
322 | ant_conf->fast_div_bias = 0x3d; | ||
323 | break; | ||
324 | case 0x03: /* A-B A+B */ | ||
325 | ant_conf->fast_div_bias = 0x1; | ||
326 | break; | ||
327 | case 0x10: /* LNA2 A-B */ | ||
328 | ant_conf->fast_div_bias = 0x7; | ||
329 | break; | ||
330 | case 0x12: /* LNA2 LNA1 */ | ||
331 | ant_conf->fast_div_bias = 0x2; | ||
332 | break; | ||
333 | case 0x13: /* LNA2 A+B */ | ||
334 | ant_conf->fast_div_bias = 0x7; | ||
335 | break; | ||
336 | case 0x20: /* LNA1 A-B */ | ||
337 | ant_conf->fast_div_bias = 0x6; | ||
338 | break; | ||
339 | case 0x21: /* LNA1 LNA2 */ | ||
340 | ant_conf->fast_div_bias = 0x0; | ||
341 | break; | ||
342 | case 0x23: /* LNA1 A+B */ | ||
343 | ant_conf->fast_div_bias = 0x6; | ||
344 | break; | ||
345 | case 0x30: /* A+B A-B */ | ||
346 | ant_conf->fast_div_bias = 0x1; | ||
347 | break; | ||
348 | case 0x31: /* A+B LNA2 */ | ||
349 | ant_conf->fast_div_bias = 0x3b; | ||
350 | break; | ||
351 | case 0x32: /* A+B LNA1 */ | ||
352 | ant_conf->fast_div_bias = 0x3d; | ||
353 | break; | ||
354 | default: | ||
355 | break; | ||
356 | } | ||
357 | } else if (ant_conf->div_group == 1) { | ||
358 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
359 | switch ((ant_conf->main_lna_conf << 4) | | ||
360 | ant_conf->alt_lna_conf) { | ||
361 | case 0x01: /* A-B LNA2 */ | ||
362 | ant_conf->fast_div_bias = 0x1; | ||
363 | ant_conf->main_gaintb = 0; | ||
364 | ant_conf->alt_gaintb = 0; | ||
365 | break; | ||
366 | case 0x02: /* A-B LNA1 */ | ||
367 | ant_conf->fast_div_bias = 0x1; | ||
368 | ant_conf->main_gaintb = 0; | ||
369 | ant_conf->alt_gaintb = 0; | ||
370 | break; | ||
371 | case 0x03: /* A-B A+B */ | ||
372 | ant_conf->fast_div_bias = 0x1; | ||
373 | ant_conf->main_gaintb = 0; | ||
374 | ant_conf->alt_gaintb = 0; | ||
375 | break; | ||
376 | case 0x10: /* LNA2 A-B */ | ||
377 | if (!(antcomb->scan) && | ||
378 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
379 | ant_conf->fast_div_bias = 0x3f; | ||
380 | else | ||
381 | ant_conf->fast_div_bias = 0x1; | ||
382 | ant_conf->main_gaintb = 0; | ||
383 | ant_conf->alt_gaintb = 0; | ||
384 | break; | ||
385 | case 0x12: /* LNA2 LNA1 */ | ||
386 | ant_conf->fast_div_bias = 0x1; | ||
387 | ant_conf->main_gaintb = 0; | ||
388 | ant_conf->alt_gaintb = 0; | ||
389 | break; | ||
390 | case 0x13: /* LNA2 A+B */ | ||
391 | if (!(antcomb->scan) && | ||
392 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
393 | ant_conf->fast_div_bias = 0x3f; | ||
394 | else | ||
395 | ant_conf->fast_div_bias = 0x1; | ||
396 | ant_conf->main_gaintb = 0; | ||
397 | ant_conf->alt_gaintb = 0; | ||
398 | break; | ||
399 | case 0x20: /* LNA1 A-B */ | ||
400 | if (!(antcomb->scan) && | ||
401 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
402 | ant_conf->fast_div_bias = 0x3f; | ||
403 | else | ||
404 | ant_conf->fast_div_bias = 0x1; | ||
405 | ant_conf->main_gaintb = 0; | ||
406 | ant_conf->alt_gaintb = 0; | ||
407 | break; | ||
408 | case 0x21: /* LNA1 LNA2 */ | ||
409 | ant_conf->fast_div_bias = 0x1; | ||
410 | ant_conf->main_gaintb = 0; | ||
411 | ant_conf->alt_gaintb = 0; | ||
412 | break; | ||
413 | case 0x23: /* LNA1 A+B */ | ||
414 | if (!(antcomb->scan) && | ||
415 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
416 | ant_conf->fast_div_bias = 0x3f; | ||
417 | else | ||
418 | ant_conf->fast_div_bias = 0x1; | ||
419 | ant_conf->main_gaintb = 0; | ||
420 | ant_conf->alt_gaintb = 0; | ||
421 | break; | ||
422 | case 0x30: /* A+B A-B */ | ||
423 | ant_conf->fast_div_bias = 0x1; | ||
424 | ant_conf->main_gaintb = 0; | ||
425 | ant_conf->alt_gaintb = 0; | ||
426 | break; | ||
427 | case 0x31: /* A+B LNA2 */ | ||
428 | ant_conf->fast_div_bias = 0x1; | ||
429 | ant_conf->main_gaintb = 0; | ||
430 | ant_conf->alt_gaintb = 0; | ||
431 | break; | ||
432 | case 0x32: /* A+B LNA1 */ | ||
433 | ant_conf->fast_div_bias = 0x1; | ||
434 | ant_conf->main_gaintb = 0; | ||
435 | ant_conf->alt_gaintb = 0; | ||
436 | break; | ||
437 | default: | ||
438 | break; | ||
439 | } | ||
440 | } else if (ant_conf->div_group == 2) { | ||
441 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
442 | switch ((ant_conf->main_lna_conf << 4) | | ||
443 | ant_conf->alt_lna_conf) { | ||
444 | case 0x01: /* A-B LNA2 */ | ||
445 | ant_conf->fast_div_bias = 0x1; | ||
446 | ant_conf->main_gaintb = 0; | ||
447 | ant_conf->alt_gaintb = 0; | ||
448 | break; | ||
449 | case 0x02: /* A-B LNA1 */ | ||
450 | ant_conf->fast_div_bias = 0x1; | ||
451 | ant_conf->main_gaintb = 0; | ||
452 | ant_conf->alt_gaintb = 0; | ||
453 | break; | ||
454 | case 0x03: /* A-B A+B */ | ||
455 | ant_conf->fast_div_bias = 0x1; | ||
456 | ant_conf->main_gaintb = 0; | ||
457 | ant_conf->alt_gaintb = 0; | ||
458 | break; | ||
459 | case 0x10: /* LNA2 A-B */ | ||
460 | if (!(antcomb->scan) && | ||
461 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
462 | ant_conf->fast_div_bias = 0x1; | ||
463 | else | ||
464 | ant_conf->fast_div_bias = 0x2; | ||
465 | ant_conf->main_gaintb = 0; | ||
466 | ant_conf->alt_gaintb = 0; | ||
467 | break; | ||
468 | case 0x12: /* LNA2 LNA1 */ | ||
469 | ant_conf->fast_div_bias = 0x1; | ||
470 | ant_conf->main_gaintb = 0; | ||
471 | ant_conf->alt_gaintb = 0; | ||
472 | break; | ||
473 | case 0x13: /* LNA2 A+B */ | ||
474 | if (!(antcomb->scan) && | ||
475 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
476 | ant_conf->fast_div_bias = 0x1; | ||
477 | else | ||
478 | ant_conf->fast_div_bias = 0x2; | ||
479 | ant_conf->main_gaintb = 0; | ||
480 | ant_conf->alt_gaintb = 0; | ||
481 | break; | ||
482 | case 0x20: /* LNA1 A-B */ | ||
483 | if (!(antcomb->scan) && | ||
484 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
485 | ant_conf->fast_div_bias = 0x1; | ||
486 | else | ||
487 | ant_conf->fast_div_bias = 0x2; | ||
488 | ant_conf->main_gaintb = 0; | ||
489 | ant_conf->alt_gaintb = 0; | ||
490 | break; | ||
491 | case 0x21: /* LNA1 LNA2 */ | ||
492 | ant_conf->fast_div_bias = 0x1; | ||
493 | ant_conf->main_gaintb = 0; | ||
494 | ant_conf->alt_gaintb = 0; | ||
495 | break; | ||
496 | case 0x23: /* LNA1 A+B */ | ||
497 | if (!(antcomb->scan) && | ||
498 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
499 | ant_conf->fast_div_bias = 0x1; | ||
500 | else | ||
501 | ant_conf->fast_div_bias = 0x2; | ||
502 | ant_conf->main_gaintb = 0; | ||
503 | ant_conf->alt_gaintb = 0; | ||
504 | break; | ||
505 | case 0x30: /* A+B A-B */ | ||
506 | ant_conf->fast_div_bias = 0x1; | ||
507 | ant_conf->main_gaintb = 0; | ||
508 | ant_conf->alt_gaintb = 0; | ||
509 | break; | ||
510 | case 0x31: /* A+B LNA2 */ | ||
511 | ant_conf->fast_div_bias = 0x1; | ||
512 | ant_conf->main_gaintb = 0; | ||
513 | ant_conf->alt_gaintb = 0; | ||
514 | break; | ||
515 | case 0x32: /* A+B LNA1 */ | ||
516 | ant_conf->fast_div_bias = 0x1; | ||
517 | ant_conf->main_gaintb = 0; | ||
518 | ant_conf->alt_gaintb = 0; | ||
519 | break; | ||
520 | default: | ||
521 | break; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | ||
527 | { | ||
528 | struct ath_hw_antcomb_conf div_ant_conf; | ||
529 | struct ath_ant_comb *antcomb = &sc->ant_comb; | ||
530 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||
531 | int curr_main_set; | ||
532 | int main_rssi = rs->rs_rssi_ctl0; | ||
533 | int alt_rssi = rs->rs_rssi_ctl1; | ||
534 | int rx_ant_conf, main_ant_conf; | ||
535 | bool short_scan = false; | ||
536 | |||
537 | rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & | ||
538 | ATH_ANT_RX_MASK; | ||
539 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | ||
540 | ATH_ANT_RX_MASK; | ||
541 | |||
542 | /* Record packet only when both main_rssi and alt_rssi is positive */ | ||
543 | if (main_rssi > 0 && alt_rssi > 0) { | ||
544 | antcomb->total_pkt_count++; | ||
545 | antcomb->main_total_rssi += main_rssi; | ||
546 | antcomb->alt_total_rssi += alt_rssi; | ||
547 | if (main_ant_conf == rx_ant_conf) | ||
548 | antcomb->main_recv_cnt++; | ||
549 | else | ||
550 | antcomb->alt_recv_cnt++; | ||
551 | } | ||
552 | |||
553 | /* Short scan check */ | ||
554 | if (antcomb->scan && antcomb->alt_good) { | ||
555 | if (time_after(jiffies, antcomb->scan_start_time + | ||
556 | msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) | ||
557 | short_scan = true; | ||
558 | else | ||
559 | if (antcomb->total_pkt_count == | ||
560 | ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { | ||
561 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
562 | antcomb->total_pkt_count); | ||
563 | if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
564 | short_scan = true; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || | ||
569 | rs->rs_moreaggr) && !short_scan) | ||
570 | return; | ||
571 | |||
572 | if (antcomb->total_pkt_count) { | ||
573 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
574 | antcomb->total_pkt_count); | ||
575 | main_rssi_avg = (antcomb->main_total_rssi / | ||
576 | antcomb->total_pkt_count); | ||
577 | alt_rssi_avg = (antcomb->alt_total_rssi / | ||
578 | antcomb->total_pkt_count); | ||
579 | } | ||
580 | |||
581 | |||
582 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||
583 | curr_alt_set = div_ant_conf.alt_lna_conf; | ||
584 | curr_main_set = div_ant_conf.main_lna_conf; | ||
585 | |||
586 | antcomb->count++; | ||
587 | |||
588 | if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { | ||
589 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | ||
590 | ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, | ||
591 | main_rssi_avg); | ||
592 | antcomb->alt_good = true; | ||
593 | } else { | ||
594 | antcomb->alt_good = false; | ||
595 | } | ||
596 | |||
597 | antcomb->count = 0; | ||
598 | antcomb->scan = true; | ||
599 | antcomb->scan_not_start = true; | ||
600 | } | ||
601 | |||
602 | if (!antcomb->scan) { | ||
603 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, | ||
604 | alt_ratio, curr_main_set, curr_alt_set, | ||
605 | alt_rssi_avg, main_rssi_avg)) { | ||
606 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | ||
607 | /* Switch main and alt LNA */ | ||
608 | div_ant_conf.main_lna_conf = | ||
609 | ATH_ANT_DIV_COMB_LNA2; | ||
610 | div_ant_conf.alt_lna_conf = | ||
611 | ATH_ANT_DIV_COMB_LNA1; | ||
612 | } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { | ||
613 | div_ant_conf.main_lna_conf = | ||
614 | ATH_ANT_DIV_COMB_LNA1; | ||
615 | div_ant_conf.alt_lna_conf = | ||
616 | ATH_ANT_DIV_COMB_LNA2; | ||
617 | } | ||
618 | |||
619 | goto div_comb_done; | ||
620 | } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && | ||
621 | (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { | ||
622 | /* Set alt to another LNA */ | ||
623 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) | ||
624 | div_ant_conf.alt_lna_conf = | ||
625 | ATH_ANT_DIV_COMB_LNA1; | ||
626 | else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) | ||
627 | div_ant_conf.alt_lna_conf = | ||
628 | ATH_ANT_DIV_COMB_LNA2; | ||
629 | |||
630 | goto div_comb_done; | ||
631 | } | ||
632 | |||
633 | if ((alt_rssi_avg < (main_rssi_avg + | ||
634 | div_ant_conf.lna1_lna2_delta))) | ||
635 | goto div_comb_done; | ||
636 | } | ||
637 | |||
638 | if (!antcomb->scan_not_start) { | ||
639 | switch (curr_alt_set) { | ||
640 | case ATH_ANT_DIV_COMB_LNA2: | ||
641 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
642 | antcomb->rssi_lna1 = main_rssi_avg; | ||
643 | antcomb->scan = true; | ||
644 | /* set to A+B */ | ||
645 | div_ant_conf.main_lna_conf = | ||
646 | ATH_ANT_DIV_COMB_LNA1; | ||
647 | div_ant_conf.alt_lna_conf = | ||
648 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
649 | break; | ||
650 | case ATH_ANT_DIV_COMB_LNA1: | ||
651 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
652 | antcomb->rssi_lna2 = main_rssi_avg; | ||
653 | antcomb->scan = true; | ||
654 | /* set to A+B */ | ||
655 | div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
656 | div_ant_conf.alt_lna_conf = | ||
657 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
658 | break; | ||
659 | case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: | ||
660 | antcomb->rssi_add = alt_rssi_avg; | ||
661 | antcomb->scan = true; | ||
662 | /* set to A-B */ | ||
663 | div_ant_conf.alt_lna_conf = | ||
664 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
665 | break; | ||
666 | case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: | ||
667 | antcomb->rssi_sub = alt_rssi_avg; | ||
668 | antcomb->scan = false; | ||
669 | if (antcomb->rssi_lna2 > | ||
670 | (antcomb->rssi_lna1 + | ||
671 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { | ||
672 | /* use LNA2 as main LNA */ | ||
673 | if ((antcomb->rssi_add > antcomb->rssi_lna1) && | ||
674 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
675 | /* set to A+B */ | ||
676 | div_ant_conf.main_lna_conf = | ||
677 | ATH_ANT_DIV_COMB_LNA2; | ||
678 | div_ant_conf.alt_lna_conf = | ||
679 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
680 | } else if (antcomb->rssi_sub > | ||
681 | antcomb->rssi_lna1) { | ||
682 | /* set to A-B */ | ||
683 | div_ant_conf.main_lna_conf = | ||
684 | ATH_ANT_DIV_COMB_LNA2; | ||
685 | div_ant_conf.alt_lna_conf = | ||
686 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
687 | } else { | ||
688 | /* set to LNA1 */ | ||
689 | div_ant_conf.main_lna_conf = | ||
690 | ATH_ANT_DIV_COMB_LNA2; | ||
691 | div_ant_conf.alt_lna_conf = | ||
692 | ATH_ANT_DIV_COMB_LNA1; | ||
693 | } | ||
694 | } else { | ||
695 | /* use LNA1 as main LNA */ | ||
696 | if ((antcomb->rssi_add > antcomb->rssi_lna2) && | ||
697 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
698 | /* set to A+B */ | ||
699 | div_ant_conf.main_lna_conf = | ||
700 | ATH_ANT_DIV_COMB_LNA1; | ||
701 | div_ant_conf.alt_lna_conf = | ||
702 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
703 | } else if (antcomb->rssi_sub > | ||
704 | antcomb->rssi_lna1) { | ||
705 | /* set to A-B */ | ||
706 | div_ant_conf.main_lna_conf = | ||
707 | ATH_ANT_DIV_COMB_LNA1; | ||
708 | div_ant_conf.alt_lna_conf = | ||
709 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
710 | } else { | ||
711 | /* set to LNA2 */ | ||
712 | div_ant_conf.main_lna_conf = | ||
713 | ATH_ANT_DIV_COMB_LNA1; | ||
714 | div_ant_conf.alt_lna_conf = | ||
715 | ATH_ANT_DIV_COMB_LNA2; | ||
716 | } | ||
717 | } | ||
718 | break; | ||
719 | default: | ||
720 | break; | ||
721 | } | ||
722 | } else { | ||
723 | if (!antcomb->alt_good) { | ||
724 | antcomb->scan_not_start = false; | ||
725 | /* Set alt to another LNA */ | ||
726 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { | ||
727 | div_ant_conf.main_lna_conf = | ||
728 | ATH_ANT_DIV_COMB_LNA2; | ||
729 | div_ant_conf.alt_lna_conf = | ||
730 | ATH_ANT_DIV_COMB_LNA1; | ||
731 | } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { | ||
732 | div_ant_conf.main_lna_conf = | ||
733 | ATH_ANT_DIV_COMB_LNA1; | ||
734 | div_ant_conf.alt_lna_conf = | ||
735 | ATH_ANT_DIV_COMB_LNA2; | ||
736 | } | ||
737 | goto div_comb_done; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, | ||
742 | main_rssi_avg, alt_rssi_avg, | ||
743 | alt_ratio); | ||
744 | |||
745 | antcomb->quick_scan_cnt++; | ||
746 | |||
747 | div_comb_done: | ||
748 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); | ||
749 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | ||
750 | |||
751 | antcomb->scan_start_time = jiffies; | ||
752 | antcomb->total_pkt_count = 0; | ||
753 | antcomb->main_total_rssi = 0; | ||
754 | antcomb->alt_total_rssi = 0; | ||
755 | antcomb->main_recv_cnt = 0; | ||
756 | antcomb->alt_recv_cnt = 0; | ||
757 | } | ||
758 | |||
759 | void ath_ant_comb_update(struct ath_softc *sc) | ||
760 | { | ||
761 | struct ath_hw *ah = sc->sc_ah; | ||
762 | struct ath_hw_antcomb_conf div_ant_conf; | ||
763 | u8 lna_conf; | ||
764 | |||
765 | ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); | ||
766 | |||
767 | if (sc->ant_rx == 1) | ||
768 | lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
769 | else | ||
770 | lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
771 | |||
772 | div_ant_conf.main_lna_conf = lna_conf; | ||
773 | div_ant_conf.alt_lna_conf = lna_conf; | ||
774 | |||
775 | ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); | ||
776 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 9fdd70fcaf5b..d7deb8c9f299 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -653,7 +653,6 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | |||
653 | } | 653 | } |
654 | 654 | ||
655 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | 655 | static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, |
656 | u8 num_chains, | ||
657 | struct coeff *coeff, | 656 | struct coeff *coeff, |
658 | bool is_reusable) | 657 | bool is_reusable) |
659 | { | 658 | { |
@@ -677,7 +676,9 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
677 | } | 676 | } |
678 | 677 | ||
679 | /* Load the average of 2 passes */ | 678 | /* Load the average of 2 passes */ |
680 | for (i = 0; i < num_chains; i++) { | 679 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
680 | if (!(ah->txchainmask & (1 << i))) | ||
681 | continue; | ||
681 | nmeasurement = REG_READ_FIELD(ah, | 682 | nmeasurement = REG_READ_FIELD(ah, |
682 | AR_PHY_TX_IQCAL_STATUS_B0, | 683 | AR_PHY_TX_IQCAL_STATUS_B0, |
683 | AR_PHY_CALIBRATED_GAINS_0); | 684 | AR_PHY_CALIBRATED_GAINS_0); |
@@ -767,16 +768,13 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
767 | }; | 768 | }; |
768 | struct coeff coeff; | 769 | struct coeff coeff; |
769 | s32 iq_res[6]; | 770 | s32 iq_res[6]; |
770 | u8 num_chains = 0; | ||
771 | int i, im, j; | 771 | int i, im, j; |
772 | int nmeasurement; | 772 | int nmeasurement; |
773 | 773 | ||
774 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | 774 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { |
775 | if (ah->txchainmask & (1 << i)) | 775 | if (!(ah->txchainmask & (1 << i))) |
776 | num_chains++; | 776 | continue; |
777 | } | ||
778 | 777 | ||
779 | for (i = 0; i < num_chains; i++) { | ||
780 | nmeasurement = REG_READ_FIELD(ah, | 778 | nmeasurement = REG_READ_FIELD(ah, |
781 | AR_PHY_TX_IQCAL_STATUS_B0, | 779 | AR_PHY_TX_IQCAL_STATUS_B0, |
782 | AR_PHY_CALIBRATED_GAINS_0); | 780 | AR_PHY_CALIBRATED_GAINS_0); |
@@ -839,8 +837,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable) | |||
839 | coeff.phs_coeff[i][im] -= 128; | 837 | coeff.phs_coeff[i][im] -= 128; |
840 | } | 838 | } |
841 | } | 839 | } |
842 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, | 840 | ar9003_hw_tx_iqcal_load_avg_2_passes(ah, &coeff, is_reusable); |
843 | &coeff, is_reusable); | ||
844 | 841 | ||
845 | return; | 842 | return; |
846 | 843 | ||
@@ -901,7 +898,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
901 | bool is_reusable = true, status = true; | 898 | bool is_reusable = true, status = true; |
902 | bool run_rtt_cal = false, run_agc_cal; | 899 | bool run_rtt_cal = false, run_agc_cal; |
903 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); | 900 | bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); |
904 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
905 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | | 901 | u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | |
906 | AR_PHY_AGC_CONTROL_FLTR_CAL | | 902 | AR_PHY_AGC_CONTROL_FLTR_CAL | |
907 | AR_PHY_AGC_CONTROL_PKDET_CAL; | 903 | AR_PHY_AGC_CONTROL_PKDET_CAL; |
@@ -970,7 +966,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
970 | } else if (caldata && !caldata->done_txiqcal_once) | 966 | } else if (caldata && !caldata->done_txiqcal_once) |
971 | run_agc_cal = true; | 967 | run_agc_cal = true; |
972 | 968 | ||
973 | if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) | 969 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
974 | ar9003_mci_init_cal_req(ah, &is_reusable); | 970 | ar9003_mci_init_cal_req(ah, &is_reusable); |
975 | 971 | ||
976 | if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) { | 972 | if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) { |
@@ -993,7 +989,7 @@ skip_tx_iqcal: | |||
993 | 0, AH_WAIT_TIMEOUT); | 989 | 0, AH_WAIT_TIMEOUT); |
994 | } | 990 | } |
995 | 991 | ||
996 | if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) | 992 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
997 | ar9003_mci_init_cal_done(ah); | 993 | ar9003_mci_init_cal_done(ah); |
998 | 994 | ||
999 | if (rtt && !run_rtt_cal) { | 995 | if (rtt && !run_rtt_cal) { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index dfb0441f406c..b1e59236d245 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3178,7 +3178,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3178 | mdata_size, length); | 3178 | mdata_size, length); |
3179 | return -1; | 3179 | return -1; |
3180 | } | 3180 | } |
3181 | memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); | 3181 | memcpy(mptr, word + COMP_HDR_LEN, length); |
3182 | ath_dbg(common, EEPROM, | 3182 | ath_dbg(common, EEPROM, |
3183 | "restored eeprom %d: uncompressed, length %d\n", | 3183 | "restored eeprom %d: uncompressed, length %d\n", |
3184 | it, length); | 3184 | it, length); |
@@ -3199,7 +3199,7 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
3199 | "restore eeprom %d: block, reference %d, length %d\n", | 3199 | "restore eeprom %d: block, reference %d, length %d\n", |
3200 | it, reference, length); | 3200 | it, reference, length); |
3201 | ar9300_uncompress_block(ah, mptr, mdata_size, | 3201 | ar9300_uncompress_block(ah, mptr, mdata_size, |
3202 | (u8 *) (word + COMP_HDR_LEN), length); | 3202 | (word + COMP_HDR_LEN), length); |
3203 | break; | 3203 | break; |
3204 | default: | 3204 | default: |
3205 | ath_dbg(common, EEPROM, "unknown compression code %d\n", code); | 3205 | ath_dbg(common, EEPROM, "unknown compression code %d\n", code); |
@@ -3412,11 +3412,11 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
3412 | if (!dump_base_hdr) { | 3412 | if (!dump_base_hdr) { |
3413 | len += snprintf(buf + len, size - len, | 3413 | len += snprintf(buf + len, size - len, |
3414 | "%20s :\n", "2GHz modal Header"); | 3414 | "%20s :\n", "2GHz modal Header"); |
3415 | len += ar9003_dump_modal_eeprom(buf, len, size, | 3415 | len = ar9003_dump_modal_eeprom(buf, len, size, |
3416 | &eep->modalHeader2G); | 3416 | &eep->modalHeader2G); |
3417 | len += snprintf(buf + len, size - len, | 3417 | len += snprintf(buf + len, size - len, |
3418 | "%20s :\n", "5GHz modal Header"); | 3418 | "%20s :\n", "5GHz modal Header"); |
3419 | len += ar9003_dump_modal_eeprom(buf, len, size, | 3419 | len = ar9003_dump_modal_eeprom(buf, len, size, |
3420 | &eep->modalHeader5G); | 3420 | &eep->modalHeader5G); |
3421 | goto out; | 3421 | goto out; |
3422 | } | 3422 | } |
@@ -3613,6 +3613,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3613 | value = ar9003_switch_com_spdt_get(ah, is2ghz); | 3613 | value = ar9003_switch_com_spdt_get(ah, is2ghz); |
3614 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, | 3614 | REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, |
3615 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); | 3615 | AR_SWITCH_TABLE_COM_SPDT_ALL, value); |
3616 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE); | ||
3616 | } | 3617 | } |
3617 | 3618 | ||
3618 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | 3619 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index ffbb180f91e1..b1ced2a76da3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -35,31 +35,30 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, | |||
35 | struct ath_common *common = ath9k_hw_common(ah); | 35 | struct ath_common *common = ath9k_hw_common(ah); |
36 | 36 | ||
37 | while (time_out) { | 37 | while (time_out) { |
38 | if (REG_READ(ah, address) & bit_position) { | 38 | if (!(REG_READ(ah, address) & bit_position)) { |
39 | REG_WRITE(ah, address, bit_position); | 39 | udelay(10); |
40 | 40 | time_out -= 10; | |
41 | if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) { | ||
42 | if (bit_position & | ||
43 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) | ||
44 | ar9003_mci_reset_req_wakeup(ah); | ||
45 | |||
46 | if (bit_position & | ||
47 | (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | | ||
48 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) | ||
49 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
50 | AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); | ||
51 | |||
52 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
53 | AR_MCI_INTERRUPT_RX_MSG); | ||
54 | } | ||
55 | break; | ||
56 | } | ||
57 | 41 | ||
58 | udelay(10); | 42 | if (time_out < 0) |
59 | time_out -= 10; | 43 | break; |
44 | else | ||
45 | continue; | ||
46 | } | ||
47 | REG_WRITE(ah, address, bit_position); | ||
60 | 48 | ||
61 | if (time_out < 0) | 49 | if (address != AR_MCI_INTERRUPT_RX_MSG_RAW) |
62 | break; | 50 | break; |
51 | |||
52 | if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) | ||
53 | ar9003_mci_reset_req_wakeup(ah); | ||
54 | |||
55 | if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | | ||
56 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) | ||
57 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | ||
58 | AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); | ||
59 | |||
60 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG); | ||
61 | break; | ||
63 | } | 62 | } |
64 | 63 | ||
65 | if (time_out <= 0) { | 64 | if (time_out <= 0) { |
@@ -127,14 +126,13 @@ static void ar9003_mci_send_coex_version_query(struct ath_hw *ah, | |||
127 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 126 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
128 | u32 payload[4] = {0, 0, 0, 0}; | 127 | u32 payload[4] = {0, 0, 0, 0}; |
129 | 128 | ||
130 | if (!mci->bt_version_known && | 129 | if (mci->bt_version_known || |
131 | (mci->bt_state != MCI_BT_SLEEP)) { | 130 | (mci->bt_state == MCI_BT_SLEEP)) |
132 | MCI_GPM_SET_TYPE_OPCODE(payload, | 131 | return; |
133 | MCI_GPM_COEX_AGENT, | 132 | |
134 | MCI_GPM_COEX_VERSION_QUERY); | 133 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, |
135 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 134 | MCI_GPM_COEX_VERSION_QUERY); |
136 | wait_done, true); | 135 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); |
137 | } | ||
138 | } | 136 | } |
139 | 137 | ||
140 | static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, | 138 | static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, |
@@ -158,15 +156,14 @@ static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah, | |||
158 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 156 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
159 | u32 *payload = &mci->wlan_channels[0]; | 157 | u32 *payload = &mci->wlan_channels[0]; |
160 | 158 | ||
161 | if ((mci->wlan_channels_update == true) && | 159 | if (!mci->wlan_channels_update || |
162 | (mci->bt_state != MCI_BT_SLEEP)) { | 160 | (mci->bt_state == MCI_BT_SLEEP)) |
163 | MCI_GPM_SET_TYPE_OPCODE(payload, | 161 | return; |
164 | MCI_GPM_COEX_AGENT, | 162 | |
165 | MCI_GPM_COEX_WLAN_CHANNELS); | 163 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, |
166 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | 164 | MCI_GPM_COEX_WLAN_CHANNELS); |
167 | wait_done, true); | 165 | ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); |
168 | MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); | 166 | MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); |
169 | } | ||
170 | } | 167 | } |
171 | 168 | ||
172 | static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | 169 | static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, |
@@ -174,29 +171,30 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, | |||
174 | { | 171 | { |
175 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 172 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
176 | u32 payload[4] = {0, 0, 0, 0}; | 173 | u32 payload[4] = {0, 0, 0, 0}; |
177 | bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | | 174 | bool query_btinfo; |
178 | MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); | ||
179 | |||
180 | if (mci->bt_state != MCI_BT_SLEEP) { | ||
181 | 175 | ||
182 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, | 176 | if (mci->bt_state == MCI_BT_SLEEP) |
183 | MCI_GPM_COEX_STATUS_QUERY); | 177 | return; |
184 | 178 | ||
185 | *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; | 179 | query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | |
180 | MCI_GPM_COEX_QUERY_BT_TOPOLOGY)); | ||
181 | MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, | ||
182 | MCI_GPM_COEX_STATUS_QUERY); | ||
186 | 183 | ||
187 | /* | 184 | *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; |
188 | * If bt_status_query message is not sent successfully, | ||
189 | * then need_flush_btinfo should be set again. | ||
190 | */ | ||
191 | if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | ||
192 | wait_done, true)) { | ||
193 | if (query_btinfo) | ||
194 | mci->need_flush_btinfo = true; | ||
195 | } | ||
196 | 185 | ||
186 | /* | ||
187 | * If bt_status_query message is not sent successfully, | ||
188 | * then need_flush_btinfo should be set again. | ||
189 | */ | ||
190 | if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, | ||
191 | wait_done, true)) { | ||
197 | if (query_btinfo) | 192 | if (query_btinfo) |
198 | mci->query_bt = false; | 193 | mci->need_flush_btinfo = true; |
199 | } | 194 | } |
195 | |||
196 | if (query_btinfo) | ||
197 | mci->query_bt = false; | ||
200 | } | 198 | } |
201 | 199 | ||
202 | static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, | 200 | static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, |
@@ -241,73 +239,73 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) | |||
241 | ar9003_mci_remote_reset(ah, true); | 239 | ar9003_mci_remote_reset(ah, true); |
242 | ar9003_mci_send_req_wake(ah, true); | 240 | ar9003_mci_send_req_wake(ah, true); |
243 | 241 | ||
244 | if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 242 | if (!ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
245 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { | 243 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) |
244 | goto clear_redunt; | ||
246 | 245 | ||
247 | mci->bt_state = MCI_BT_AWAKE; | 246 | mci->bt_state = MCI_BT_AWAKE; |
248 | 247 | ||
249 | /* | 248 | /* |
250 | * we don't need to send more remote_reset at this moment. | 249 | * we don't need to send more remote_reset at this moment. |
251 | * If BT receive first remote_reset, then BT HW will | 250 | * If BT receive first remote_reset, then BT HW will |
252 | * be cleaned up and will be able to receive req_wake | 251 | * be cleaned up and will be able to receive req_wake |
253 | * and BT HW will respond sys_waking. | 252 | * and BT HW will respond sys_waking. |
254 | * In this case, WLAN will receive BT's HW sys_waking. | 253 | * In this case, WLAN will receive BT's HW sys_waking. |
255 | * Otherwise, if BT SW missed initial remote_reset, | 254 | * Otherwise, if BT SW missed initial remote_reset, |
256 | * that remote_reset will still clean up BT MCI RX, | 255 | * that remote_reset will still clean up BT MCI RX, |
257 | * and the req_wake will wake BT up, | 256 | * and the req_wake will wake BT up, |
258 | * and BT SW will respond this req_wake with a remote_reset and | 257 | * and BT SW will respond this req_wake with a remote_reset and |
259 | * sys_waking. In this case, WLAN will receive BT's SW | 258 | * sys_waking. In this case, WLAN will receive BT's SW |
260 | * sys_waking. In either case, BT's RX is cleaned up. So we | 259 | * sys_waking. In either case, BT's RX is cleaned up. So we |
261 | * don't need to reply BT's remote_reset now, if any. | 260 | * don't need to reply BT's remote_reset now, if any. |
262 | * Similarly, if in any case, WLAN can receive BT's sys_waking, | 261 | * Similarly, if in any case, WLAN can receive BT's sys_waking, |
263 | * that means WLAN's RX is also fine. | 262 | * that means WLAN's RX is also fine. |
264 | */ | 263 | */ |
265 | ar9003_mci_send_sys_waking(ah, true); | 264 | ar9003_mci_send_sys_waking(ah, true); |
266 | udelay(10); | 265 | udelay(10); |
267 | 266 | ||
268 | /* | 267 | /* |
269 | * Set BT priority interrupt value to be 0xff to | 268 | * Set BT priority interrupt value to be 0xff to |
270 | * avoid having too many BT PRIORITY interrupts. | 269 | * avoid having too many BT PRIORITY interrupts. |
271 | */ | 270 | */ |
272 | REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); | 271 | REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); |
273 | REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); | 272 | REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); |
274 | REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); | 273 | REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); |
275 | REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); | 274 | REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); |
276 | REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); | 275 | REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); |
277 | 276 | ||
278 | /* | 277 | /* |
279 | * A contention reset will be received after send out | 278 | * A contention reset will be received after send out |
280 | * sys_waking. Also BT priority interrupt bits will be set. | 279 | * sys_waking. Also BT priority interrupt bits will be set. |
281 | * Clear those bits before the next step. | 280 | * Clear those bits before the next step. |
282 | */ | 281 | */ |
283 | 282 | ||
284 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 283 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
285 | AR_MCI_INTERRUPT_RX_MSG_CONT_RST); | 284 | AR_MCI_INTERRUPT_RX_MSG_CONT_RST); |
286 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, | 285 | REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); |
287 | AR_MCI_INTERRUPT_BT_PRI); | ||
288 | 286 | ||
289 | if (mci->is_2g) { | 287 | if (mci->is_2g) { |
290 | ar9003_mci_send_lna_transfer(ah, true); | 288 | ar9003_mci_send_lna_transfer(ah, true); |
291 | udelay(5); | 289 | udelay(5); |
292 | } | 290 | } |
293 | 291 | ||
294 | if ((mci->is_2g && !mci->update_2g5g)) { | 292 | if ((mci->is_2g && !mci->update_2g5g)) { |
295 | if (ar9003_mci_wait_for_interrupt(ah, | 293 | if (ar9003_mci_wait_for_interrupt(ah, |
296 | AR_MCI_INTERRUPT_RX_MSG_RAW, | 294 | AR_MCI_INTERRUPT_RX_MSG_RAW, |
297 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, | 295 | AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, |
298 | mci_timeout)) | 296 | mci_timeout)) |
299 | ath_dbg(common, MCI, | 297 | ath_dbg(common, MCI, |
300 | "MCI WLAN has control over the LNA & BT obeys it\n"); | 298 | "MCI WLAN has control over the LNA & BT obeys it\n"); |
301 | else | 299 | else |
302 | ath_dbg(common, MCI, | 300 | ath_dbg(common, MCI, |
303 | "MCI BT didn't respond to LNA_TRANS\n"); | 301 | "MCI BT didn't respond to LNA_TRANS\n"); |
304 | } | ||
305 | } | 302 | } |
306 | 303 | ||
304 | clear_redunt: | ||
307 | /* Clear the extra redundant SYS_WAKING from BT */ | 305 | /* Clear the extra redundant SYS_WAKING from BT */ |
308 | if ((mci->bt_state == MCI_BT_AWAKE) && | 306 | if ((mci->bt_state == MCI_BT_AWAKE) && |
309 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 307 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
310 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && | 308 | AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && |
311 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 309 | (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
312 | AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { | 310 | AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { |
313 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 311 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
@@ -330,7 +328,6 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah) | |||
330 | } | 328 | } |
331 | 329 | ||
332 | mci->ready = false; | 330 | mci->ready = false; |
333 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
334 | } | 331 | } |
335 | 332 | ||
336 | static void ar9003_mci_disable_interrupt(struct ath_hw *ah) | 333 | static void ar9003_mci_disable_interrupt(struct ath_hw *ah) |
@@ -615,9 +612,9 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, | |||
615 | } | 612 | } |
616 | break; | 613 | break; |
617 | } | 614 | } |
618 | } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) { | 615 | } else if ((recv_type == gpm_type) && |
616 | (recv_opcode == gpm_opcode)) | ||
619 | break; | 617 | break; |
620 | } | ||
621 | 618 | ||
622 | /* | 619 | /* |
623 | * check if it's cal_grant | 620 | * check if it's cal_grant |
@@ -731,38 +728,38 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
731 | if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) | 728 | if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) |
732 | goto exit; | 729 | goto exit; |
733 | 730 | ||
734 | if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || | 731 | if (!ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) && |
735 | ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) { | 732 | !ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) |
733 | goto exit; | ||
736 | 734 | ||
737 | /* | 735 | /* |
738 | * BT is sleeping. Check if BT wakes up during | 736 | * BT is sleeping. Check if BT wakes up during |
739 | * WLAN calibration. If BT wakes up during | 737 | * WLAN calibration. If BT wakes up during |
740 | * WLAN calibration, need to go through all | 738 | * WLAN calibration, need to go through all |
741 | * message exchanges again and recal. | 739 | * message exchanges again and recal. |
742 | */ | 740 | */ |
743 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, | 741 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, |
744 | AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | | 742 | (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | |
745 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); | 743 | AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)); |
746 | 744 | ||
747 | ar9003_mci_remote_reset(ah, true); | 745 | ar9003_mci_remote_reset(ah, true); |
748 | ar9003_mci_send_sys_waking(ah, true); | 746 | ar9003_mci_send_sys_waking(ah, true); |
749 | udelay(1); | 747 | udelay(1); |
750 | 748 | ||
751 | if (IS_CHAN_2GHZ(chan)) | 749 | if (IS_CHAN_2GHZ(chan)) |
752 | ar9003_mci_send_lna_transfer(ah, true); | 750 | ar9003_mci_send_lna_transfer(ah, true); |
753 | 751 | ||
754 | mci_hw->bt_state = MCI_BT_AWAKE; | 752 | mci_hw->bt_state = MCI_BT_AWAKE; |
755 | 753 | ||
756 | if (caldata) { | 754 | if (caldata) { |
757 | caldata->done_txiqcal_once = false; | 755 | caldata->done_txiqcal_once = false; |
758 | caldata->done_txclcal_once = false; | 756 | caldata->done_txclcal_once = false; |
759 | caldata->rtt_done = false; | 757 | caldata->rtt_done = false; |
760 | } | 758 | } |
761 | 759 | ||
762 | if (!ath9k_hw_init_cal(ah, chan)) | 760 | if (!ath9k_hw_init_cal(ah, chan)) |
763 | return -EIO; | 761 | return -EIO; |
764 | 762 | ||
765 | } | ||
766 | exit: | 763 | exit: |
767 | ar9003_mci_enable_interrupt(ah); | 764 | ar9003_mci_enable_interrupt(ah); |
768 | return 0; | 765 | return 0; |
@@ -798,29 +795,27 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) | |||
798 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 795 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
799 | u32 thresh; | 796 | u32 thresh; |
800 | 797 | ||
801 | if (enable) { | 798 | if (!enable) { |
802 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
803 | AR_MCI_SCHD_TABLE_2_HW_BASED, 1); | ||
804 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
805 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | ||
806 | |||
807 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | ||
808 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); | ||
809 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
810 | AR_BTCOEX_CTRL_AGGR_THRESH, thresh); | ||
811 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
812 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); | ||
813 | } else { | ||
814 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
815 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); | ||
816 | } | ||
817 | |||
818 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
819 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); | ||
820 | } else { | ||
821 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, | 799 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, |
822 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 800 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); |
801 | return; | ||
823 | } | 802 | } |
803 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1); | ||
804 | REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, | ||
805 | AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); | ||
806 | |||
807 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { | ||
808 | thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); | ||
809 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
810 | AR_BTCOEX_CTRL_AGGR_THRESH, thresh); | ||
811 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
812 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); | ||
813 | } else | ||
814 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
815 | AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); | ||
816 | |||
817 | REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, | ||
818 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); | ||
824 | } | 819 | } |
825 | 820 | ||
826 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | 821 | void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, |
@@ -943,26 +938,27 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) | |||
943 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 938 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
944 | u32 new_flags, to_set, to_clear; | 939 | u32 new_flags, to_set, to_clear; |
945 | 940 | ||
946 | if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) { | 941 | if (!mci->update_2g5g || (mci->bt_state == MCI_BT_SLEEP)) |
947 | if (mci->is_2g) { | 942 | return; |
948 | new_flags = MCI_2G_FLAGS; | 943 | |
949 | to_clear = MCI_2G_FLAGS_CLEAR_MASK; | 944 | if (mci->is_2g) { |
950 | to_set = MCI_2G_FLAGS_SET_MASK; | 945 | new_flags = MCI_2G_FLAGS; |
951 | } else { | 946 | to_clear = MCI_2G_FLAGS_CLEAR_MASK; |
952 | new_flags = MCI_5G_FLAGS; | 947 | to_set = MCI_2G_FLAGS_SET_MASK; |
953 | to_clear = MCI_5G_FLAGS_CLEAR_MASK; | 948 | } else { |
954 | to_set = MCI_5G_FLAGS_SET_MASK; | 949 | new_flags = MCI_5G_FLAGS; |
955 | } | 950 | to_clear = MCI_5G_FLAGS_CLEAR_MASK; |
951 | to_set = MCI_5G_FLAGS_SET_MASK; | ||
952 | } | ||
956 | 953 | ||
957 | if (to_clear) | 954 | if (to_clear) |
958 | ar9003_mci_send_coex_bt_flags(ah, wait_done, | 955 | ar9003_mci_send_coex_bt_flags(ah, wait_done, |
959 | MCI_GPM_COEX_BT_FLAGS_CLEAR, | 956 | MCI_GPM_COEX_BT_FLAGS_CLEAR, |
960 | to_clear); | 957 | to_clear); |
961 | if (to_set) | 958 | if (to_set) |
962 | ar9003_mci_send_coex_bt_flags(ah, wait_done, | 959 | ar9003_mci_send_coex_bt_flags(ah, wait_done, |
963 | MCI_GPM_COEX_BT_FLAGS_SET, | 960 | MCI_GPM_COEX_BT_FLAGS_SET, |
964 | to_set); | 961 | to_set); |
965 | } | ||
966 | } | 962 | } |
967 | 963 | ||
968 | static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, | 964 | static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, |
@@ -1018,34 +1014,34 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) | |||
1018 | { | 1014 | { |
1019 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | 1015 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; |
1020 | 1016 | ||
1021 | if (mci->update_2g5g) { | 1017 | if (!mci->update_2g5g) |
1022 | if (mci->is_2g) { | 1018 | return; |
1023 | ar9003_mci_send_2g5g_status(ah, true); | ||
1024 | ar9003_mci_send_lna_transfer(ah, true); | ||
1025 | udelay(5); | ||
1026 | 1019 | ||
1027 | REG_CLR_BIT(ah, AR_MCI_TX_CTRL, | 1020 | if (mci->is_2g) { |
1028 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); | 1021 | ar9003_mci_send_2g5g_status(ah, true); |
1029 | REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, | 1022 | ar9003_mci_send_lna_transfer(ah, true); |
1030 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | 1023 | udelay(5); |
1031 | 1024 | ||
1032 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { | 1025 | REG_CLR_BIT(ah, AR_MCI_TX_CTRL, |
1033 | REG_SET_BIT(ah, AR_BTCOEX_CTRL, | 1026 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); |
1034 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 1027 | REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, |
1035 | } | 1028 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); |
1036 | } else { | 1029 | |
1037 | ar9003_mci_send_lna_take(ah, true); | 1030 | if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) |
1038 | udelay(5); | 1031 | REG_SET_BIT(ah, AR_BTCOEX_CTRL, |
1039 | |||
1040 | REG_SET_BIT(ah, AR_MCI_TX_CTRL, | ||
1041 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); | ||
1042 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, | ||
1043 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1044 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, | ||
1045 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | 1032 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); |
1033 | } else { | ||
1034 | ar9003_mci_send_lna_take(ah, true); | ||
1035 | udelay(5); | ||
1046 | 1036 | ||
1047 | ar9003_mci_send_2g5g_status(ah, true); | 1037 | REG_SET_BIT(ah, AR_MCI_TX_CTRL, |
1048 | } | 1038 | AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); |
1039 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, | ||
1040 | AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1041 | REG_CLR_BIT(ah, AR_BTCOEX_CTRL, | ||
1042 | AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); | ||
1043 | |||
1044 | ar9003_mci_send_2g5g_status(ah, true); | ||
1049 | } | 1045 | } |
1050 | } | 1046 | } |
1051 | 1047 | ||
@@ -1132,7 +1128,7 @@ void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable) | |||
1132 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { | 1128 | if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { |
1133 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); | 1129 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); |
1134 | } else { | 1130 | } else { |
1135 | is_reusable = false; | 1131 | *is_reusable = false; |
1136 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); | 1132 | ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); |
1137 | } | 1133 | } |
1138 | } | 1134 | } |
@@ -1259,12 +1255,12 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1259 | } | 1255 | } |
1260 | if (p_data) | 1256 | if (p_data) |
1261 | *p_data = more_gpm; | 1257 | *p_data = more_gpm; |
1262 | } | 1258 | } |
1263 | 1259 | ||
1264 | if (value != MCI_GPM_INVALID) | 1260 | if (value != MCI_GPM_INVALID) |
1265 | value <<= 4; | 1261 | value <<= 4; |
1266 | 1262 | ||
1267 | break; | 1263 | break; |
1268 | case MCI_STATE_LAST_SCHD_MSG_OFFSET: | 1264 | case MCI_STATE_LAST_SCHD_MSG_OFFSET: |
1269 | value = MS(REG_READ(ah, AR_MCI_RX_STATUS), | 1265 | value = MS(REG_READ(ah, AR_MCI_RX_STATUS), |
1270 | AR_MCI_RX_LAST_SCHD_MSG_INDEX); | 1266 | AR_MCI_RX_LAST_SCHD_MSG_INDEX); |
@@ -1359,24 +1355,22 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1359 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); | 1355 | ar9003_mci_send_coex_bt_status_query(ah, true, query_type); |
1360 | break; | 1356 | break; |
1361 | case MCI_STATE_NEED_FLUSH_BT_INFO: | 1357 | case MCI_STATE_NEED_FLUSH_BT_INFO: |
1362 | /* | 1358 | /* |
1363 | * btcoex_hw.mci.unhalt_bt_gpm means whether it's | 1359 | * btcoex_hw.mci.unhalt_bt_gpm means whether it's |
1364 | * needed to send UNHALT message. It's set whenever | 1360 | * needed to send UNHALT message. It's set whenever |
1365 | * there's a request to send HALT message. | 1361 | * there's a request to send HALT message. |
1366 | * mci_halted_bt_gpm means whether HALT message is sent | 1362 | * mci_halted_bt_gpm means whether HALT message is sent |
1367 | * out successfully. | 1363 | * out successfully. |
1368 | * | 1364 | * |
1369 | * Checking (mci_unhalt_bt_gpm == false) instead of | 1365 | * Checking (mci_unhalt_bt_gpm == false) instead of |
1370 | * checking (ah->mci_halted_bt_gpm == false) will make | 1366 | * checking (ah->mci_halted_bt_gpm == false) will make |
1371 | * sure currently is in UNHALT-ed mode and BT can | 1367 | * sure currently is in UNHALT-ed mode and BT can |
1372 | * respond to status query. | 1368 | * respond to status query. |
1373 | */ | 1369 | */ |
1374 | value = (!mci->unhalt_bt_gpm && | 1370 | value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; |
1375 | mci->need_flush_btinfo) ? 1 : 0; | 1371 | if (p_data) |
1376 | if (p_data) | 1372 | mci->need_flush_btinfo = (*p_data != 0) ? true : false; |
1377 | mci->need_flush_btinfo = | 1373 | break; |
1378 | (*p_data != 0) ? true : false; | ||
1379 | break; | ||
1380 | case MCI_STATE_RECOVER_RX: | 1374 | case MCI_STATE_RECOVER_RX: |
1381 | ar9003_mci_prep_interface(ah); | 1375 | ar9003_mci_prep_interface(ah); |
1382 | mci->query_bt = true; | 1376 | mci->query_bt = true; |
@@ -1387,9 +1381,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1387 | case MCI_STATE_NEED_FTP_STOMP: | 1381 | case MCI_STATE_NEED_FTP_STOMP: |
1388 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); | 1382 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); |
1389 | break; | 1383 | break; |
1390 | case MCI_STATE_NEED_TUNING: | ||
1391 | value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING); | ||
1392 | break; | ||
1393 | default: | 1384 | default: |
1394 | break; | 1385 | break; |
1395 | } | 1386 | } |
@@ -1397,3 +1388,19 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1397 | return value; | 1388 | return value; |
1398 | } | 1389 | } |
1399 | EXPORT_SYMBOL(ar9003_mci_state); | 1390 | EXPORT_SYMBOL(ar9003_mci_state); |
1391 | |||
1392 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) | ||
1393 | { | ||
1394 | struct ath_common *common = ath9k_hw_common(ah); | ||
1395 | struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; | ||
1396 | |||
1397 | ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n"); | ||
1398 | |||
1399 | REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); | ||
1400 | mci->is_2g = false; | ||
1401 | mci->update_2g5g = true; | ||
1402 | ar9003_mci_send_2g5g_status(ah, true); | ||
1403 | |||
1404 | /* Force another 2g5g update at next scanning */ | ||
1405 | mci->update_2g5g = true; | ||
1406 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 4842f6c06b8c..10282e2bcdc9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h | |||
@@ -212,7 +212,6 @@ enum mci_state_type { | |||
212 | MCI_STATE_SET_CONCUR_TX_PRI, | 212 | MCI_STATE_SET_CONCUR_TX_PRI, |
213 | MCI_STATE_RECOVER_RX, | 213 | MCI_STATE_RECOVER_RX, |
214 | MCI_STATE_NEED_FTP_STOMP, | 214 | MCI_STATE_NEED_FTP_STOMP, |
215 | MCI_STATE_NEED_TUNING, | ||
216 | MCI_STATE_DEBUG, | 215 | MCI_STATE_DEBUG, |
217 | MCI_STATE_MAX | 216 | MCI_STATE_MAX |
218 | }; | 217 | }; |
@@ -266,6 +265,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, | |||
266 | void ar9003_mci_cleanup(struct ath_hw *ah); | 265 | void ar9003_mci_cleanup(struct ath_hw *ah); |
267 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | 266 | void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, |
268 | u32 *rx_msg_intr); | 267 | u32 *rx_msg_intr); |
268 | void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); | ||
269 | 269 | ||
270 | /* | 270 | /* |
271 | * These functions are used by ath9k_hw. | 271 | * These functions are used by ath9k_hw. |
@@ -273,10 +273,6 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, | |||
273 | 273 | ||
274 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 274 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
275 | 275 | ||
276 | static inline bool ar9003_mci_is_ready(struct ath_hw *ah) | ||
277 | { | ||
278 | return ah->btcoex_hw.mci.ready; | ||
279 | } | ||
280 | void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); | 276 | void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); |
281 | void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); | 277 | void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); |
282 | void ar9003_mci_init_cal_done(struct ath_hw *ah); | 278 | void ar9003_mci_init_cal_done(struct ath_hw *ah); |
@@ -292,10 +288,6 @@ void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); | |||
292 | 288 | ||
293 | #else | 289 | #else |
294 | 290 | ||
295 | static inline bool ar9003_mci_is_ready(struct ath_hw *ah) | ||
296 | { | ||
297 | return false; | ||
298 | } | ||
299 | static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) | 291 | static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) |
300 | { | 292 | { |
301 | } | 293 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 11abb972be1f..d6baf69cdc14 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -676,6 +676,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
676 | if (chan->channel == 2484) | 676 | if (chan->channel == 2484) |
677 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); | 677 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); |
678 | 678 | ||
679 | if (AR_SREV_9462(ah)) | ||
680 | REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, | ||
681 | AR_GLB_SWREG_DISCONT_EN_BT_WLAN); | ||
682 | |||
679 | ah->modes_index = modesIndex; | 683 | ah->modes_index = modesIndex; |
680 | ar9003_hw_override_ini(ah); | 684 | ar9003_hw_override_ini(ah); |
681 | ar9003_hw_set_channel_regs(ah, chan); | 685 | ar9003_hw_set_channel_regs(ah, chan); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7268a48a92a1..ed662c3bae5b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -820,18 +820,26 @@ | |||
820 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | 820 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 |
821 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | 821 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF |
822 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | 822 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 |
823 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 | 823 | |
824 | #define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 | 824 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 |
825 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 | 825 | #define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 |
826 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 | 826 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 |
827 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 | 827 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 |
828 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 | 828 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 |
829 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 | 829 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 |
830 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | 830 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 |
831 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 | 831 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 |
832 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | 832 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x0FFF0000 |
833 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 | 833 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 |
834 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | 834 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x10000000 |
835 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 28 | ||
836 | #define AR_PHY_SPECTRAL_SCAN_PRIORITY 0x20000000 | ||
837 | #define AR_PHY_SPECTRAL_SCAN_PRIORITY_S 29 | ||
838 | #define AR_PHY_SPECTRAL_SCAN_USE_ERR5 0x40000000 | ||
839 | #define AR_PHY_SPECTRAL_SCAN_USE_ERR5_S 30 | ||
840 | #define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT 0x80000000 | ||
841 | #define AR_PHY_SPECTRAL_SCAN_COMPRESSED_RPT_S 31 | ||
842 | |||
835 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 | 843 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 |
836 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001 | 844 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001 |
837 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0 | 845 | #define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0 |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1d6658e139b5..4a93e1534c1d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -958,7 +958,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
958 | {0x0001604c, 0x2699e04f}, | 958 | {0x0001604c, 0x2699e04f}, |
959 | {0x00016050, 0x6db6db6c}, | 959 | {0x00016050, 0x6db6db6c}, |
960 | {0x00016058, 0x6c200000}, | 960 | {0x00016058, 0x6c200000}, |
961 | {0x00016080, 0x00040000}, | 961 | {0x00016080, 0x000c0000}, |
962 | {0x00016084, 0x9a68048c}, | 962 | {0x00016084, 0x9a68048c}, |
963 | {0x00016088, 0x54214514}, | 963 | {0x00016088, 0x54214514}, |
964 | {0x0001608c, 0x1203040b}, | 964 | {0x0001608c, 0x1203040b}, |
@@ -981,7 +981,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
981 | {0x00016144, 0x02084080}, | 981 | {0x00016144, 0x02084080}, |
982 | {0x00016148, 0x000080c0}, | 982 | {0x00016148, 0x000080c0}, |
983 | {0x00016280, 0x050a0001}, | 983 | {0x00016280, 0x050a0001}, |
984 | {0x00016284, 0x3d841400}, | 984 | {0x00016284, 0x3d841418}, |
985 | {0x00016288, 0x00000000}, | 985 | {0x00016288, 0x00000000}, |
986 | {0x0001628c, 0xe3000000}, | 986 | {0x0001628c, 0xe3000000}, |
987 | {0x00016290, 0xa1005080}, | 987 | {0x00016290, 0xa1005080}, |
@@ -1007,6 +1007,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { | |||
1007 | 1007 | ||
1008 | static const u32 ar9462_2p0_soc_preamble[][2] = { | 1008 | static const u32 ar9462_2p0_soc_preamble[][2] = { |
1009 | /* Addr allmodes */ | 1009 | /* Addr allmodes */ |
1010 | {0x000040a4 ,0x00a0c1c9}, | ||
1010 | {0x00007020, 0x00000000}, | 1011 | {0x00007020, 0x00000000}, |
1011 | {0x00007034, 0x00000002}, | 1012 | {0x00007034, 0x00000002}, |
1012 | {0x00007038, 0x000004c2}, | 1013 | {0x00007038, 0x000004c2}, |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a277cf6f339d..02fc1c1e5eeb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -307,6 +307,7 @@ struct ath_rx { | |||
307 | u8 defant; | 307 | u8 defant; |
308 | u8 rxotherant; | 308 | u8 rxotherant; |
309 | u32 *rxlink; | 309 | u32 *rxlink; |
310 | u32 num_pkts; | ||
310 | unsigned int rxfilter; | 311 | unsigned int rxfilter; |
311 | spinlock_t rxbuflock; | 312 | spinlock_t rxbuflock; |
312 | struct list_head rxbuf; | 313 | struct list_head rxbuf; |
@@ -325,6 +326,9 @@ int ath_rx_init(struct ath_softc *sc, int nbufs); | |||
325 | void ath_rx_cleanup(struct ath_softc *sc); | 326 | void ath_rx_cleanup(struct ath_softc *sc); |
326 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | 327 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); |
327 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 328 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
329 | void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq); | ||
330 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq); | ||
331 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq); | ||
328 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 332 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
329 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 333 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
330 | void ath_draintxq(struct ath_softc *sc, | 334 | void ath_draintxq(struct ath_softc *sc, |
@@ -414,9 +418,9 @@ int ath_beaconq_config(struct ath_softc *sc); | |||
414 | void ath_set_beacon(struct ath_softc *sc); | 418 | void ath_set_beacon(struct ath_softc *sc); |
415 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | 419 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); |
416 | 420 | ||
417 | /*******/ | 421 | /*******************/ |
418 | /* ANI */ | 422 | /* Link Monitoring */ |
419 | /*******/ | 423 | /*******************/ |
420 | 424 | ||
421 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ | 425 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ |
422 | #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ | 426 | #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ |
@@ -427,7 +431,9 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | |||
427 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | 431 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ |
428 | 432 | ||
429 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ | 433 | #define ATH_PAPRD_TIMEOUT 100 /* msecs */ |
434 | #define ATH_PLL_WORK_INTERVAL 100 | ||
430 | 435 | ||
436 | void ath_tx_complete_poll_work(struct work_struct *work); | ||
431 | void ath_reset_work(struct work_struct *work); | 437 | void ath_reset_work(struct work_struct *work); |
432 | void ath_hw_check(struct work_struct *work); | 438 | void ath_hw_check(struct work_struct *work); |
433 | void ath_hw_pll_work(struct work_struct *work); | 439 | void ath_hw_pll_work(struct work_struct *work); |
@@ -436,22 +442,31 @@ void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); | |||
436 | void ath_paprd_calibrate(struct work_struct *work); | 442 | void ath_paprd_calibrate(struct work_struct *work); |
437 | void ath_ani_calibrate(unsigned long data); | 443 | void ath_ani_calibrate(unsigned long data); |
438 | void ath_start_ani(struct ath_common *common); | 444 | void ath_start_ani(struct ath_common *common); |
445 | int ath_update_survey_stats(struct ath_softc *sc); | ||
446 | void ath_update_survey_nf(struct ath_softc *sc, int channel); | ||
439 | 447 | ||
440 | /**********/ | 448 | /**********/ |
441 | /* BTCOEX */ | 449 | /* BTCOEX */ |
442 | /**********/ | 450 | /**********/ |
443 | 451 | ||
452 | enum bt_op_flags { | ||
453 | BT_OP_PRIORITY_DETECTED, | ||
454 | BT_OP_SCAN, | ||
455 | }; | ||
456 | |||
444 | struct ath_btcoex { | 457 | struct ath_btcoex { |
445 | bool hw_timer_enabled; | 458 | bool hw_timer_enabled; |
446 | spinlock_t btcoex_lock; | 459 | spinlock_t btcoex_lock; |
447 | struct timer_list period_timer; /* Timer for BT period */ | 460 | struct timer_list period_timer; /* Timer for BT period */ |
448 | u32 bt_priority_cnt; | 461 | u32 bt_priority_cnt; |
449 | unsigned long bt_priority_time; | 462 | unsigned long bt_priority_time; |
463 | unsigned long op_flags; | ||
450 | int bt_stomp_type; /* Types of BT stomping */ | 464 | int bt_stomp_type; /* Types of BT stomping */ |
451 | u32 btcoex_no_stomp; /* in usec */ | 465 | u32 btcoex_no_stomp; /* in usec */ |
452 | u32 btcoex_period; /* in usec */ | 466 | u32 btcoex_period; /* in usec */ |
453 | u32 btscan_no_stomp; /* in usec */ | 467 | u32 btscan_no_stomp; /* in usec */ |
454 | u32 duty_cycle; | 468 | u32 duty_cycle; |
469 | u32 bt_wait_time; | ||
455 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 470 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
456 | struct ath_mci_profile mci; | 471 | struct ath_mci_profile mci; |
457 | }; | 472 | }; |
@@ -513,8 +528,10 @@ static inline void ath_deinit_leds(struct ath_softc *sc) | |||
513 | } | 528 | } |
514 | #endif | 529 | #endif |
515 | 530 | ||
516 | 531 | /*******************************/ | |
517 | /* Antenna diversity/combining */ | 532 | /* Antenna diversity/combining */ |
533 | /*******************************/ | ||
534 | |||
518 | #define ATH_ANT_RX_CURRENT_SHIFT 4 | 535 | #define ATH_ANT_RX_CURRENT_SHIFT 4 |
519 | #define ATH_ANT_RX_MAIN_SHIFT 2 | 536 | #define ATH_ANT_RX_MAIN_SHIFT 2 |
520 | #define ATH_ANT_RX_MASK 0x3 | 537 | #define ATH_ANT_RX_MASK 0x3 |
@@ -567,6 +584,9 @@ struct ath_ant_comb { | |||
567 | unsigned long scan_start_time; | 584 | unsigned long scan_start_time; |
568 | }; | 585 | }; |
569 | 586 | ||
587 | void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); | ||
588 | void ath_ant_comb_update(struct ath_softc *sc); | ||
589 | |||
570 | /********************/ | 590 | /********************/ |
571 | /* Main driver core */ | 591 | /* Main driver core */ |
572 | /********************/ | 592 | /********************/ |
@@ -584,15 +604,15 @@ struct ath_ant_comb { | |||
584 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 604 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
585 | #define ATH_RATE_DUMMY_MARKER 0 | 605 | #define ATH_RATE_DUMMY_MARKER 0 |
586 | 606 | ||
587 | #define SC_OP_INVALID BIT(0) | 607 | enum sc_op_flags { |
588 | #define SC_OP_BEACONS BIT(1) | 608 | SC_OP_INVALID, |
589 | #define SC_OP_OFFCHANNEL BIT(2) | 609 | SC_OP_BEACONS, |
590 | #define SC_OP_RXFLUSH BIT(3) | 610 | SC_OP_RXFLUSH, |
591 | #define SC_OP_TSF_RESET BIT(4) | 611 | SC_OP_TSF_RESET, |
592 | #define SC_OP_BT_PRIORITY_DETECTED BIT(5) | 612 | SC_OP_ANI_RUN, |
593 | #define SC_OP_BT_SCAN BIT(6) | 613 | SC_OP_PRIM_STA_VIF, |
594 | #define SC_OP_ANI_RUN BIT(7) | 614 | SC_OP_HW_RESET, |
595 | #define SC_OP_PRIM_STA_VIF BIT(8) | 615 | }; |
596 | 616 | ||
597 | /* Powersave flags */ | 617 | /* Powersave flags */ |
598 | #define PS_WAIT_FOR_BEACON BIT(0) | 618 | #define PS_WAIT_FOR_BEACON BIT(0) |
@@ -638,9 +658,9 @@ struct ath_softc { | |||
638 | struct completion paprd_complete; | 658 | struct completion paprd_complete; |
639 | 659 | ||
640 | unsigned int hw_busy_count; | 660 | unsigned int hw_busy_count; |
661 | unsigned long sc_flags; | ||
641 | 662 | ||
642 | u32 intrstatus; | 663 | u32 intrstatus; |
643 | u32 sc_flags; /* SC_OP_* */ | ||
644 | u16 ps_flags; /* PS_* */ | 664 | u16 ps_flags; /* PS_* */ |
645 | u16 curtxpow; | 665 | u16 curtxpow; |
646 | bool ps_enabled; | 666 | bool ps_enabled; |
@@ -736,5 +756,4 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
736 | struct ieee80211_vif *vif, | 756 | struct ieee80211_vif *vif, |
737 | struct ath9k_vif_iter_data *iter_data); | 757 | struct ath9k_vif_iter_data *iter_data); |
738 | 758 | ||
739 | |||
740 | #endif /* ATH9K_H */ | 759 | #endif /* ATH9K_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 11bc55e3d697..40775da8941e 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -48,7 +48,10 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
48 | txq = sc->tx.txq_map[WME_AC_BE]; | 48 | txq = sc->tx.txq_map[WME_AC_BE]; |
49 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); | 49 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); |
50 | qi.tqi_aifs = qi_be.tqi_aifs; | 50 | qi.tqi_aifs = qi_be.tqi_aifs; |
51 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | 51 | if (ah->slottime == ATH9K_SLOT_TIME_20) |
52 | qi.tqi_cwmin = 2*qi_be.tqi_cwmin; | ||
53 | else | ||
54 | qi.tqi_cwmin = 4*qi_be.tqi_cwmin; | ||
52 | qi.tqi_cwmax = qi_be.tqi_cwmax; | 55 | qi.tqi_cwmax = qi_be.tqi_cwmax; |
53 | } | 56 | } |
54 | 57 | ||
@@ -387,7 +390,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
387 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | 390 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { |
388 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); | 391 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); |
389 | sc->beacon.bmisscnt = 0; | 392 | sc->beacon.bmisscnt = 0; |
390 | sc->sc_flags |= SC_OP_TSF_RESET; | 393 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
391 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 394 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
392 | } | 395 | } |
393 | 396 | ||
@@ -477,16 +480,16 @@ static void ath9k_beacon_init(struct ath_softc *sc, | |||
477 | u32 next_beacon, | 480 | u32 next_beacon, |
478 | u32 beacon_period) | 481 | u32 beacon_period) |
479 | { | 482 | { |
480 | if (sc->sc_flags & SC_OP_TSF_RESET) { | 483 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { |
481 | ath9k_ps_wakeup(sc); | 484 | ath9k_ps_wakeup(sc); |
482 | ath9k_hw_reset_tsf(sc->sc_ah); | 485 | ath9k_hw_reset_tsf(sc->sc_ah); |
483 | } | 486 | } |
484 | 487 | ||
485 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); | 488 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); |
486 | 489 | ||
487 | if (sc->sc_flags & SC_OP_TSF_RESET) { | 490 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { |
488 | ath9k_ps_restore(sc); | 491 | ath9k_ps_restore(sc); |
489 | sc->sc_flags &= ~SC_OP_TSF_RESET; | 492 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
490 | } | 493 | } |
491 | } | 494 | } |
492 | 495 | ||
@@ -516,7 +519,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
516 | /* Set the computed AP beacon timers */ | 519 | /* Set the computed AP beacon timers */ |
517 | 520 | ||
518 | ath9k_hw_disable_interrupts(ah); | 521 | ath9k_hw_disable_interrupts(ah); |
519 | sc->sc_flags |= SC_OP_TSF_RESET; | 522 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
520 | ath9k_beacon_init(sc, nexttbtt, intval); | 523 | ath9k_beacon_init(sc, nexttbtt, intval); |
521 | sc->beacon.bmisscnt = 0; | 524 | sc->beacon.bmisscnt = 0; |
522 | ath9k_hw_set_interrupts(ah); | 525 | ath9k_hw_set_interrupts(ah); |
@@ -659,7 +662,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
659 | u32 tsf, intval, nexttbtt; | 662 | u32 tsf, intval, nexttbtt; |
660 | 663 | ||
661 | ath9k_reset_beacon_status(sc); | 664 | ath9k_reset_beacon_status(sc); |
662 | if (!(sc->sc_flags & SC_OP_BEACONS)) | 665 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) |
663 | ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); | 666 | ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); |
664 | 667 | ||
665 | intval = TU_TO_USEC(conf->beacon_interval); | 668 | intval = TU_TO_USEC(conf->beacon_interval); |
@@ -724,7 +727,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
724 | */ | 727 | */ |
725 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 728 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && |
726 | (vif->type == NL80211_IFTYPE_STATION) && | 729 | (vif->type == NL80211_IFTYPE_STATION) && |
727 | (sc->sc_flags & SC_OP_BEACONS) && | 730 | test_bit(SC_OP_BEACONS, &sc->sc_flags) && |
728 | !avp->primary_sta_vif) { | 731 | !avp->primary_sta_vif) { |
729 | ath_dbg(common, CONFIG, | 732 | ath_dbg(common, CONFIG, |
730 | "Beacon already configured for a station interface\n"); | 733 | "Beacon already configured for a station interface\n"); |
@@ -810,7 +813,7 @@ void ath_set_beacon(struct ath_softc *sc) | |||
810 | return; | 813 | return; |
811 | } | 814 | } |
812 | 815 | ||
813 | sc->sc_flags |= SC_OP_BEACONS; | 816 | set_bit(SC_OP_BEACONS, &sc->sc_flags); |
814 | } | 817 | } |
815 | 818 | ||
816 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | 819 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) |
@@ -818,7 +821,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | |||
818 | struct ath_hw *ah = sc->sc_ah; | 821 | struct ath_hw *ah = sc->sc_ah; |
819 | 822 | ||
820 | if (!ath_has_valid_bslot(sc)) { | 823 | if (!ath_has_valid_bslot(sc)) { |
821 | sc->sc_flags &= ~SC_OP_BEACONS; | 824 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); |
822 | return; | 825 | return; |
823 | } | 826 | } |
824 | 827 | ||
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index 1ca6da80d4ad..acd437384fe4 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -336,10 +336,16 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | |||
336 | enum ath_stomp_type stomp_type) | 336 | enum ath_stomp_type stomp_type) |
337 | { | 337 | { |
338 | struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; | 338 | struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; |
339 | const u32 *weight = AR_SREV_9462(ah) ? ar9003_wlan_weights[stomp_type] : | 339 | const u32 *weight = ar9003_wlan_weights[stomp_type]; |
340 | ar9462_wlan_weights[stomp_type]; | ||
341 | int i; | 340 | int i; |
342 | 341 | ||
342 | if (AR_SREV_9462(ah)) { | ||
343 | if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && | ||
344 | btcoex->mci.stomp_ftp) | ||
345 | stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; | ||
346 | weight = ar9462_wlan_weights[stomp_type]; | ||
347 | } | ||
348 | |||
343 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { | 349 | for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { |
344 | btcoex->bt_weight[i] = AR9300_BT_WGHT; | 350 | btcoex->bt_weight[i] = AR9300_BT_WGHT; |
345 | btcoex->wlan_weight[i] = weight[i]; | 351 | btcoex->wlan_weight[i] = weight[i]; |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 3a1e1cfabd5e..20092f98658f 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -36,6 +36,9 @@ | |||
36 | #define ATH_BT_CNT_THRESHOLD 3 | 36 | #define ATH_BT_CNT_THRESHOLD 3 |
37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 | 37 | #define ATH_BT_CNT_SCAN_THRESHOLD 15 |
38 | 38 | ||
39 | #define ATH_BTCOEX_RX_WAIT_TIME 100 | ||
40 | #define ATH_BTCOEX_STOMP_FTP_THRESH 5 | ||
41 | |||
39 | #define AR9300_NUM_BT_WEIGHTS 4 | 42 | #define AR9300_NUM_BT_WEIGHTS 4 |
40 | #define AR9300_NUM_WLAN_WEIGHTS 4 | 43 | #define AR9300_NUM_WLAN_WEIGHTS 4 |
41 | /* Defines the BT AR_BT_COEX_WGHT used */ | 44 | /* Defines the BT AR_BT_COEX_WGHT used */ |
@@ -80,6 +83,7 @@ struct ath9k_hw_mci { | |||
80 | u8 bt_ver_major; | 83 | u8 bt_ver_major; |
81 | u8 bt_ver_minor; | 84 | u8 bt_ver_minor; |
82 | u8 bt_state; | 85 | u8 bt_state; |
86 | u8 stomp_ftp; | ||
83 | }; | 87 | }; |
84 | 88 | ||
85 | struct ath_btcoex_hw { | 89 | struct ath_btcoex_hw { |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index fde700c4e490..2831258d9507 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -205,10 +205,10 @@ static ssize_t write_file_disable_ani(struct file *file, | |||
205 | common->disable_ani = !!disable_ani; | 205 | common->disable_ani = !!disable_ani; |
206 | 206 | ||
207 | if (disable_ani) { | 207 | if (disable_ani) { |
208 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
209 | del_timer_sync(&common->ani.timer); | 209 | del_timer_sync(&common->ani.timer); |
210 | } else { | 210 | } else { |
211 | sc->sc_flags |= SC_OP_ANI_RUN; | 211 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
212 | ath_start_ani(common); | 212 | ath_start_ani(common); |
213 | } | 213 | } |
214 | 214 | ||
@@ -374,6 +374,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
374 | sc->debug.stats.istats.dtim++; | 374 | sc->debug.stats.istats.dtim++; |
375 | if (status & ATH9K_INT_TSFOOR) | 375 | if (status & ATH9K_INT_TSFOOR) |
376 | sc->debug.stats.istats.tsfoor++; | 376 | sc->debug.stats.istats.tsfoor++; |
377 | if (status & ATH9K_INT_MCI) | ||
378 | sc->debug.stats.istats.mci++; | ||
377 | } | 379 | } |
378 | 380 | ||
379 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | 381 | static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, |
@@ -418,6 +420,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | |||
418 | PR_IS("DTIMSYNC", dtimsync); | 420 | PR_IS("DTIMSYNC", dtimsync); |
419 | PR_IS("DTIM", dtim); | 421 | PR_IS("DTIM", dtim); |
420 | PR_IS("TSFOOR", tsfoor); | 422 | PR_IS("TSFOOR", tsfoor); |
423 | PR_IS("MCI", mci); | ||
421 | PR_IS("TOTAL", total); | 424 | PR_IS("TOTAL", total); |
422 | 425 | ||
423 | len += snprintf(buf + len, mxlen - len, | 426 | len += snprintf(buf + len, mxlen - len, |
@@ -1318,7 +1321,7 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file) | |||
1318 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | 1321 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; |
1319 | u8 nread; | 1322 | u8 nread; |
1320 | 1323 | ||
1321 | if (sc->sc_flags & SC_OP_INVALID) | 1324 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
1322 | return -EAGAIN; | 1325 | return -EAGAIN; |
1323 | 1326 | ||
1324 | buf = vmalloc(size); | 1327 | buf = vmalloc(size); |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index c34da09d9103..d0f851cea43a 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -86,6 +86,7 @@ struct ath_interrupt_stats { | |||
86 | u32 dtim; | 86 | u32 dtim; |
87 | u32 bb_watchdog; | 87 | u32 bb_watchdog; |
88 | u32 tsfoor; | 88 | u32 tsfoor; |
89 | u32 mci; | ||
89 | 90 | ||
90 | /* Sync-cause stats */ | 91 | /* Sync-cause stats */ |
91 | u32 sync_cause_all; | 92 | u32 sync_cause_all; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 4322ac80c203..7d075105a85d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -135,7 +135,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
135 | if (!dump_base_hdr) { | 135 | if (!dump_base_hdr) { |
136 | len += snprintf(buf + len, size - len, | 136 | len += snprintf(buf + len, size - len, |
137 | "%20s :\n", "2GHz modal Header"); | 137 | "%20s :\n", "2GHz modal Header"); |
138 | len += ath9k_dump_4k_modal_eeprom(buf, len, size, | 138 | len = ath9k_dump_4k_modal_eeprom(buf, len, size, |
139 | &eep->modalHeader); | 139 | &eep->modalHeader); |
140 | goto out; | 140 | goto out; |
141 | } | 141 | } |
@@ -188,8 +188,7 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah) | |||
188 | { | 188 | { |
189 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) | 189 | #define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16)) |
190 | struct ath_common *common = ath9k_hw_common(ah); | 190 | struct ath_common *common = ath9k_hw_common(ah); |
191 | struct ar5416_eeprom_4k *eep = | 191 | struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; |
192 | (struct ar5416_eeprom_4k *) &ah->eeprom.map4k; | ||
193 | u16 *eepdata, temp, magic, magic2; | 192 | u16 *eepdata, temp, magic, magic2; |
194 | u32 sum = 0, el; | 193 | u32 sum = 0, el; |
195 | bool need_swap = false; | 194 | bool need_swap = false; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index aa614767adff..cd742fb944c2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -132,7 +132,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
132 | if (!dump_base_hdr) { | 132 | if (!dump_base_hdr) { |
133 | len += snprintf(buf + len, size - len, | 133 | len += snprintf(buf + len, size - len, |
134 | "%20s :\n", "2GHz modal Header"); | 134 | "%20s :\n", "2GHz modal Header"); |
135 | len += ar9287_dump_modal_eeprom(buf, len, size, | 135 | len = ar9287_dump_modal_eeprom(buf, len, size, |
136 | &eep->modalHeader); | 136 | &eep->modalHeader); |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index b5fba8b18b8b..a8ac30a00720 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -211,11 +211,11 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
211 | if (!dump_base_hdr) { | 211 | if (!dump_base_hdr) { |
212 | len += snprintf(buf + len, size - len, | 212 | len += snprintf(buf + len, size - len, |
213 | "%20s :\n", "2GHz modal Header"); | 213 | "%20s :\n", "2GHz modal Header"); |
214 | len += ath9k_def_dump_modal_eeprom(buf, len, size, | 214 | len = ath9k_def_dump_modal_eeprom(buf, len, size, |
215 | &eep->modalHeader[0]); | 215 | &eep->modalHeader[0]); |
216 | len += snprintf(buf + len, size - len, | 216 | len += snprintf(buf + len, size - len, |
217 | "%20s :\n", "5GHz modal Header"); | 217 | "%20s :\n", "5GHz modal Header"); |
218 | len += ath9k_def_dump_modal_eeprom(buf, len, size, | 218 | len = ath9k_def_dump_modal_eeprom(buf, len, size, |
219 | &eep->modalHeader[1]); | 219 | &eep->modalHeader[1]); |
220 | goto out; | 220 | goto out; |
221 | } | 221 | } |
@@ -264,8 +264,7 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, | |||
264 | 264 | ||
265 | static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | 265 | static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) |
266 | { | 266 | { |
267 | struct ar5416_eeprom_def *eep = | 267 | struct ar5416_eeprom_def *eep = &ah->eeprom.def; |
268 | (struct ar5416_eeprom_def *) &ah->eeprom.def; | ||
269 | struct ath_common *common = ath9k_hw_common(ah); | 268 | struct ath_common *common = ath9k_hw_common(ah); |
270 | u16 *eepdata, temp, magic, magic2; | 269 | u16 *eepdata, temp, magic, magic2; |
271 | u32 sum = 0, el; | 270 | u32 sum = 0, el; |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 281a9af0f1b6..af6d27350291 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -132,17 +132,18 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
132 | 132 | ||
133 | if (time_after(jiffies, btcoex->bt_priority_time + | 133 | if (time_after(jiffies, btcoex->bt_priority_time + |
134 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | 134 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { |
135 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 135 | clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
136 | clear_bit(BT_OP_SCAN, &btcoex->op_flags); | ||
136 | /* Detect if colocated bt started scanning */ | 137 | /* Detect if colocated bt started scanning */ |
137 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | 138 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { |
138 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 139 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
139 | "BT scan detected\n"); | 140 | "BT scan detected\n"); |
140 | sc->sc_flags |= (SC_OP_BT_SCAN | | 141 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
141 | SC_OP_BT_PRIORITY_DETECTED); | 142 | set_bit(BT_OP_SCAN, &btcoex->op_flags); |
142 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | 143 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { |
143 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 144 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
144 | "BT priority traffic detected\n"); | 145 | "BT priority traffic detected\n"); |
145 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | 146 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
146 | } | 147 | } |
147 | 148 | ||
148 | btcoex->bt_priority_cnt = 0; | 149 | btcoex->bt_priority_cnt = 0; |
@@ -190,13 +191,26 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
190 | struct ath_softc *sc = (struct ath_softc *) data; | 191 | struct ath_softc *sc = (struct ath_softc *) data; |
191 | struct ath_hw *ah = sc->sc_ah; | 192 | struct ath_hw *ah = sc->sc_ah; |
192 | struct ath_btcoex *btcoex = &sc->btcoex; | 193 | struct ath_btcoex *btcoex = &sc->btcoex; |
194 | struct ath_mci_profile *mci = &btcoex->mci; | ||
193 | u32 timer_period; | 195 | u32 timer_period; |
194 | bool is_btscan; | 196 | bool is_btscan; |
195 | 197 | ||
196 | ath9k_ps_wakeup(sc); | 198 | ath9k_ps_wakeup(sc); |
197 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 199 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
198 | ath_detect_bt_priority(sc); | 200 | ath_detect_bt_priority(sc); |
199 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 201 | is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); |
202 | |||
203 | btcoex->bt_wait_time += btcoex->btcoex_period; | ||
204 | if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { | ||
205 | if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP, NULL) && | ||
206 | (mci->num_pan || mci->num_other_acl)) | ||
207 | ah->btcoex_hw.mci.stomp_ftp = | ||
208 | (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); | ||
209 | else | ||
210 | ah->btcoex_hw.mci.stomp_ftp = false; | ||
211 | btcoex->bt_wait_time = 0; | ||
212 | sc->rx.num_pkts = 0; | ||
213 | } | ||
200 | 214 | ||
201 | spin_lock_bh(&btcoex->btcoex_lock); | 215 | spin_lock_bh(&btcoex->btcoex_lock); |
202 | 216 | ||
@@ -219,8 +233,7 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
219 | 233 | ||
220 | ath9k_ps_restore(sc); | 234 | ath9k_ps_restore(sc); |
221 | timer_period = btcoex->btcoex_period / 1000; | 235 | timer_period = btcoex->btcoex_period / 1000; |
222 | mod_timer(&btcoex->period_timer, jiffies + | 236 | mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); |
223 | msecs_to_jiffies(timer_period)); | ||
224 | } | 237 | } |
225 | 238 | ||
226 | /* | 239 | /* |
@@ -233,14 +246,14 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
233 | struct ath_hw *ah = sc->sc_ah; | 246 | struct ath_hw *ah = sc->sc_ah; |
234 | struct ath_btcoex *btcoex = &sc->btcoex; | 247 | struct ath_btcoex *btcoex = &sc->btcoex; |
235 | struct ath_common *common = ath9k_hw_common(ah); | 248 | struct ath_common *common = ath9k_hw_common(ah); |
236 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||
237 | 249 | ||
238 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); | 250 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); |
239 | 251 | ||
240 | ath9k_ps_wakeup(sc); | 252 | ath9k_ps_wakeup(sc); |
241 | spin_lock_bh(&btcoex->btcoex_lock); | 253 | spin_lock_bh(&btcoex->btcoex_lock); |
242 | 254 | ||
243 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 255 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || |
256 | test_bit(BT_OP_SCAN, &btcoex->op_flags)) | ||
244 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 257 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
245 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 258 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
246 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | 259 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
@@ -292,7 +305,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
292 | 305 | ||
293 | btcoex->bt_priority_cnt = 0; | 306 | btcoex->bt_priority_cnt = 0; |
294 | btcoex->bt_priority_time = jiffies; | 307 | btcoex->bt_priority_time = jiffies; |
295 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 308 | btcoex->op_flags &= ~(BT_OP_PRIORITY_DETECTED | BT_OP_SCAN); |
296 | 309 | ||
297 | mod_timer(&btcoex->period_timer, jiffies); | 310 | mod_timer(&btcoex->period_timer, jiffies); |
298 | } | 311 | } |
@@ -316,12 +329,13 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) | |||
316 | 329 | ||
317 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 330 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
318 | { | 331 | { |
332 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
319 | struct ath_mci_profile *mci = &sc->btcoex.mci; | 333 | struct ath_mci_profile *mci = &sc->btcoex.mci; |
320 | u16 aggr_limit = 0; | 334 | u16 aggr_limit = 0; |
321 | 335 | ||
322 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) | 336 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) |
323 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; | 337 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; |
324 | else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | 338 | else if (test_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags)) |
325 | aggr_limit = min((max_4ms_framelen * 3) / 8, | 339 | aggr_limit = min((max_4ms_framelen * 3) / 8, |
326 | (u32)ATH_AMPDU_LIMIT_MAX); | 340 | (u32)ATH_AMPDU_LIMIT_MAX); |
327 | 341 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7db1890448f2..45e670087e1c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -390,14 +390,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) | |||
390 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 390 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
391 | } | 391 | } |
392 | 392 | ||
393 | static void ath9k_hw_aspm_init(struct ath_hw *ah) | ||
394 | { | ||
395 | struct ath_common *common = ath9k_hw_common(ah); | ||
396 | |||
397 | if (common->bus_ops->aspm_init) | ||
398 | common->bus_ops->aspm_init(common); | ||
399 | } | ||
400 | |||
401 | /* This should work for all families including legacy */ | 393 | /* This should work for all families including legacy */ |
402 | static bool ath9k_hw_chip_test(struct ath_hw *ah) | 394 | static bool ath9k_hw_chip_test(struct ath_hw *ah) |
403 | { | 395 | { |
@@ -693,9 +685,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
693 | if (r) | 685 | if (r) |
694 | return r; | 686 | return r; |
695 | 687 | ||
696 | if (ah->is_pciexpress) | ||
697 | ath9k_hw_aspm_init(ah); | ||
698 | |||
699 | r = ath9k_hw_init_macaddr(ah); | 688 | r = ath9k_hw_init_macaddr(ah); |
700 | if (r) { | 689 | if (r) { |
701 | ath_err(common, "Failed to initialize MAC address\n"); | 690 | ath_err(common, "Failed to initialize MAC address\n"); |
@@ -1443,9 +1432,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1443 | break; | 1432 | break; |
1444 | } | 1433 | } |
1445 | 1434 | ||
1446 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
1447 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
1448 | |||
1449 | return ret; | 1435 | return ret; |
1450 | } | 1436 | } |
1451 | 1437 | ||
@@ -1721,7 +1707,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) | |||
1721 | ath9k_hw_loadnf(ah, ah->curchan); | 1707 | ath9k_hw_loadnf(ah, ah->curchan); |
1722 | ath9k_hw_start_nfcal(ah, true); | 1708 | ath9k_hw_start_nfcal(ah, true); |
1723 | 1709 | ||
1724 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) | 1710 | if (ath9k_hw_mci_is_enabled(ah)) |
1725 | ar9003_mci_2g5g_switch(ah, true); | 1711 | ar9003_mci_2g5g_switch(ah, true); |
1726 | 1712 | ||
1727 | if (AR_SREV_9271(ah)) | 1713 | if (AR_SREV_9271(ah)) |
@@ -1742,10 +1728,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1742 | u64 tsf = 0; | 1728 | u64 tsf = 0; |
1743 | int i, r; | 1729 | int i, r; |
1744 | bool start_mci_reset = false; | 1730 | bool start_mci_reset = false; |
1745 | bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
1746 | bool save_fullsleep = ah->chip_fullsleep; | 1731 | bool save_fullsleep = ah->chip_fullsleep; |
1747 | 1732 | ||
1748 | if (mci) { | 1733 | if (ath9k_hw_mci_is_enabled(ah)) { |
1749 | start_mci_reset = ar9003_mci_start_reset(ah, chan); | 1734 | start_mci_reset = ar9003_mci_start_reset(ah, chan); |
1750 | if (start_mci_reset) | 1735 | if (start_mci_reset) |
1751 | return 0; | 1736 | return 0; |
@@ -1774,7 +1759,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1774 | return r; | 1759 | return r; |
1775 | } | 1760 | } |
1776 | 1761 | ||
1777 | if (mci) | 1762 | if (ath9k_hw_mci_is_enabled(ah)) |
1778 | ar9003_mci_stop_bt(ah, save_fullsleep); | 1763 | ar9003_mci_stop_bt(ah, save_fullsleep); |
1779 | 1764 | ||
1780 | saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); | 1765 | saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); |
@@ -1832,7 +1817,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1832 | if (r) | 1817 | if (r) |
1833 | return r; | 1818 | return r; |
1834 | 1819 | ||
1835 | if (mci) | 1820 | if (ath9k_hw_mci_is_enabled(ah)) |
1836 | ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); | 1821 | ar9003_mci_reset(ah, false, IS_CHAN_2GHZ(chan), save_fullsleep); |
1837 | 1822 | ||
1838 | /* | 1823 | /* |
@@ -1951,7 +1936,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1951 | ath9k_hw_loadnf(ah, chan); | 1936 | ath9k_hw_loadnf(ah, chan); |
1952 | ath9k_hw_start_nfcal(ah, true); | 1937 | ath9k_hw_start_nfcal(ah, true); |
1953 | 1938 | ||
1954 | if (mci && ar9003_mci_end_reset(ah, chan, caldata)) | 1939 | if (ath9k_hw_mci_is_enabled(ah) && ar9003_mci_end_reset(ah, chan, caldata)) |
1955 | return -EIO; | 1940 | return -EIO; |
1956 | 1941 | ||
1957 | ENABLE_REGWRITE_BUFFER(ah); | 1942 | ENABLE_REGWRITE_BUFFER(ah); |
@@ -1996,7 +1981,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1996 | if (ath9k_hw_btcoex_is_enabled(ah)) | 1981 | if (ath9k_hw_btcoex_is_enabled(ah)) |
1997 | ath9k_hw_btcoex_enable(ah); | 1982 | ath9k_hw_btcoex_enable(ah); |
1998 | 1983 | ||
1999 | if (mci) | 1984 | if (ath9k_hw_mci_is_enabled(ah)) |
2000 | ar9003_mci_check_bt(ah); | 1985 | ar9003_mci_check_bt(ah); |
2001 | 1986 | ||
2002 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 1987 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
@@ -2019,39 +2004,35 @@ EXPORT_SYMBOL(ath9k_hw_reset); | |||
2019 | * Notify Power Mgt is disabled in self-generated frames. | 2004 | * Notify Power Mgt is disabled in self-generated frames. |
2020 | * If requested, force chip to sleep. | 2005 | * If requested, force chip to sleep. |
2021 | */ | 2006 | */ |
2022 | static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | 2007 | static void ath9k_set_power_sleep(struct ath_hw *ah) |
2023 | { | 2008 | { |
2024 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2009 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
2025 | if (setChip) { | ||
2026 | if (AR_SREV_9462(ah)) { | ||
2027 | REG_WRITE(ah, AR_TIMER_MODE, | ||
2028 | REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00); | ||
2029 | REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah, | ||
2030 | AR_NDP2_TIMER_MODE) & 0xFFFFFF00); | ||
2031 | REG_WRITE(ah, AR_SLP32_INC, | ||
2032 | REG_READ(ah, AR_SLP32_INC) & 0xFFF00000); | ||
2033 | /* xxx Required for WLAN only case ? */ | ||
2034 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); | ||
2035 | udelay(100); | ||
2036 | } | ||
2037 | 2010 | ||
2038 | /* | 2011 | if (AR_SREV_9462(ah)) { |
2039 | * Clear the RTC force wake bit to allow the | 2012 | REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff); |
2040 | * mac to go to sleep. | 2013 | REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff); |
2041 | */ | 2014 | REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff); |
2042 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); | 2015 | /* xxx Required for WLAN only case ? */ |
2016 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); | ||
2017 | udelay(100); | ||
2018 | } | ||
2043 | 2019 | ||
2044 | if (AR_SREV_9462(ah)) | 2020 | /* |
2045 | udelay(100); | 2021 | * Clear the RTC force wake bit to allow the |
2022 | * mac to go to sleep. | ||
2023 | */ | ||
2024 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); | ||
2025 | |||
2026 | if (ath9k_hw_mci_is_enabled(ah)) | ||
2027 | udelay(100); | ||
2046 | 2028 | ||
2047 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) | 2029 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) |
2048 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 2030 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); |
2049 | 2031 | ||
2050 | /* Shutdown chip. Active low */ | 2032 | /* Shutdown chip. Active low */ |
2051 | if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { | 2033 | if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { |
2052 | REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); | 2034 | REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); |
2053 | udelay(2); | 2035 | udelay(2); |
2054 | } | ||
2055 | } | 2036 | } |
2056 | 2037 | ||
2057 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ | 2038 | /* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */ |
@@ -2064,44 +2045,38 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | |||
2064 | * frames. If request, set power mode of chip to | 2045 | * frames. If request, set power mode of chip to |
2065 | * auto/normal. Duration in units of 128us (1/8 TU). | 2046 | * auto/normal. Duration in units of 128us (1/8 TU). |
2066 | */ | 2047 | */ |
2067 | static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | 2048 | static void ath9k_set_power_network_sleep(struct ath_hw *ah) |
2068 | { | 2049 | { |
2069 | u32 val; | 2050 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
2070 | 2051 | ||
2071 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2052 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
2072 | if (setChip) { | ||
2073 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2074 | 2053 | ||
2075 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 2054 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
2076 | /* Set WakeOnInterrupt bit; clear ForceWake bit */ | 2055 | /* Set WakeOnInterrupt bit; clear ForceWake bit */ |
2077 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | 2056 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, |
2078 | AR_RTC_FORCE_WAKE_ON_INT); | 2057 | AR_RTC_FORCE_WAKE_ON_INT); |
2079 | } else { | 2058 | } else { |
2080 | 2059 | ||
2081 | /* When chip goes into network sleep, it could be waken | 2060 | /* When chip goes into network sleep, it could be waken |
2082 | * up by MCI_INT interrupt caused by BT's HW messages | 2061 | * up by MCI_INT interrupt caused by BT's HW messages |
2083 | * (LNA_xxx, CONT_xxx) which chould be in a very fast | 2062 | * (LNA_xxx, CONT_xxx) which chould be in a very fast |
2084 | * rate (~100us). This will cause chip to leave and | 2063 | * rate (~100us). This will cause chip to leave and |
2085 | * re-enter network sleep mode frequently, which in | 2064 | * re-enter network sleep mode frequently, which in |
2086 | * consequence will have WLAN MCI HW to generate lots of | 2065 | * consequence will have WLAN MCI HW to generate lots of |
2087 | * SYS_WAKING and SYS_SLEEPING messages which will make | 2066 | * SYS_WAKING and SYS_SLEEPING messages which will make |
2088 | * BT CPU to busy to process. | 2067 | * BT CPU to busy to process. |
2089 | */ | 2068 | */ |
2090 | if (AR_SREV_9462(ah)) { | 2069 | if (ath9k_hw_mci_is_enabled(ah)) |
2091 | val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) & | 2070 | REG_CLR_BIT(ah, AR_MCI_INTERRUPT_RX_MSG_EN, |
2092 | ~AR_MCI_INTERRUPT_RX_HW_MSG_MASK; | 2071 | AR_MCI_INTERRUPT_RX_HW_MSG_MASK); |
2093 | REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val); | 2072 | /* |
2094 | } | 2073 | * Clear the RTC force wake bit to allow the |
2095 | /* | 2074 | * mac to go to sleep. |
2096 | * Clear the RTC force wake bit to allow the | 2075 | */ |
2097 | * mac to go to sleep. | 2076 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); |
2098 | */ | 2077 | |
2099 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | 2078 | if (ath9k_hw_mci_is_enabled(ah)) |
2100 | AR_RTC_FORCE_WAKE_EN); | 2079 | udelay(30); |
2101 | |||
2102 | if (AR_SREV_9462(ah)) | ||
2103 | udelay(30); | ||
2104 | } | ||
2105 | } | 2080 | } |
2106 | 2081 | ||
2107 | /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ | 2082 | /* Clear Bit 14 of AR_WA after putting chip into Net Sleep mode. */ |
@@ -2109,7 +2084,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | |||
2109 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); | 2084 | REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE); |
2110 | } | 2085 | } |
2111 | 2086 | ||
2112 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | 2087 | static bool ath9k_hw_set_power_awake(struct ath_hw *ah) |
2113 | { | 2088 | { |
2114 | u32 val; | 2089 | u32 val; |
2115 | int i; | 2090 | int i; |
@@ -2120,37 +2095,35 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2120 | udelay(10); | 2095 | udelay(10); |
2121 | } | 2096 | } |
2122 | 2097 | ||
2123 | if (setChip) { | 2098 | if ((REG_READ(ah, AR_RTC_STATUS) & |
2124 | if ((REG_READ(ah, AR_RTC_STATUS) & | 2099 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { |
2125 | AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { | 2100 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
2126 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 2101 | return false; |
2127 | return false; | ||
2128 | } | ||
2129 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
2130 | ath9k_hw_init_pll(ah, NULL); | ||
2131 | } | 2102 | } |
2132 | if (AR_SREV_9100(ah)) | 2103 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
2133 | REG_SET_BIT(ah, AR_RTC_RESET, | 2104 | ath9k_hw_init_pll(ah, NULL); |
2134 | AR_RTC_RESET_EN); | 2105 | } |
2106 | if (AR_SREV_9100(ah)) | ||
2107 | REG_SET_BIT(ah, AR_RTC_RESET, | ||
2108 | AR_RTC_RESET_EN); | ||
2135 | 2109 | ||
2110 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2111 | AR_RTC_FORCE_WAKE_EN); | ||
2112 | udelay(50); | ||
2113 | |||
2114 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | ||
2115 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | ||
2116 | if (val == AR_RTC_STATUS_ON) | ||
2117 | break; | ||
2118 | udelay(50); | ||
2136 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2119 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
2137 | AR_RTC_FORCE_WAKE_EN); | 2120 | AR_RTC_FORCE_WAKE_EN); |
2138 | udelay(50); | 2121 | } |
2139 | 2122 | if (i == 0) { | |
2140 | for (i = POWER_UP_TIME / 50; i > 0; i--) { | 2123 | ath_err(ath9k_hw_common(ah), |
2141 | val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; | 2124 | "Failed to wakeup in %uus\n", |
2142 | if (val == AR_RTC_STATUS_ON) | 2125 | POWER_UP_TIME / 20); |
2143 | break; | 2126 | return false; |
2144 | udelay(50); | ||
2145 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | ||
2146 | AR_RTC_FORCE_WAKE_EN); | ||
2147 | } | ||
2148 | if (i == 0) { | ||
2149 | ath_err(ath9k_hw_common(ah), | ||
2150 | "Failed to wakeup in %uus\n", | ||
2151 | POWER_UP_TIME / 20); | ||
2152 | return false; | ||
2153 | } | ||
2154 | } | 2127 | } |
2155 | 2128 | ||
2156 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 2129 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
@@ -2161,7 +2134,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2161 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | 2134 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) |
2162 | { | 2135 | { |
2163 | struct ath_common *common = ath9k_hw_common(ah); | 2136 | struct ath_common *common = ath9k_hw_common(ah); |
2164 | int status = true, setChip = true; | 2137 | int status = true; |
2165 | static const char *modes[] = { | 2138 | static const char *modes[] = { |
2166 | "AWAKE", | 2139 | "AWAKE", |
2167 | "FULL-SLEEP", | 2140 | "FULL-SLEEP", |
@@ -2177,25 +2150,17 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | |||
2177 | 2150 | ||
2178 | switch (mode) { | 2151 | switch (mode) { |
2179 | case ATH9K_PM_AWAKE: | 2152 | case ATH9K_PM_AWAKE: |
2180 | status = ath9k_hw_set_power_awake(ah, setChip); | 2153 | status = ath9k_hw_set_power_awake(ah); |
2181 | |||
2182 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
2183 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
2184 | |||
2185 | break; | 2154 | break; |
2186 | case ATH9K_PM_FULL_SLEEP: | 2155 | case ATH9K_PM_FULL_SLEEP: |
2187 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | 2156 | if (ath9k_hw_mci_is_enabled(ah)) |
2188 | ar9003_mci_set_full_sleep(ah); | 2157 | ar9003_mci_set_full_sleep(ah); |
2189 | 2158 | ||
2190 | ath9k_set_power_sleep(ah, setChip); | 2159 | ath9k_set_power_sleep(ah); |
2191 | ah->chip_fullsleep = true; | 2160 | ah->chip_fullsleep = true; |
2192 | break; | 2161 | break; |
2193 | case ATH9K_PM_NETWORK_SLEEP: | 2162 | case ATH9K_PM_NETWORK_SLEEP: |
2194 | 2163 | ath9k_set_power_network_sleep(ah); | |
2195 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
2196 | REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); | ||
2197 | |||
2198 | ath9k_set_power_network_sleep(ah, setChip); | ||
2199 | break; | 2164 | break; |
2200 | default: | 2165 | default: |
2201 | ath_err(common, "Unknown power mode %u\n", mode); | 2166 | ath_err(common, "Unknown power mode %u\n", mode); |
@@ -2765,6 +2730,9 @@ EXPORT_SYMBOL(ath9k_hw_setrxfilter); | |||
2765 | 2730 | ||
2766 | bool ath9k_hw_phy_disable(struct ath_hw *ah) | 2731 | bool ath9k_hw_phy_disable(struct ath_hw *ah) |
2767 | { | 2732 | { |
2733 | if (ath9k_hw_mci_is_enabled(ah)) | ||
2734 | ar9003_mci_bt_gain_ctrl(ah); | ||
2735 | |||
2768 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) | 2736 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) |
2769 | return false; | 2737 | return false; |
2770 | 2738 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index b620c557c2a6..03d590924c64 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -824,7 +824,6 @@ struct ath_hw { | |||
824 | struct ar5416IniArray ini_japan2484; | 824 | struct ar5416IniArray ini_japan2484; |
825 | struct ar5416IniArray iniModes_9271_ANI_reg; | 825 | struct ar5416IniArray iniModes_9271_ANI_reg; |
826 | struct ar5416IniArray ini_radio_post_sys2ant; | 826 | struct ar5416IniArray ini_radio_post_sys2ant; |
827 | struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; | ||
828 | 827 | ||
829 | struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; | 828 | struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; |
830 | struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; | 829 | struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; |
@@ -1037,6 +1036,11 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | |||
1037 | { | 1036 | { |
1038 | return ah->btcoex_hw.enabled; | 1037 | return ah->btcoex_hw.enabled; |
1039 | } | 1038 | } |
1039 | static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) | ||
1040 | { | ||
1041 | return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); | ||
1042 | |||
1043 | } | ||
1040 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | 1044 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); |
1041 | static inline enum ath_btcoex_scheme | 1045 | static inline enum ath_btcoex_scheme |
1042 | ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) | 1046 | ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) |
@@ -1048,6 +1052,10 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | |||
1048 | { | 1052 | { |
1049 | return false; | 1053 | return false; |
1050 | } | 1054 | } |
1055 | static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) | ||
1056 | { | ||
1057 | return false; | ||
1058 | } | ||
1051 | static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) | 1059 | static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) |
1052 | { | 1060 | { |
1053 | } | 1061 | } |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index dee9e092449a..9dfce1a69c73 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -489,6 +489,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
489 | 489 | ||
490 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 490 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
491 | 491 | ||
492 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
492 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 493 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
493 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | 494 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); |
494 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 495 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
@@ -560,6 +561,12 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
560 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 561 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, |
561 | (unsigned long)sc); | 562 | (unsigned long)sc); |
562 | 563 | ||
564 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
565 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
566 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
567 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
568 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
569 | |||
563 | /* | 570 | /* |
564 | * Cache line size is used to size and align various | 571 | * Cache line size is used to size and align various |
565 | * structures used to communicate with the hardware. | 572 | * structures used to communicate with the hardware. |
@@ -590,6 +597,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
590 | ath9k_cmn_init_crypto(sc->sc_ah); | 597 | ath9k_cmn_init_crypto(sc->sc_ah); |
591 | ath9k_init_misc(sc); | 598 | ath9k_init_misc(sc); |
592 | 599 | ||
600 | if (common->bus_ops->aspm_init) | ||
601 | common->bus_ops->aspm_init(common); | ||
602 | |||
593 | return 0; | 603 | return 0; |
594 | 604 | ||
595 | err_btcoex: | 605 | err_btcoex: |
@@ -782,11 +792,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
782 | ARRAY_SIZE(ath9k_tpt_blink)); | 792 | ARRAY_SIZE(ath9k_tpt_blink)); |
783 | #endif | 793 | #endif |
784 | 794 | ||
785 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | ||
786 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
787 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||
788 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
789 | |||
790 | /* Register with mac80211 */ | 795 | /* Register with mac80211 */ |
791 | error = ieee80211_register_hw(hw); | 796 | error = ieee80211_register_hw(hw); |
792 | if (error) | 797 | if (error) |
@@ -805,9 +810,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
805 | goto error_world; | 810 | goto error_world; |
806 | } | 811 | } |
807 | 812 | ||
808 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
809 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
810 | |||
811 | ath_init_leds(sc); | 813 | ath_init_leds(sc); |
812 | ath_start_rfkill_poll(sc); | 814 | ath_start_rfkill_poll(sc); |
813 | 815 | ||
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c new file mode 100644 index 000000000000..0cc4c70f7f0c --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -0,0 +1,502 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | |||
19 | /* | ||
20 | * TX polling - checks if the TX engine is stuck somewhere | ||
21 | * and issues a chip reset if so. | ||
22 | */ | ||
23 | void ath_tx_complete_poll_work(struct work_struct *work) | ||
24 | { | ||
25 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
26 | tx_complete_work.work); | ||
27 | struct ath_txq *txq; | ||
28 | int i; | ||
29 | bool needreset = false; | ||
30 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
31 | sc->tx_complete_poll_work_seen++; | ||
32 | #endif | ||
33 | |||
34 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
35 | if (ATH_TXQ_SETUP(sc, i)) { | ||
36 | txq = &sc->tx.txq[i]; | ||
37 | ath_txq_lock(sc, txq); | ||
38 | if (txq->axq_depth) { | ||
39 | if (txq->axq_tx_inprogress) { | ||
40 | needreset = true; | ||
41 | ath_txq_unlock(sc, txq); | ||
42 | break; | ||
43 | } else { | ||
44 | txq->axq_tx_inprogress = true; | ||
45 | } | ||
46 | } | ||
47 | ath_txq_unlock_complete(sc, txq); | ||
48 | } | ||
49 | |||
50 | if (needreset) { | ||
51 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, | ||
52 | "tx hung, resetting the chip\n"); | ||
53 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | ||
54 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
59 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Checks if the BB/MAC is hung. | ||
64 | */ | ||
65 | void ath_hw_check(struct work_struct *work) | ||
66 | { | ||
67 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); | ||
68 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
69 | unsigned long flags; | ||
70 | int busy; | ||
71 | u8 is_alive, nbeacon = 1; | ||
72 | |||
73 | ath9k_ps_wakeup(sc); | ||
74 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | ||
75 | |||
76 | if (is_alive && !AR_SREV_9300(sc->sc_ah)) | ||
77 | goto out; | ||
78 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | ||
79 | ath_dbg(common, RESET, | ||
80 | "DCU stuck is detected. Schedule chip reset\n"); | ||
81 | RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); | ||
82 | goto sched_reset; | ||
83 | } | ||
84 | |||
85 | spin_lock_irqsave(&common->cc_lock, flags); | ||
86 | busy = ath_update_survey_stats(sc); | ||
87 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
88 | |||
89 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", | ||
90 | busy, sc->hw_busy_count + 1); | ||
91 | if (busy >= 99) { | ||
92 | if (++sc->hw_busy_count >= 3) { | ||
93 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | ||
94 | goto sched_reset; | ||
95 | } | ||
96 | } else if (busy >= 0) { | ||
97 | sc->hw_busy_count = 0; | ||
98 | nbeacon = 3; | ||
99 | } | ||
100 | |||
101 | ath_start_rx_poll(sc, nbeacon); | ||
102 | goto out; | ||
103 | |||
104 | sched_reset: | ||
105 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
106 | out: | ||
107 | ath9k_ps_restore(sc); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * PLL-WAR for AR9485/AR9340 | ||
112 | */ | ||
113 | static bool ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
114 | { | ||
115 | static int count; | ||
116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
117 | |||
118 | if (pll_sqsum >= 0x40000) { | ||
119 | count++; | ||
120 | if (count == 3) { | ||
121 | ath_dbg(common, RESET, "PLL WAR, resetting the chip\n"); | ||
122 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | ||
123 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
124 | count = 0; | ||
125 | return true; | ||
126 | } | ||
127 | } else { | ||
128 | count = 0; | ||
129 | } | ||
130 | |||
131 | return false; | ||
132 | } | ||
133 | |||
134 | void ath_hw_pll_work(struct work_struct *work) | ||
135 | { | ||
136 | u32 pll_sqsum; | ||
137 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
138 | hw_pll_work.work); | ||
139 | |||
140 | ath9k_ps_wakeup(sc); | ||
141 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
142 | ath9k_ps_restore(sc); | ||
143 | if (ath_hw_pll_rx_hang_check(sc, pll_sqsum)) | ||
144 | return; | ||
145 | |||
146 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, | ||
147 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * RX Polling - monitors baseband hangs. | ||
152 | */ | ||
153 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) | ||
154 | { | ||
155 | if (!AR_SREV_9300(sc->sc_ah)) | ||
156 | return; | ||
157 | |||
158 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
159 | return; | ||
160 | |||
161 | mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies | ||
162 | (nbeacon * sc->cur_beacon_conf.beacon_interval)); | ||
163 | } | ||
164 | |||
165 | void ath_rx_poll(unsigned long data) | ||
166 | { | ||
167 | struct ath_softc *sc = (struct ath_softc *)data; | ||
168 | |||
169 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * PA Pre-distortion. | ||
174 | */ | ||
175 | static void ath_paprd_activate(struct ath_softc *sc) | ||
176 | { | ||
177 | struct ath_hw *ah = sc->sc_ah; | ||
178 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
179 | int chain; | ||
180 | |||
181 | if (!caldata || !caldata->paprd_done) | ||
182 | return; | ||
183 | |||
184 | ath9k_ps_wakeup(sc); | ||
185 | ar9003_paprd_enable(ah, false); | ||
186 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
187 | if (!(ah->txchainmask & BIT(chain))) | ||
188 | continue; | ||
189 | |||
190 | ar9003_paprd_populate_single_table(ah, caldata, chain); | ||
191 | } | ||
192 | |||
193 | ar9003_paprd_enable(ah, true); | ||
194 | ath9k_ps_restore(sc); | ||
195 | } | ||
196 | |||
197 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
198 | { | ||
199 | struct ieee80211_hw *hw = sc->hw; | ||
200 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
201 | struct ath_hw *ah = sc->sc_ah; | ||
202 | struct ath_common *common = ath9k_hw_common(ah); | ||
203 | struct ath_tx_control txctl; | ||
204 | int time_left; | ||
205 | |||
206 | memset(&txctl, 0, sizeof(txctl)); | ||
207 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
208 | |||
209 | memset(tx_info, 0, sizeof(*tx_info)); | ||
210 | tx_info->band = hw->conf.channel->band; | ||
211 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
212 | tx_info->control.rates[0].idx = 0; | ||
213 | tx_info->control.rates[0].count = 1; | ||
214 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
215 | tx_info->control.rates[1].idx = -1; | ||
216 | |||
217 | init_completion(&sc->paprd_complete); | ||
218 | txctl.paprd = BIT(chain); | ||
219 | |||
220 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
221 | ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); | ||
222 | dev_kfree_skb_any(skb); | ||
223 | return false; | ||
224 | } | ||
225 | |||
226 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
227 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
228 | |||
229 | if (!time_left) | ||
230 | ath_dbg(common, CALIBRATE, | ||
231 | "Timeout waiting for paprd training on TX chain %d\n", | ||
232 | chain); | ||
233 | |||
234 | return !!time_left; | ||
235 | } | ||
236 | |||
237 | void ath_paprd_calibrate(struct work_struct *work) | ||
238 | { | ||
239 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | ||
240 | struct ieee80211_hw *hw = sc->hw; | ||
241 | struct ath_hw *ah = sc->sc_ah; | ||
242 | struct ieee80211_hdr *hdr; | ||
243 | struct sk_buff *skb = NULL; | ||
244 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
245 | struct ath_common *common = ath9k_hw_common(ah); | ||
246 | int ftype; | ||
247 | int chain_ok = 0; | ||
248 | int chain; | ||
249 | int len = 1800; | ||
250 | |||
251 | if (!caldata) | ||
252 | return; | ||
253 | |||
254 | ath9k_ps_wakeup(sc); | ||
255 | |||
256 | if (ar9003_paprd_init_table(ah) < 0) | ||
257 | goto fail_paprd; | ||
258 | |||
259 | skb = alloc_skb(len, GFP_KERNEL); | ||
260 | if (!skb) | ||
261 | goto fail_paprd; | ||
262 | |||
263 | skb_put(skb, len); | ||
264 | memset(skb->data, 0, len); | ||
265 | hdr = (struct ieee80211_hdr *)skb->data; | ||
266 | ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; | ||
267 | hdr->frame_control = cpu_to_le16(ftype); | ||
268 | hdr->duration_id = cpu_to_le16(10); | ||
269 | memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); | ||
270 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | ||
271 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | ||
272 | |||
273 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
274 | if (!(ah->txchainmask & BIT(chain))) | ||
275 | continue; | ||
276 | |||
277 | chain_ok = 0; | ||
278 | |||
279 | ath_dbg(common, CALIBRATE, | ||
280 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
281 | chain); | ||
282 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
283 | goto fail_paprd; | ||
284 | |||
285 | ar9003_paprd_setup_gain_table(ah, chain); | ||
286 | |||
287 | ath_dbg(common, CALIBRATE, | ||
288 | "Sending PAPRD training frame on chain %d\n", chain); | ||
289 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
290 | goto fail_paprd; | ||
291 | |||
292 | if (!ar9003_paprd_is_done(ah)) { | ||
293 | ath_dbg(common, CALIBRATE, | ||
294 | "PAPRD not yet done on chain %d\n", chain); | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | ||
299 | ath_dbg(common, CALIBRATE, | ||
300 | "PAPRD create curve failed on chain %d\n", | ||
301 | chain); | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | chain_ok = 1; | ||
306 | } | ||
307 | kfree_skb(skb); | ||
308 | |||
309 | if (chain_ok) { | ||
310 | caldata->paprd_done = true; | ||
311 | ath_paprd_activate(sc); | ||
312 | } | ||
313 | |||
314 | fail_paprd: | ||
315 | ath9k_ps_restore(sc); | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * ANI performs periodic noise floor calibration | ||
320 | * that is used to adjust and optimize the chip performance. This | ||
321 | * takes environmental changes (location, temperature) into account. | ||
322 | * When the task is complete, it reschedules itself depending on the | ||
323 | * appropriate interval that was calculated. | ||
324 | */ | ||
325 | void ath_ani_calibrate(unsigned long data) | ||
326 | { | ||
327 | struct ath_softc *sc = (struct ath_softc *)data; | ||
328 | struct ath_hw *ah = sc->sc_ah; | ||
329 | struct ath_common *common = ath9k_hw_common(ah); | ||
330 | bool longcal = false; | ||
331 | bool shortcal = false; | ||
332 | bool aniflag = false; | ||
333 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
334 | u32 cal_interval, short_cal_interval, long_cal_interval; | ||
335 | unsigned long flags; | ||
336 | |||
337 | if (ah->caldata && ah->caldata->nfcal_interference) | ||
338 | long_cal_interval = ATH_LONG_CALINTERVAL_INT; | ||
339 | else | ||
340 | long_cal_interval = ATH_LONG_CALINTERVAL; | ||
341 | |||
342 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | ||
343 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | ||
344 | |||
345 | /* Only calibrate if awake */ | ||
346 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | ||
347 | goto set_timer; | ||
348 | |||
349 | ath9k_ps_wakeup(sc); | ||
350 | |||
351 | /* Long calibration runs independently of short calibration. */ | ||
352 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | ||
353 | longcal = true; | ||
354 | common->ani.longcal_timer = timestamp; | ||
355 | } | ||
356 | |||
357 | /* Short calibration applies only while caldone is false */ | ||
358 | if (!common->ani.caldone) { | ||
359 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | ||
360 | shortcal = true; | ||
361 | common->ani.shortcal_timer = timestamp; | ||
362 | common->ani.resetcal_timer = timestamp; | ||
363 | } | ||
364 | } else { | ||
365 | if ((timestamp - common->ani.resetcal_timer) >= | ||
366 | ATH_RESTART_CALINTERVAL) { | ||
367 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
368 | if (common->ani.caldone) | ||
369 | common->ani.resetcal_timer = timestamp; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* Verify whether we must check ANI */ | ||
374 | if (sc->sc_ah->config.enable_ani | ||
375 | && (timestamp - common->ani.checkani_timer) >= | ||
376 | ah->config.ani_poll_interval) { | ||
377 | aniflag = true; | ||
378 | common->ani.checkani_timer = timestamp; | ||
379 | } | ||
380 | |||
381 | /* Call ANI routine if necessary */ | ||
382 | if (aniflag) { | ||
383 | spin_lock_irqsave(&common->cc_lock, flags); | ||
384 | ath9k_hw_ani_monitor(ah, ah->curchan); | ||
385 | ath_update_survey_stats(sc); | ||
386 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
387 | } | ||
388 | |||
389 | /* Perform calibration if necessary */ | ||
390 | if (longcal || shortcal) { | ||
391 | common->ani.caldone = | ||
392 | ath9k_hw_calibrate(ah, ah->curchan, | ||
393 | ah->rxchainmask, longcal); | ||
394 | } | ||
395 | |||
396 | ath_dbg(common, ANI, | ||
397 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", | ||
398 | jiffies, | ||
399 | longcal ? "long" : "", shortcal ? "short" : "", | ||
400 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | ||
401 | |||
402 | ath9k_ps_restore(sc); | ||
403 | |||
404 | set_timer: | ||
405 | /* | ||
406 | * Set timer interval based on previous results. | ||
407 | * The interval must be the shortest necessary to satisfy ANI, | ||
408 | * short calibration and long calibration. | ||
409 | */ | ||
410 | ath9k_debug_samp_bb_mac(sc); | ||
411 | cal_interval = ATH_LONG_CALINTERVAL; | ||
412 | if (sc->sc_ah->config.enable_ani) | ||
413 | cal_interval = min(cal_interval, | ||
414 | (u32)ah->config.ani_poll_interval); | ||
415 | if (!common->ani.caldone) | ||
416 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
417 | |||
418 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
419 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | ||
420 | if (!ah->caldata->paprd_done) | ||
421 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | ||
422 | else if (!ah->paprd_table_write_done) | ||
423 | ath_paprd_activate(sc); | ||
424 | } | ||
425 | } | ||
426 | |||
427 | void ath_start_ani(struct ath_common *common) | ||
428 | { | ||
429 | struct ath_hw *ah = common->ah; | ||
430 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
431 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
432 | |||
433 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) | ||
434 | return; | ||
435 | |||
436 | if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
437 | return; | ||
438 | |||
439 | common->ani.longcal_timer = timestamp; | ||
440 | common->ani.shortcal_timer = timestamp; | ||
441 | common->ani.checkani_timer = timestamp; | ||
442 | |||
443 | mod_timer(&common->ani.timer, | ||
444 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
445 | } | ||
446 | |||
447 | void ath_update_survey_nf(struct ath_softc *sc, int channel) | ||
448 | { | ||
449 | struct ath_hw *ah = sc->sc_ah; | ||
450 | struct ath9k_channel *chan = &ah->channels[channel]; | ||
451 | struct survey_info *survey = &sc->survey[channel]; | ||
452 | |||
453 | if (chan->noisefloor) { | ||
454 | survey->filled |= SURVEY_INFO_NOISE_DBM; | ||
455 | survey->noise = ath9k_hw_getchan_noise(ah, chan); | ||
456 | } | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * Updates the survey statistics and returns the busy time since last | ||
461 | * update in %, if the measurement duration was long enough for the | ||
462 | * result to be useful, -1 otherwise. | ||
463 | */ | ||
464 | int ath_update_survey_stats(struct ath_softc *sc) | ||
465 | { | ||
466 | struct ath_hw *ah = sc->sc_ah; | ||
467 | struct ath_common *common = ath9k_hw_common(ah); | ||
468 | int pos = ah->curchan - &ah->channels[0]; | ||
469 | struct survey_info *survey = &sc->survey[pos]; | ||
470 | struct ath_cycle_counters *cc = &common->cc_survey; | ||
471 | unsigned int div = common->clockrate * 1000; | ||
472 | int ret = 0; | ||
473 | |||
474 | if (!ah->curchan) | ||
475 | return -1; | ||
476 | |||
477 | if (ah->power_mode == ATH9K_PM_AWAKE) | ||
478 | ath_hw_cycle_counters_update(common); | ||
479 | |||
480 | if (cc->cycles > 0) { | ||
481 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | ||
482 | SURVEY_INFO_CHANNEL_TIME_BUSY | | ||
483 | SURVEY_INFO_CHANNEL_TIME_RX | | ||
484 | SURVEY_INFO_CHANNEL_TIME_TX; | ||
485 | survey->channel_time += cc->cycles / div; | ||
486 | survey->channel_time_busy += cc->rx_busy / div; | ||
487 | survey->channel_time_rx += cc->rx_frame / div; | ||
488 | survey->channel_time_tx += cc->tx_frame / div; | ||
489 | } | ||
490 | |||
491 | if (cc->cycles < div) | ||
492 | return -1; | ||
493 | |||
494 | if (cc->cycles > 0) | ||
495 | ret = cc->rx_busy * 100 / cc->cycles; | ||
496 | |||
497 | memset(cc, 0, sizeof(*cc)); | ||
498 | |||
499 | ath_update_survey_nf(sc, pos); | ||
500 | |||
501 | return ret; | ||
502 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4de4473776ac..c0f478b0a9a2 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -101,6 +101,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc) | |||
101 | spin_lock(&common->cc_lock); | 101 | spin_lock(&common->cc_lock); |
102 | ath_hw_cycle_counters_update(common); | 102 | ath_hw_cycle_counters_update(common); |
103 | memset(&common->cc_survey, 0, sizeof(common->cc_survey)); | 103 | memset(&common->cc_survey, 0, sizeof(common->cc_survey)); |
104 | memset(&common->cc_ani, 0, sizeof(common->cc_ani)); | ||
104 | spin_unlock(&common->cc_lock); | 105 | spin_unlock(&common->cc_lock); |
105 | } | 106 | } |
106 | 107 | ||
@@ -143,84 +144,6 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
143 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 144 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
144 | } | 145 | } |
145 | 146 | ||
146 | void ath_start_ani(struct ath_common *common) | ||
147 | { | ||
148 | struct ath_hw *ah = common->ah; | ||
149 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
150 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
151 | |||
152 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
153 | return; | ||
154 | |||
155 | if (sc->sc_flags & SC_OP_OFFCHANNEL) | ||
156 | return; | ||
157 | |||
158 | common->ani.longcal_timer = timestamp; | ||
159 | common->ani.shortcal_timer = timestamp; | ||
160 | common->ani.checkani_timer = timestamp; | ||
161 | |||
162 | mod_timer(&common->ani.timer, | ||
163 | jiffies + | ||
164 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
165 | } | ||
166 | |||
167 | static void ath_update_survey_nf(struct ath_softc *sc, int channel) | ||
168 | { | ||
169 | struct ath_hw *ah = sc->sc_ah; | ||
170 | struct ath9k_channel *chan = &ah->channels[channel]; | ||
171 | struct survey_info *survey = &sc->survey[channel]; | ||
172 | |||
173 | if (chan->noisefloor) { | ||
174 | survey->filled |= SURVEY_INFO_NOISE_DBM; | ||
175 | survey->noise = ath9k_hw_getchan_noise(ah, chan); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Updates the survey statistics and returns the busy time since last | ||
181 | * update in %, if the measurement duration was long enough for the | ||
182 | * result to be useful, -1 otherwise. | ||
183 | */ | ||
184 | static int ath_update_survey_stats(struct ath_softc *sc) | ||
185 | { | ||
186 | struct ath_hw *ah = sc->sc_ah; | ||
187 | struct ath_common *common = ath9k_hw_common(ah); | ||
188 | int pos = ah->curchan - &ah->channels[0]; | ||
189 | struct survey_info *survey = &sc->survey[pos]; | ||
190 | struct ath_cycle_counters *cc = &common->cc_survey; | ||
191 | unsigned int div = common->clockrate * 1000; | ||
192 | int ret = 0; | ||
193 | |||
194 | if (!ah->curchan) | ||
195 | return -1; | ||
196 | |||
197 | if (ah->power_mode == ATH9K_PM_AWAKE) | ||
198 | ath_hw_cycle_counters_update(common); | ||
199 | |||
200 | if (cc->cycles > 0) { | ||
201 | survey->filled |= SURVEY_INFO_CHANNEL_TIME | | ||
202 | SURVEY_INFO_CHANNEL_TIME_BUSY | | ||
203 | SURVEY_INFO_CHANNEL_TIME_RX | | ||
204 | SURVEY_INFO_CHANNEL_TIME_TX; | ||
205 | survey->channel_time += cc->cycles / div; | ||
206 | survey->channel_time_busy += cc->rx_busy / div; | ||
207 | survey->channel_time_rx += cc->rx_frame / div; | ||
208 | survey->channel_time_tx += cc->tx_frame / div; | ||
209 | } | ||
210 | |||
211 | if (cc->cycles < div) | ||
212 | return -1; | ||
213 | |||
214 | if (cc->cycles > 0) | ||
215 | ret = cc->rx_busy * 100 / cc->cycles; | ||
216 | |||
217 | memset(cc, 0, sizeof(*cc)); | ||
218 | |||
219 | ath_update_survey_nf(sc, pos); | ||
220 | |||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | static void __ath_cancel_work(struct ath_softc *sc) | 147 | static void __ath_cancel_work(struct ath_softc *sc) |
225 | { | 148 | { |
226 | cancel_work_sync(&sc->paprd_work); | 149 | cancel_work_sync(&sc->paprd_work); |
@@ -235,6 +158,22 @@ static void ath_cancel_work(struct ath_softc *sc) | |||
235 | cancel_work_sync(&sc->hw_reset_work); | 158 | cancel_work_sync(&sc->hw_reset_work); |
236 | } | 159 | } |
237 | 160 | ||
161 | static void ath_restart_work(struct ath_softc *sc) | ||
162 | { | ||
163 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
164 | |||
165 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
166 | |||
167 | if (AR_SREV_9485(sc->sc_ah) || AR_SREV_9340(sc->sc_ah)) | ||
168 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, | ||
169 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | ||
170 | |||
171 | ath_start_rx_poll(sc, 3); | ||
172 | |||
173 | if (!common->disable_ani) | ||
174 | ath_start_ani(common); | ||
175 | } | ||
176 | |||
238 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 177 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) |
239 | { | 178 | { |
240 | struct ath_hw *ah = sc->sc_ah; | 179 | struct ath_hw *ah = sc->sc_ah; |
@@ -271,6 +210,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
271 | { | 210 | { |
272 | struct ath_hw *ah = sc->sc_ah; | 211 | struct ath_hw *ah = sc->sc_ah; |
273 | struct ath_common *common = ath9k_hw_common(ah); | 212 | struct ath_common *common = ath9k_hw_common(ah); |
213 | unsigned long flags; | ||
274 | 214 | ||
275 | if (ath_startrecv(sc) != 0) { | 215 | if (ath_startrecv(sc) != 0) { |
276 | ath_err(common, "Unable to restart recv logic\n"); | 216 | ath_err(common, "Unable to restart recv logic\n"); |
@@ -279,36 +219,30 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
279 | 219 | ||
280 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 220 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
281 | sc->config.txpowlimit, &sc->curtxpow); | 221 | sc->config.txpowlimit, &sc->curtxpow); |
222 | |||
223 | clear_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
282 | ath9k_hw_set_interrupts(ah); | 224 | ath9k_hw_set_interrupts(ah); |
283 | ath9k_hw_enable_interrupts(ah); | 225 | ath9k_hw_enable_interrupts(ah); |
284 | 226 | ||
285 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { | 227 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) { |
286 | if (sc->sc_flags & SC_OP_BEACONS) | 228 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) |
287 | ath_set_beacon(sc); | 229 | goto work; |
288 | 230 | ||
289 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 231 | ath_set_beacon(sc); |
290 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); | ||
291 | ath_start_rx_poll(sc, 3); | ||
292 | if (!common->disable_ani) | ||
293 | ath_start_ani(common); | ||
294 | } | ||
295 | |||
296 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { | ||
297 | struct ath_hw_antcomb_conf div_ant_conf; | ||
298 | u8 lna_conf; | ||
299 | |||
300 | ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); | ||
301 | |||
302 | if (sc->ant_rx == 1) | ||
303 | lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
304 | else | ||
305 | lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
306 | div_ant_conf.main_lna_conf = lna_conf; | ||
307 | div_ant_conf.alt_lna_conf = lna_conf; | ||
308 | 232 | ||
309 | ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); | 233 | if (ah->opmode == NL80211_IFTYPE_STATION && |
234 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | ||
235 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
236 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
237 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
238 | } | ||
239 | work: | ||
240 | ath_restart_work(sc); | ||
310 | } | 241 | } |
311 | 242 | ||
243 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) | ||
244 | ath_ant_comb_update(sc); | ||
245 | |||
312 | ieee80211_wake_queues(sc->hw); | 246 | ieee80211_wake_queues(sc->hw); |
313 | 247 | ||
314 | return true; | 248 | return true; |
@@ -328,7 +262,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, | |||
328 | 262 | ||
329 | spin_lock_bh(&sc->sc_pcu_lock); | 263 | spin_lock_bh(&sc->sc_pcu_lock); |
330 | 264 | ||
331 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { | 265 | if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { |
332 | fastcc = false; | 266 | fastcc = false; |
333 | caldata = &sc->caldata; | 267 | caldata = &sc->caldata; |
334 | } | 268 | } |
@@ -371,7 +305,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
371 | { | 305 | { |
372 | int r; | 306 | int r; |
373 | 307 | ||
374 | if (sc->sc_flags & SC_OP_INVALID) | 308 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
375 | return -EIO; | 309 | return -EIO; |
376 | 310 | ||
377 | r = ath_reset_internal(sc, hchan, false); | 311 | r = ath_reset_internal(sc, hchan, false); |
@@ -379,258 +313,6 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
379 | return r; | 313 | return r; |
380 | } | 314 | } |
381 | 315 | ||
382 | static void ath_paprd_activate(struct ath_softc *sc) | ||
383 | { | ||
384 | struct ath_hw *ah = sc->sc_ah; | ||
385 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
386 | int chain; | ||
387 | |||
388 | if (!caldata || !caldata->paprd_done) | ||
389 | return; | ||
390 | |||
391 | ath9k_ps_wakeup(sc); | ||
392 | ar9003_paprd_enable(ah, false); | ||
393 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
394 | if (!(ah->txchainmask & BIT(chain))) | ||
395 | continue; | ||
396 | |||
397 | ar9003_paprd_populate_single_table(ah, caldata, chain); | ||
398 | } | ||
399 | |||
400 | ar9003_paprd_enable(ah, true); | ||
401 | ath9k_ps_restore(sc); | ||
402 | } | ||
403 | |||
404 | static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) | ||
405 | { | ||
406 | struct ieee80211_hw *hw = sc->hw; | ||
407 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
408 | struct ath_hw *ah = sc->sc_ah; | ||
409 | struct ath_common *common = ath9k_hw_common(ah); | ||
410 | struct ath_tx_control txctl; | ||
411 | int time_left; | ||
412 | |||
413 | memset(&txctl, 0, sizeof(txctl)); | ||
414 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | ||
415 | |||
416 | memset(tx_info, 0, sizeof(*tx_info)); | ||
417 | tx_info->band = hw->conf.channel->band; | ||
418 | tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
419 | tx_info->control.rates[0].idx = 0; | ||
420 | tx_info->control.rates[0].count = 1; | ||
421 | tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; | ||
422 | tx_info->control.rates[1].idx = -1; | ||
423 | |||
424 | init_completion(&sc->paprd_complete); | ||
425 | txctl.paprd = BIT(chain); | ||
426 | |||
427 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
428 | ath_dbg(common, CALIBRATE, "PAPRD TX failed\n"); | ||
429 | dev_kfree_skb_any(skb); | ||
430 | return false; | ||
431 | } | ||
432 | |||
433 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | ||
434 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | ||
435 | |||
436 | if (!time_left) | ||
437 | ath_dbg(common, CALIBRATE, | ||
438 | "Timeout waiting for paprd training on TX chain %d\n", | ||
439 | chain); | ||
440 | |||
441 | return !!time_left; | ||
442 | } | ||
443 | |||
444 | void ath_paprd_calibrate(struct work_struct *work) | ||
445 | { | ||
446 | struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); | ||
447 | struct ieee80211_hw *hw = sc->hw; | ||
448 | struct ath_hw *ah = sc->sc_ah; | ||
449 | struct ieee80211_hdr *hdr; | ||
450 | struct sk_buff *skb = NULL; | ||
451 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
452 | struct ath_common *common = ath9k_hw_common(ah); | ||
453 | int ftype; | ||
454 | int chain_ok = 0; | ||
455 | int chain; | ||
456 | int len = 1800; | ||
457 | |||
458 | if (!caldata) | ||
459 | return; | ||
460 | |||
461 | ath9k_ps_wakeup(sc); | ||
462 | |||
463 | if (ar9003_paprd_init_table(ah) < 0) | ||
464 | goto fail_paprd; | ||
465 | |||
466 | skb = alloc_skb(len, GFP_KERNEL); | ||
467 | if (!skb) | ||
468 | goto fail_paprd; | ||
469 | |||
470 | skb_put(skb, len); | ||
471 | memset(skb->data, 0, len); | ||
472 | hdr = (struct ieee80211_hdr *)skb->data; | ||
473 | ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; | ||
474 | hdr->frame_control = cpu_to_le16(ftype); | ||
475 | hdr->duration_id = cpu_to_le16(10); | ||
476 | memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); | ||
477 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | ||
478 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | ||
479 | |||
480 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||
481 | if (!(ah->txchainmask & BIT(chain))) | ||
482 | continue; | ||
483 | |||
484 | chain_ok = 0; | ||
485 | |||
486 | ath_dbg(common, CALIBRATE, | ||
487 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
488 | chain); | ||
489 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
490 | goto fail_paprd; | ||
491 | |||
492 | ar9003_paprd_setup_gain_table(ah, chain); | ||
493 | |||
494 | ath_dbg(common, CALIBRATE, | ||
495 | "Sending PAPRD training frame on chain %d\n", chain); | ||
496 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
497 | goto fail_paprd; | ||
498 | |||
499 | if (!ar9003_paprd_is_done(ah)) { | ||
500 | ath_dbg(common, CALIBRATE, | ||
501 | "PAPRD not yet done on chain %d\n", chain); | ||
502 | break; | ||
503 | } | ||
504 | |||
505 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | ||
506 | ath_dbg(common, CALIBRATE, | ||
507 | "PAPRD create curve failed on chain %d\n", | ||
508 | chain); | ||
509 | break; | ||
510 | } | ||
511 | |||
512 | chain_ok = 1; | ||
513 | } | ||
514 | kfree_skb(skb); | ||
515 | |||
516 | if (chain_ok) { | ||
517 | caldata->paprd_done = true; | ||
518 | ath_paprd_activate(sc); | ||
519 | } | ||
520 | |||
521 | fail_paprd: | ||
522 | ath9k_ps_restore(sc); | ||
523 | } | ||
524 | |||
525 | /* | ||
526 | * This routine performs the periodic noise floor calibration function | ||
527 | * that is used to adjust and optimize the chip performance. This | ||
528 | * takes environmental changes (location, temperature) into account. | ||
529 | * When the task is complete, it reschedules itself depending on the | ||
530 | * appropriate interval that was calculated. | ||
531 | */ | ||
532 | void ath_ani_calibrate(unsigned long data) | ||
533 | { | ||
534 | struct ath_softc *sc = (struct ath_softc *)data; | ||
535 | struct ath_hw *ah = sc->sc_ah; | ||
536 | struct ath_common *common = ath9k_hw_common(ah); | ||
537 | bool longcal = false; | ||
538 | bool shortcal = false; | ||
539 | bool aniflag = false; | ||
540 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
541 | u32 cal_interval, short_cal_interval, long_cal_interval; | ||
542 | unsigned long flags; | ||
543 | |||
544 | if (ah->caldata && ah->caldata->nfcal_interference) | ||
545 | long_cal_interval = ATH_LONG_CALINTERVAL_INT; | ||
546 | else | ||
547 | long_cal_interval = ATH_LONG_CALINTERVAL; | ||
548 | |||
549 | short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? | ||
550 | ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; | ||
551 | |||
552 | /* Only calibrate if awake */ | ||
553 | if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) | ||
554 | goto set_timer; | ||
555 | |||
556 | ath9k_ps_wakeup(sc); | ||
557 | |||
558 | /* Long calibration runs independently of short calibration. */ | ||
559 | if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { | ||
560 | longcal = true; | ||
561 | common->ani.longcal_timer = timestamp; | ||
562 | } | ||
563 | |||
564 | /* Short calibration applies only while caldone is false */ | ||
565 | if (!common->ani.caldone) { | ||
566 | if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) { | ||
567 | shortcal = true; | ||
568 | common->ani.shortcal_timer = timestamp; | ||
569 | common->ani.resetcal_timer = timestamp; | ||
570 | } | ||
571 | } else { | ||
572 | if ((timestamp - common->ani.resetcal_timer) >= | ||
573 | ATH_RESTART_CALINTERVAL) { | ||
574 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
575 | if (common->ani.caldone) | ||
576 | common->ani.resetcal_timer = timestamp; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /* Verify whether we must check ANI */ | ||
581 | if (sc->sc_ah->config.enable_ani | ||
582 | && (timestamp - common->ani.checkani_timer) >= | ||
583 | ah->config.ani_poll_interval) { | ||
584 | aniflag = true; | ||
585 | common->ani.checkani_timer = timestamp; | ||
586 | } | ||
587 | |||
588 | /* Call ANI routine if necessary */ | ||
589 | if (aniflag) { | ||
590 | spin_lock_irqsave(&common->cc_lock, flags); | ||
591 | ath9k_hw_ani_monitor(ah, ah->curchan); | ||
592 | ath_update_survey_stats(sc); | ||
593 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
594 | } | ||
595 | |||
596 | /* Perform calibration if necessary */ | ||
597 | if (longcal || shortcal) { | ||
598 | common->ani.caldone = | ||
599 | ath9k_hw_calibrate(ah, ah->curchan, | ||
600 | ah->rxchainmask, longcal); | ||
601 | } | ||
602 | |||
603 | ath_dbg(common, ANI, | ||
604 | "Calibration @%lu finished: %s %s %s, caldone: %s\n", | ||
605 | jiffies, | ||
606 | longcal ? "long" : "", shortcal ? "short" : "", | ||
607 | aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); | ||
608 | |||
609 | ath9k_ps_restore(sc); | ||
610 | |||
611 | set_timer: | ||
612 | /* | ||
613 | * Set timer interval based on previous results. | ||
614 | * The interval must be the shortest necessary to satisfy ANI, | ||
615 | * short calibration and long calibration. | ||
616 | */ | ||
617 | ath9k_debug_samp_bb_mac(sc); | ||
618 | cal_interval = ATH_LONG_CALINTERVAL; | ||
619 | if (sc->sc_ah->config.enable_ani) | ||
620 | cal_interval = min(cal_interval, | ||
621 | (u32)ah->config.ani_poll_interval); | ||
622 | if (!common->ani.caldone) | ||
623 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
624 | |||
625 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | ||
626 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | ||
627 | if (!ah->caldata->paprd_done) | ||
628 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | ||
629 | else if (!ah->paprd_table_write_done) | ||
630 | ath_paprd_activate(sc); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | 316 | static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, |
635 | struct ieee80211_vif *vif) | 317 | struct ieee80211_vif *vif) |
636 | { | 318 | { |
@@ -668,13 +350,12 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
668 | ath_tx_node_cleanup(sc, an); | 350 | ath_tx_node_cleanup(sc, an); |
669 | } | 351 | } |
670 | 352 | ||
671 | |||
672 | void ath9k_tasklet(unsigned long data) | 353 | void ath9k_tasklet(unsigned long data) |
673 | { | 354 | { |
674 | struct ath_softc *sc = (struct ath_softc *)data; | 355 | struct ath_softc *sc = (struct ath_softc *)data; |
675 | struct ath_hw *ah = sc->sc_ah; | 356 | struct ath_hw *ah = sc->sc_ah; |
676 | struct ath_common *common = ath9k_hw_common(ah); | 357 | struct ath_common *common = ath9k_hw_common(ah); |
677 | 358 | unsigned long flags; | |
678 | u32 status = sc->intrstatus; | 359 | u32 status = sc->intrstatus; |
679 | u32 rxmask; | 360 | u32 rxmask; |
680 | 361 | ||
@@ -693,10 +374,12 @@ void ath9k_tasklet(unsigned long data) | |||
693 | 374 | ||
694 | RESET_STAT_INC(sc, type); | 375 | RESET_STAT_INC(sc, type); |
695 | #endif | 376 | #endif |
377 | set_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
696 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 378 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); |
697 | goto out; | 379 | goto out; |
698 | } | 380 | } |
699 | 381 | ||
382 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
700 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 383 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
701 | /* | 384 | /* |
702 | * TSF sync does not look correct; remain awake to sync with | 385 | * TSF sync does not look correct; remain awake to sync with |
@@ -705,6 +388,7 @@ void ath9k_tasklet(unsigned long data) | |||
705 | ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); | 388 | ath_dbg(common, PS, "TSFOOR - Sync with next Beacon\n"); |
706 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; | 389 | sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC; |
707 | } | 390 | } |
391 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
708 | 392 | ||
709 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 393 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
710 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | | 394 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | |
@@ -766,15 +450,17 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
766 | * touch anything. Note this can happen early | 450 | * touch anything. Note this can happen early |
767 | * on if the IRQ is shared. | 451 | * on if the IRQ is shared. |
768 | */ | 452 | */ |
769 | if (sc->sc_flags & SC_OP_INVALID) | 453 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
770 | return IRQ_NONE; | 454 | return IRQ_NONE; |
771 | 455 | ||
772 | |||
773 | /* shared irq, not for us */ | 456 | /* shared irq, not for us */ |
774 | 457 | ||
775 | if (!ath9k_hw_intrpend(ah)) | 458 | if (!ath9k_hw_intrpend(ah)) |
776 | return IRQ_NONE; | 459 | return IRQ_NONE; |
777 | 460 | ||
461 | if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | ||
462 | return IRQ_HANDLED; | ||
463 | |||
778 | /* | 464 | /* |
779 | * Figure out the reason(s) for the interrupt. Note | 465 | * Figure out the reason(s) for the interrupt. Note |
780 | * that the hal returns a pseudo-ISR that may include | 466 | * that the hal returns a pseudo-ISR that may include |
@@ -852,8 +538,10 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
852 | /* Clear RxAbort bit so that we can | 538 | /* Clear RxAbort bit so that we can |
853 | * receive frames */ | 539 | * receive frames */ |
854 | ath9k_setpower(sc, ATH9K_PM_AWAKE); | 540 | ath9k_setpower(sc, ATH9K_PM_AWAKE); |
541 | spin_lock(&sc->sc_pm_lock); | ||
855 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 542 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
856 | sc->ps_flags |= PS_WAIT_FOR_BEACON; | 543 | sc->ps_flags |= PS_WAIT_FOR_BEACON; |
544 | spin_unlock(&sc->sc_pm_lock); | ||
857 | } | 545 | } |
858 | 546 | ||
859 | chip_reset: | 547 | chip_reset: |
@@ -902,87 +590,6 @@ void ath_reset_work(struct work_struct *work) | |||
902 | ath_reset(sc, true); | 590 | ath_reset(sc, true); |
903 | } | 591 | } |
904 | 592 | ||
905 | void ath_hw_check(struct work_struct *work) | ||
906 | { | ||
907 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); | ||
908 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
909 | unsigned long flags; | ||
910 | int busy; | ||
911 | u8 is_alive, nbeacon = 1; | ||
912 | |||
913 | ath9k_ps_wakeup(sc); | ||
914 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | ||
915 | |||
916 | if (is_alive && !AR_SREV_9300(sc->sc_ah)) | ||
917 | goto out; | ||
918 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | ||
919 | ath_dbg(common, RESET, | ||
920 | "DCU stuck is detected. Schedule chip reset\n"); | ||
921 | RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); | ||
922 | goto sched_reset; | ||
923 | } | ||
924 | |||
925 | spin_lock_irqsave(&common->cc_lock, flags); | ||
926 | busy = ath_update_survey_stats(sc); | ||
927 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
928 | |||
929 | ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n", | ||
930 | busy, sc->hw_busy_count + 1); | ||
931 | if (busy >= 99) { | ||
932 | if (++sc->hw_busy_count >= 3) { | ||
933 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | ||
934 | goto sched_reset; | ||
935 | } | ||
936 | } else if (busy >= 0) { | ||
937 | sc->hw_busy_count = 0; | ||
938 | nbeacon = 3; | ||
939 | } | ||
940 | |||
941 | ath_start_rx_poll(sc, nbeacon); | ||
942 | goto out; | ||
943 | |||
944 | sched_reset: | ||
945 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
946 | out: | ||
947 | ath9k_ps_restore(sc); | ||
948 | } | ||
949 | |||
950 | static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||
951 | { | ||
952 | static int count; | ||
953 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
954 | |||
955 | if (pll_sqsum >= 0x40000) { | ||
956 | count++; | ||
957 | if (count == 3) { | ||
958 | /* Rx is hung for more than 500ms. Reset it */ | ||
959 | ath_dbg(common, RESET, "Possible RX hang, resetting\n"); | ||
960 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | ||
961 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
962 | count = 0; | ||
963 | } | ||
964 | } else | ||
965 | count = 0; | ||
966 | } | ||
967 | |||
968 | void ath_hw_pll_work(struct work_struct *work) | ||
969 | { | ||
970 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
971 | hw_pll_work.work); | ||
972 | u32 pll_sqsum; | ||
973 | |||
974 | if (AR_SREV_9485(sc->sc_ah)) { | ||
975 | |||
976 | ath9k_ps_wakeup(sc); | ||
977 | pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||
978 | ath9k_ps_restore(sc); | ||
979 | |||
980 | ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||
981 | |||
982 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
983 | } | ||
984 | } | ||
985 | |||
986 | /**********************/ | 593 | /**********************/ |
987 | /* mac80211 callbacks */ | 594 | /* mac80211 callbacks */ |
988 | /**********************/ | 595 | /**********************/ |
@@ -1045,10 +652,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1045 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 652 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
1046 | ah->imask |= ATH9K_INT_CST; | 653 | ah->imask |= ATH9K_INT_CST; |
1047 | 654 | ||
1048 | if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | 655 | ath_mci_enable(sc); |
1049 | ah->imask |= ATH9K_INT_MCI; | ||
1050 | 656 | ||
1051 | sc->sc_flags &= ~SC_OP_INVALID; | 657 | clear_bit(SC_OP_INVALID, &sc->sc_flags); |
1052 | sc->sc_ah->is_monitoring = false; | 658 | sc->sc_ah->is_monitoring = false; |
1053 | 659 | ||
1054 | if (!ath_complete_reset(sc, false)) { | 660 | if (!ath_complete_reset(sc, false)) { |
@@ -1090,6 +696,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1090 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 696 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1091 | struct ath_tx_control txctl; | 697 | struct ath_tx_control txctl; |
1092 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 698 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
699 | unsigned long flags; | ||
1093 | 700 | ||
1094 | if (sc->ps_enabled) { | 701 | if (sc->ps_enabled) { |
1095 | /* | 702 | /* |
@@ -1112,6 +719,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1112 | * completed and if needed, also for RX of buffered frames. | 719 | * completed and if needed, also for RX of buffered frames. |
1113 | */ | 720 | */ |
1114 | ath9k_ps_wakeup(sc); | 721 | ath9k_ps_wakeup(sc); |
722 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1115 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 723 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
1116 | ath9k_hw_setrxabort(sc->sc_ah, 0); | 724 | ath9k_hw_setrxabort(sc->sc_ah, 0); |
1117 | if (ieee80211_is_pspoll(hdr->frame_control)) { | 725 | if (ieee80211_is_pspoll(hdr->frame_control)) { |
@@ -1127,6 +735,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1127 | * the ps_flags bit is cleared. We are just dropping | 735 | * the ps_flags bit is cleared. We are just dropping |
1128 | * the ps_usecount here. | 736 | * the ps_usecount here. |
1129 | */ | 737 | */ |
738 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1130 | ath9k_ps_restore(sc); | 739 | ath9k_ps_restore(sc); |
1131 | } | 740 | } |
1132 | 741 | ||
@@ -1167,7 +776,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1167 | ath_cancel_work(sc); | 776 | ath_cancel_work(sc); |
1168 | del_timer_sync(&sc->rx_poll_timer); | 777 | del_timer_sync(&sc->rx_poll_timer); |
1169 | 778 | ||
1170 | if (sc->sc_flags & SC_OP_INVALID) { | 779 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
1171 | ath_dbg(common, ANY, "Device not present\n"); | 780 | ath_dbg(common, ANY, "Device not present\n"); |
1172 | mutex_unlock(&sc->mutex); | 781 | mutex_unlock(&sc->mutex); |
1173 | return; | 782 | return; |
@@ -1224,7 +833,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1224 | 833 | ||
1225 | ath9k_ps_restore(sc); | 834 | ath9k_ps_restore(sc); |
1226 | 835 | ||
1227 | sc->sc_flags |= SC_OP_INVALID; | 836 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
1228 | sc->ps_idle = prev_idle; | 837 | sc->ps_idle = prev_idle; |
1229 | 838 | ||
1230 | mutex_unlock(&sc->mutex); | 839 | mutex_unlock(&sc->mutex); |
@@ -1328,11 +937,11 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1328 | /* Set op-mode & TSF */ | 937 | /* Set op-mode & TSF */ |
1329 | if (iter_data.naps > 0) { | 938 | if (iter_data.naps > 0) { |
1330 | ath9k_hw_set_tsfadjust(ah, 1); | 939 | ath9k_hw_set_tsfadjust(ah, 1); |
1331 | sc->sc_flags |= SC_OP_TSF_RESET; | 940 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
1332 | ah->opmode = NL80211_IFTYPE_AP; | 941 | ah->opmode = NL80211_IFTYPE_AP; |
1333 | } else { | 942 | } else { |
1334 | ath9k_hw_set_tsfadjust(ah, 0); | 943 | ath9k_hw_set_tsfadjust(ah, 0); |
1335 | sc->sc_flags &= ~SC_OP_TSF_RESET; | 944 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
1336 | 945 | ||
1337 | if (iter_data.nmeshes) | 946 | if (iter_data.nmeshes) |
1338 | ah->opmode = NL80211_IFTYPE_MESH_POINT; | 947 | ah->opmode = NL80211_IFTYPE_MESH_POINT; |
@@ -1363,12 +972,12 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1363 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 972 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
1364 | 973 | ||
1365 | if (!common->disable_ani) { | 974 | if (!common->disable_ani) { |
1366 | sc->sc_flags |= SC_OP_ANI_RUN; | 975 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1367 | ath_start_ani(common); | 976 | ath_start_ani(common); |
1368 | } | 977 | } |
1369 | 978 | ||
1370 | } else { | 979 | } else { |
1371 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 980 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1372 | del_timer_sync(&common->ani.timer); | 981 | del_timer_sync(&common->ani.timer); |
1373 | } | 982 | } |
1374 | } | 983 | } |
@@ -1389,25 +998,6 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | |||
1389 | } | 998 | } |
1390 | } | 999 | } |
1391 | 1000 | ||
1392 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon) | ||
1393 | { | ||
1394 | if (!AR_SREV_9300(sc->sc_ah)) | ||
1395 | return; | ||
1396 | |||
1397 | if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) | ||
1398 | return; | ||
1399 | |||
1400 | mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies | ||
1401 | (nbeacon * sc->cur_beacon_conf.beacon_interval)); | ||
1402 | } | ||
1403 | |||
1404 | void ath_rx_poll(unsigned long data) | ||
1405 | { | ||
1406 | struct ath_softc *sc = (struct ath_softc *)data; | ||
1407 | |||
1408 | ieee80211_queue_work(sc->hw, &sc->hw_check_work); | ||
1409 | } | ||
1410 | |||
1411 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1001 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
1412 | struct ieee80211_vif *vif) | 1002 | struct ieee80211_vif *vif) |
1413 | { | 1003 | { |
@@ -1627,11 +1217,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1627 | if (ah->curchan) | 1217 | if (ah->curchan) |
1628 | old_pos = ah->curchan - &ah->channels[0]; | 1218 | old_pos = ah->curchan - &ah->channels[0]; |
1629 | 1219 | ||
1630 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
1631 | sc->sc_flags |= SC_OP_OFFCHANNEL; | ||
1632 | else | ||
1633 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | ||
1634 | |||
1635 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", | 1220 | ath_dbg(common, CONFIG, "Set channel: %d MHz type: %d\n", |
1636 | curchan->center_freq, conf->channel_type); | 1221 | curchan->center_freq, conf->channel_type); |
1637 | 1222 | ||
@@ -1911,16 +1496,16 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1911 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1496 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1912 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1497 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
1913 | struct ath_vif *avp = (void *)vif->drv_priv; | 1498 | struct ath_vif *avp = (void *)vif->drv_priv; |
1914 | 1499 | unsigned long flags; | |
1915 | /* | 1500 | /* |
1916 | * Skip iteration if primary station vif's bss info | 1501 | * Skip iteration if primary station vif's bss info |
1917 | * was not changed | 1502 | * was not changed |
1918 | */ | 1503 | */ |
1919 | if (sc->sc_flags & SC_OP_PRIM_STA_VIF) | 1504 | if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) |
1920 | return; | 1505 | return; |
1921 | 1506 | ||
1922 | if (bss_conf->assoc) { | 1507 | if (bss_conf->assoc) { |
1923 | sc->sc_flags |= SC_OP_PRIM_STA_VIF; | 1508 | set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); |
1924 | avp->primary_sta_vif = true; | 1509 | avp->primary_sta_vif = true; |
1925 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1510 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1926 | common->curaid = bss_conf->aid; | 1511 | common->curaid = bss_conf->aid; |
@@ -1933,7 +1518,10 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1933 | * on the receipt of the first Beacon frame (i.e., | 1518 | * on the receipt of the first Beacon frame (i.e., |
1934 | * after time sync with the AP). | 1519 | * after time sync with the AP). |
1935 | */ | 1520 | */ |
1521 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1936 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 1522 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
1523 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1524 | |||
1937 | /* Reset rssi stats */ | 1525 | /* Reset rssi stats */ |
1938 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1526 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1939 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1527 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
@@ -1941,7 +1529,7 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1941 | ath_start_rx_poll(sc, 3); | 1529 | ath_start_rx_poll(sc, 3); |
1942 | 1530 | ||
1943 | if (!common->disable_ani) { | 1531 | if (!common->disable_ani) { |
1944 | sc->sc_flags |= SC_OP_ANI_RUN; | 1532 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1945 | ath_start_ani(common); | 1533 | ath_start_ani(common); |
1946 | } | 1534 | } |
1947 | 1535 | ||
@@ -1961,7 +1549,8 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1961 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 1549 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
1962 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", | 1550 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", |
1963 | common->curaid, common->curbssid); | 1551 | common->curaid, common->curbssid); |
1964 | sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS); | 1552 | clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); |
1553 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
1965 | avp->primary_sta_vif = false; | 1554 | avp->primary_sta_vif = false; |
1966 | memset(common->curbssid, 0, ETH_ALEN); | 1555 | memset(common->curbssid, 0, ETH_ALEN); |
1967 | common->curaid = 0; | 1556 | common->curaid = 0; |
@@ -1974,10 +1563,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1974 | * None of station vifs are associated. | 1563 | * None of station vifs are associated. |
1975 | * Clear bssid & aid | 1564 | * Clear bssid & aid |
1976 | */ | 1565 | */ |
1977 | if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { | 1566 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
1978 | ath9k_hw_write_associd(sc->sc_ah); | 1567 | ath9k_hw_write_associd(sc->sc_ah); |
1979 | /* Stop ANI */ | 1568 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
1980 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
1981 | del_timer_sync(&common->ani.timer); | 1569 | del_timer_sync(&common->ani.timer); |
1982 | del_timer_sync(&sc->rx_poll_timer); | 1570 | del_timer_sync(&sc->rx_poll_timer); |
1983 | memset(&sc->caldata, 0, sizeof(sc->caldata)); | 1571 | memset(&sc->caldata, 0, sizeof(sc->caldata)); |
@@ -2015,12 +1603,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2015 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1603 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
2016 | 1604 | ||
2017 | if (!common->disable_ani) { | 1605 | if (!common->disable_ani) { |
2018 | sc->sc_flags |= SC_OP_ANI_RUN; | 1606 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
2019 | ath_start_ani(common); | 1607 | ath_start_ani(common); |
2020 | } | 1608 | } |
2021 | 1609 | ||
2022 | } else { | 1610 | } else { |
2023 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 1611 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
2024 | del_timer_sync(&common->ani.timer); | 1612 | del_timer_sync(&common->ani.timer); |
2025 | del_timer_sync(&sc->rx_poll_timer); | 1613 | del_timer_sync(&sc->rx_poll_timer); |
2026 | } | 1614 | } |
@@ -2032,7 +1620,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2032 | */ | 1620 | */ |
2033 | if ((changed & BSS_CHANGED_BEACON_INT) && | 1621 | if ((changed & BSS_CHANGED_BEACON_INT) && |
2034 | (vif->type == NL80211_IFTYPE_AP)) | 1622 | (vif->type == NL80211_IFTYPE_AP)) |
2035 | sc->sc_flags |= SC_OP_TSF_RESET; | 1623 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); |
2036 | 1624 | ||
2037 | /* Configure beaconing (AP, IBSS, MESH) */ | 1625 | /* Configure beaconing (AP, IBSS, MESH) */ |
2038 | if (ath9k_uses_beacons(vif->type) && | 1626 | if (ath9k_uses_beacons(vif->type) && |
@@ -2224,7 +1812,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
2224 | return; | 1812 | return; |
2225 | } | 1813 | } |
2226 | 1814 | ||
2227 | if (sc->sc_flags & SC_OP_INVALID) { | 1815 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { |
2228 | ath_dbg(common, ANY, "Device not present\n"); | 1816 | ath_dbg(common, ANY, "Device not present\n"); |
2229 | mutex_unlock(&sc->mutex); | 1817 | mutex_unlock(&sc->mutex); |
2230 | return; | 1818 | return; |
@@ -2389,6 +1977,134 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) | |||
2389 | return 0; | 1977 | return 0; |
2390 | } | 1978 | } |
2391 | 1979 | ||
1980 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
1981 | |||
1982 | /* Ethtool support for get-stats */ | ||
1983 | |||
1984 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" | ||
1985 | static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { | ||
1986 | "tx_pkts_nic", | ||
1987 | "tx_bytes_nic", | ||
1988 | "rx_pkts_nic", | ||
1989 | "rx_bytes_nic", | ||
1990 | AMKSTR(d_tx_pkts), | ||
1991 | AMKSTR(d_tx_bytes), | ||
1992 | AMKSTR(d_tx_mpdus_queued), | ||
1993 | AMKSTR(d_tx_mpdus_completed), | ||
1994 | AMKSTR(d_tx_mpdu_xretries), | ||
1995 | AMKSTR(d_tx_aggregates), | ||
1996 | AMKSTR(d_tx_ampdus_queued_hw), | ||
1997 | AMKSTR(d_tx_ampdus_queued_sw), | ||
1998 | AMKSTR(d_tx_ampdus_completed), | ||
1999 | AMKSTR(d_tx_ampdu_retries), | ||
2000 | AMKSTR(d_tx_ampdu_xretries), | ||
2001 | AMKSTR(d_tx_fifo_underrun), | ||
2002 | AMKSTR(d_tx_op_exceeded), | ||
2003 | AMKSTR(d_tx_timer_expiry), | ||
2004 | AMKSTR(d_tx_desc_cfg_err), | ||
2005 | AMKSTR(d_tx_data_underrun), | ||
2006 | AMKSTR(d_tx_delim_underrun), | ||
2007 | |||
2008 | "d_rx_decrypt_crc_err", | ||
2009 | "d_rx_phy_err", | ||
2010 | "d_rx_mic_err", | ||
2011 | "d_rx_pre_delim_crc_err", | ||
2012 | "d_rx_post_delim_crc_err", | ||
2013 | "d_rx_decrypt_busy_err", | ||
2014 | |||
2015 | "d_rx_phyerr_radar", | ||
2016 | "d_rx_phyerr_ofdm_timing", | ||
2017 | "d_rx_phyerr_cck_timing", | ||
2018 | |||
2019 | }; | ||
2020 | #define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) | ||
2021 | |||
2022 | static void ath9k_get_et_strings(struct ieee80211_hw *hw, | ||
2023 | struct ieee80211_vif *vif, | ||
2024 | u32 sset, u8 *data) | ||
2025 | { | ||
2026 | if (sset == ETH_SS_STATS) | ||
2027 | memcpy(data, *ath9k_gstrings_stats, | ||
2028 | sizeof(ath9k_gstrings_stats)); | ||
2029 | } | ||
2030 | |||
2031 | static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, | ||
2032 | struct ieee80211_vif *vif, int sset) | ||
2033 | { | ||
2034 | if (sset == ETH_SS_STATS) | ||
2035 | return ATH9K_SSTATS_LEN; | ||
2036 | return 0; | ||
2037 | } | ||
2038 | |||
2039 | #define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) | ||
2040 | #define AWDATA(elem) \ | ||
2041 | do { \ | ||
2042 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ | ||
2043 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ | ||
2044 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ | ||
2045 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ | ||
2046 | } while (0) | ||
2047 | |||
2048 | #define AWDATA_RX(elem) \ | ||
2049 | do { \ | ||
2050 | data[i++] = sc->debug.stats.rxstats.elem; \ | ||
2051 | } while (0) | ||
2052 | |||
2053 | static void ath9k_get_et_stats(struct ieee80211_hw *hw, | ||
2054 | struct ieee80211_vif *vif, | ||
2055 | struct ethtool_stats *stats, u64 *data) | ||
2056 | { | ||
2057 | struct ath_softc *sc = hw->priv; | ||
2058 | int i = 0; | ||
2059 | |||
2060 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + | ||
2061 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + | ||
2062 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + | ||
2063 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); | ||
2064 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + | ||
2065 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + | ||
2066 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + | ||
2067 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); | ||
2068 | AWDATA_RX(rx_pkts_all); | ||
2069 | AWDATA_RX(rx_bytes_all); | ||
2070 | |||
2071 | AWDATA(tx_pkts_all); | ||
2072 | AWDATA(tx_bytes_all); | ||
2073 | AWDATA(queued); | ||
2074 | AWDATA(completed); | ||
2075 | AWDATA(xretries); | ||
2076 | AWDATA(a_aggr); | ||
2077 | AWDATA(a_queued_hw); | ||
2078 | AWDATA(a_queued_sw); | ||
2079 | AWDATA(a_completed); | ||
2080 | AWDATA(a_retries); | ||
2081 | AWDATA(a_xretries); | ||
2082 | AWDATA(fifo_underrun); | ||
2083 | AWDATA(xtxop); | ||
2084 | AWDATA(timer_exp); | ||
2085 | AWDATA(desc_cfg_err); | ||
2086 | AWDATA(data_underrun); | ||
2087 | AWDATA(delim_underrun); | ||
2088 | |||
2089 | AWDATA_RX(decrypt_crc_err); | ||
2090 | AWDATA_RX(phy_err); | ||
2091 | AWDATA_RX(mic_err); | ||
2092 | AWDATA_RX(pre_delim_crc_err); | ||
2093 | AWDATA_RX(post_delim_crc_err); | ||
2094 | AWDATA_RX(decrypt_busy_err); | ||
2095 | |||
2096 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); | ||
2097 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); | ||
2098 | AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); | ||
2099 | |||
2100 | WARN_ON(i != ATH9K_SSTATS_LEN); | ||
2101 | } | ||
2102 | |||
2103 | /* End of ethtool get-stats functions */ | ||
2104 | |||
2105 | #endif | ||
2106 | |||
2107 | |||
2392 | struct ieee80211_ops ath9k_ops = { | 2108 | struct ieee80211_ops ath9k_ops = { |
2393 | .tx = ath9k_tx, | 2109 | .tx = ath9k_tx, |
2394 | .start = ath9k_start, | 2110 | .start = ath9k_start, |
@@ -2417,4 +2133,10 @@ struct ieee80211_ops ath9k_ops = { | |||
2417 | .get_stats = ath9k_get_stats, | 2133 | .get_stats = ath9k_get_stats, |
2418 | .set_antenna = ath9k_set_antenna, | 2134 | .set_antenna = ath9k_set_antenna, |
2419 | .get_antenna = ath9k_get_antenna, | 2135 | .get_antenna = ath9k_get_antenna, |
2136 | |||
2137 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
2138 | .get_et_sset_count = ath9k_get_et_sset_count, | ||
2139 | .get_et_stats = ath9k_get_et_stats, | ||
2140 | .get_et_strings = ath9k_get_et_strings, | ||
2141 | #endif | ||
2420 | }; | 2142 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 29fe52d69973..49137f477b05 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -116,42 +116,58 @@ static void ath_mci_update_scheme(struct ath_softc *sc) | |||
116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
117 | struct ath_btcoex *btcoex = &sc->btcoex; | 117 | struct ath_btcoex *btcoex = &sc->btcoex; |
118 | struct ath_mci_profile *mci = &btcoex->mci; | 118 | struct ath_mci_profile *mci = &btcoex->mci; |
119 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; | ||
119 | struct ath_mci_profile_info *info; | 120 | struct ath_mci_profile_info *info; |
120 | u32 num_profile = NUM_PROF(mci); | 121 | u32 num_profile = NUM_PROF(mci); |
121 | 122 | ||
123 | if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) | ||
124 | goto skip_tuning; | ||
125 | |||
122 | if (num_profile == 1) { | 126 | if (num_profile == 1) { |
123 | info = list_first_entry(&mci->info, | 127 | info = list_first_entry(&mci->info, |
124 | struct ath_mci_profile_info, | 128 | struct ath_mci_profile_info, |
125 | list); | 129 | list); |
126 | if (mci->num_sco && info->T == 12) { | 130 | if (mci->num_sco) { |
127 | mci->aggr_limit = 8; | 131 | if (info->T == 12) |
132 | mci->aggr_limit = 8; | ||
133 | else if (info->T == 6) { | ||
134 | mci->aggr_limit = 6; | ||
135 | btcoex->duty_cycle = 30; | ||
136 | } | ||
128 | ath_dbg(common, MCI, | 137 | ath_dbg(common, MCI, |
129 | "Single SCO, aggregation limit 2 ms\n"); | 138 | "Single SCO, aggregation limit %d 1/4 ms\n", |
130 | } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && | 139 | mci->aggr_limit); |
131 | !info->master) { | 140 | } else if (mci->num_pan || mci->num_other_acl) { |
132 | btcoex->btcoex_period = 60; | 141 | /* |
142 | * For single PAN/FTP profile, allocate 35% for BT | ||
143 | * to improve WLAN throughput. | ||
144 | */ | ||
145 | btcoex->duty_cycle = 35; | ||
146 | btcoex->btcoex_period = 53; | ||
133 | ath_dbg(common, MCI, | 147 | ath_dbg(common, MCI, |
134 | "Single slave PAN/FTP, bt period 60 ms\n"); | 148 | "Single PAN/FTP bt period %d ms dutycycle %d\n", |
135 | } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && | 149 | btcoex->duty_cycle, btcoex->btcoex_period); |
136 | (info->T > 0 && info->T < 50) && | 150 | } else if (mci->num_hid) { |
137 | (info->A > 1 || info->W > 1)) { | ||
138 | btcoex->duty_cycle = 30; | 151 | btcoex->duty_cycle = 30; |
139 | mci->aggr_limit = 8; | 152 | mci->aggr_limit = 6; |
140 | ath_dbg(common, MCI, | 153 | ath_dbg(common, MCI, |
141 | "Multiple attempt/timeout single HID " | 154 | "Multiple attempt/timeout single HID " |
142 | "aggregation limit 2 ms dutycycle 30%%\n"); | 155 | "aggregation limit 1.5 ms dutycycle 30%%\n"); |
143 | } | 156 | } |
144 | } else if ((num_profile == 2) && (mci->num_hid == 2)) { | 157 | } else if (num_profile == 2) { |
145 | btcoex->duty_cycle = 30; | 158 | if (mci->num_hid == 2) |
146 | mci->aggr_limit = 8; | 159 | btcoex->duty_cycle = 30; |
147 | ath_dbg(common, MCI, | ||
148 | "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); | ||
149 | } else if (num_profile > 3) { | ||
150 | mci->aggr_limit = 6; | 160 | mci->aggr_limit = 6; |
151 | ath_dbg(common, MCI, | 161 | ath_dbg(common, MCI, |
152 | "Three or more profiles aggregation limit 1.5 ms\n"); | 162 | "Two BT profiles aggr limit 1.5 ms dutycycle %d%%\n", |
163 | btcoex->duty_cycle); | ||
164 | } else if (num_profile >= 3) { | ||
165 | mci->aggr_limit = 4; | ||
166 | ath_dbg(common, MCI, | ||
167 | "Three or more profiles aggregation limit 1 ms\n"); | ||
153 | } | 168 | } |
154 | 169 | ||
170 | skip_tuning: | ||
155 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { | 171 | if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { |
156 | if (IS_CHAN_HT(sc->sc_ah->curchan)) | 172 | if (IS_CHAN_HT(sc->sc_ah->curchan)) |
157 | ath_mci_adjust_aggr_limit(btcoex); | 173 | ath_mci_adjust_aggr_limit(btcoex); |
@@ -538,3 +554,14 @@ void ath_mci_intr(struct ath_softc *sc) | |||
538 | mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | | 554 | mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | |
539 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); | 555 | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); |
540 | } | 556 | } |
557 | |||
558 | void ath_mci_enable(struct ath_softc *sc) | ||
559 | { | ||
560 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
561 | |||
562 | if (!common->btcoex_enabled) | ||
563 | return; | ||
564 | |||
565 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) | ||
566 | sc->sc_ah->imask |= ATH9K_INT_MCI; | ||
567 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index c841444f53c2..fc14eea034eb 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h | |||
@@ -130,4 +130,13 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci); | |||
130 | int ath_mci_setup(struct ath_softc *sc); | 130 | int ath_mci_setup(struct ath_softc *sc); |
131 | void ath_mci_cleanup(struct ath_softc *sc); | 131 | void ath_mci_cleanup(struct ath_softc *sc); |
132 | void ath_mci_intr(struct ath_softc *sc); | 132 | void ath_mci_intr(struct ath_softc *sc); |
133 | #endif | 133 | |
134 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | ||
135 | void ath_mci_enable(struct ath_softc *sc); | ||
136 | #else | ||
137 | static inline void ath_mci_enable(struct ath_softc *sc) | ||
138 | { | ||
139 | } | ||
140 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | ||
141 | |||
142 | #endif /* MCI_H*/ | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index a856b51255f4..aa0e83ac51f4 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -115,6 +115,9 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
115 | int pos; | 115 | int pos; |
116 | u8 aspm; | 116 | u8 aspm; |
117 | 117 | ||
118 | if (!ah->is_pciexpress) | ||
119 | return; | ||
120 | |||
118 | pos = pci_pcie_cap(pdev); | 121 | pos = pci_pcie_cap(pdev); |
119 | if (!pos) | 122 | if (!pos) |
120 | return; | 123 | return; |
@@ -138,6 +141,7 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
138 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); | 141 | aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); |
139 | pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); | 142 | pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); |
140 | 143 | ||
144 | ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); | ||
141 | return; | 145 | return; |
142 | } | 146 | } |
143 | 147 | ||
@@ -147,6 +151,7 @@ static void ath_pci_aspm_init(struct ath_common *common) | |||
147 | ah->aspm_enabled = true; | 151 | ah->aspm_enabled = true; |
148 | /* Initialize PCIe PM and SERDES registers. */ | 152 | /* Initialize PCIe PM and SERDES registers. */ |
149 | ath9k_hw_configpcipowersave(ah, false); | 153 | ath9k_hw_configpcipowersave(ah, false); |
154 | ath_info(common, "ASPM enabled: 0x%x\n", aspm); | ||
150 | } | 155 | } |
151 | } | 156 | } |
152 | 157 | ||
@@ -246,7 +251,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
246 | sc->mem = mem; | 251 | sc->mem = mem; |
247 | 252 | ||
248 | /* Will be cleared in ath9k_start() */ | 253 | /* Will be cleared in ath9k_start() */ |
249 | sc->sc_flags |= SC_OP_INVALID; | 254 | set_bit(SC_OP_INVALID, &sc->sc_flags); |
250 | 255 | ||
251 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); | 256 | ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); |
252 | if (ret) { | 257 | if (ret) { |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e1fcc68124dc..fbdcc80437fe 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -20,43 +20,6 @@ | |||
20 | 20 | ||
21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) | 21 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) |
22 | 22 | ||
23 | static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, | ||
24 | int mindelta, int main_rssi_avg, | ||
25 | int alt_rssi_avg, int pkt_count) | ||
26 | { | ||
27 | return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
28 | (alt_rssi_avg > main_rssi_avg + maxdelta)) || | ||
29 | (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); | ||
30 | } | ||
31 | |||
32 | static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio, | ||
33 | int curr_main_set, int curr_alt_set, | ||
34 | int alt_rssi_avg, int main_rssi_avg) | ||
35 | { | ||
36 | bool result = false; | ||
37 | switch (div_group) { | ||
38 | case 0: | ||
39 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
40 | result = true; | ||
41 | break; | ||
42 | case 1: | ||
43 | case 2: | ||
44 | if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) && | ||
45 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) && | ||
46 | (alt_rssi_avg >= (main_rssi_avg - 5))) || | ||
47 | ((curr_main_set == ATH_ANT_DIV_COMB_LNA1) && | ||
48 | (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) && | ||
49 | (alt_rssi_avg >= (main_rssi_avg - 2)))) && | ||
50 | (alt_rssi_avg >= 4)) | ||
51 | result = true; | ||
52 | else | ||
53 | result = false; | ||
54 | break; | ||
55 | } | ||
56 | |||
57 | return result; | ||
58 | } | ||
59 | |||
60 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) | 23 | static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) |
61 | { | 24 | { |
62 | return sc->ps_enabled && | 25 | return sc->ps_enabled && |
@@ -303,7 +266,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) | |||
303 | 266 | ||
304 | ath_opmode_init(sc); | 267 | ath_opmode_init(sc); |
305 | 268 | ||
306 | ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 269 | ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
307 | 270 | ||
308 | spin_unlock_bh(&sc->rx.rxbuflock); | 271 | spin_unlock_bh(&sc->rx.rxbuflock); |
309 | } | 272 | } |
@@ -322,8 +285,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
322 | int error = 0; | 285 | int error = 0; |
323 | 286 | ||
324 | spin_lock_init(&sc->sc_pcu_lock); | 287 | spin_lock_init(&sc->sc_pcu_lock); |
325 | sc->sc_flags &= ~SC_OP_RXFLUSH; | ||
326 | spin_lock_init(&sc->rx.rxbuflock); | 288 | spin_lock_init(&sc->rx.rxbuflock); |
289 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); | ||
327 | 290 | ||
328 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | 291 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + |
329 | sc->sc_ah->caps.rx_status_len; | 292 | sc->sc_ah->caps.rx_status_len; |
@@ -500,7 +463,7 @@ int ath_startrecv(struct ath_softc *sc) | |||
500 | 463 | ||
501 | start_recv: | 464 | start_recv: |
502 | ath_opmode_init(sc); | 465 | ath_opmode_init(sc); |
503 | ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); | 466 | ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); |
504 | 467 | ||
505 | spin_unlock_bh(&sc->rx.rxbuflock); | 468 | spin_unlock_bh(&sc->rx.rxbuflock); |
506 | 469 | ||
@@ -535,11 +498,11 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
535 | 498 | ||
536 | void ath_flushrecv(struct ath_softc *sc) | 499 | void ath_flushrecv(struct ath_softc *sc) |
537 | { | 500 | { |
538 | sc->sc_flags |= SC_OP_RXFLUSH; | 501 | set_bit(SC_OP_RXFLUSH, &sc->sc_flags); |
539 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | 502 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
540 | ath_rx_tasklet(sc, 1, true); | 503 | ath_rx_tasklet(sc, 1, true); |
541 | ath_rx_tasklet(sc, 1, false); | 504 | ath_rx_tasklet(sc, 1, false); |
542 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 505 | clear_bit(SC_OP_RXFLUSH, &sc->sc_flags); |
543 | } | 506 | } |
544 | 507 | ||
545 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | 508 | static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) |
@@ -624,13 +587,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) | |||
624 | 587 | ||
625 | /* Process Beacon and CAB receive in PS state */ | 588 | /* Process Beacon and CAB receive in PS state */ |
626 | if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) | 589 | if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc)) |
627 | && mybeacon) | 590 | && mybeacon) { |
628 | ath_rx_ps_beacon(sc, skb); | 591 | ath_rx_ps_beacon(sc, skb); |
629 | else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && | 592 | } else if ((sc->ps_flags & PS_WAIT_FOR_CAB) && |
630 | (ieee80211_is_data(hdr->frame_control) || | 593 | (ieee80211_is_data(hdr->frame_control) || |
631 | ieee80211_is_action(hdr->frame_control)) && | 594 | ieee80211_is_action(hdr->frame_control)) && |
632 | is_multicast_ether_addr(hdr->addr1) && | 595 | is_multicast_ether_addr(hdr->addr1) && |
633 | !ieee80211_has_moredata(hdr->frame_control)) { | 596 | !ieee80211_has_moredata(hdr->frame_control)) { |
634 | /* | 597 | /* |
635 | * No more broadcast/multicast frames to be received at this | 598 | * No more broadcast/multicast frames to be received at this |
636 | * point. | 599 | * point. |
@@ -1067,709 +1030,6 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, | |||
1067 | rxs->flag &= ~RX_FLAG_DECRYPTED; | 1030 | rxs->flag &= ~RX_FLAG_DECRYPTED; |
1068 | } | 1031 | } |
1069 | 1032 | ||
1070 | static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, | ||
1071 | struct ath_hw_antcomb_conf ant_conf, | ||
1072 | int main_rssi_avg) | ||
1073 | { | ||
1074 | antcomb->quick_scan_cnt = 0; | ||
1075 | |||
1076 | if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1077 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1078 | else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1079 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1080 | |||
1081 | switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { | ||
1082 | case 0x10: /* LNA2 A-B */ | ||
1083 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1084 | antcomb->first_quick_scan_conf = | ||
1085 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1086 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1087 | break; | ||
1088 | case 0x20: /* LNA1 A-B */ | ||
1089 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1090 | antcomb->first_quick_scan_conf = | ||
1091 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1092 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1093 | break; | ||
1094 | case 0x21: /* LNA1 LNA2 */ | ||
1095 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1096 | antcomb->first_quick_scan_conf = | ||
1097 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1098 | antcomb->second_quick_scan_conf = | ||
1099 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1100 | break; | ||
1101 | case 0x12: /* LNA2 LNA1 */ | ||
1102 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1103 | antcomb->first_quick_scan_conf = | ||
1104 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1105 | antcomb->second_quick_scan_conf = | ||
1106 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1107 | break; | ||
1108 | case 0x13: /* LNA2 A+B */ | ||
1109 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1110 | antcomb->first_quick_scan_conf = | ||
1111 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1112 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1113 | break; | ||
1114 | case 0x23: /* LNA1 A+B */ | ||
1115 | antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1116 | antcomb->first_quick_scan_conf = | ||
1117 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1118 | antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1119 | break; | ||
1120 | default: | ||
1121 | break; | ||
1122 | } | ||
1123 | } | ||
1124 | |||
1125 | static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, | ||
1126 | struct ath_hw_antcomb_conf *div_ant_conf, | ||
1127 | int main_rssi_avg, int alt_rssi_avg, | ||
1128 | int alt_ratio) | ||
1129 | { | ||
1130 | /* alt_good */ | ||
1131 | switch (antcomb->quick_scan_cnt) { | ||
1132 | case 0: | ||
1133 | /* set alt to main, and alt to first conf */ | ||
1134 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1135 | div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; | ||
1136 | break; | ||
1137 | case 1: | ||
1138 | /* set alt to main, and alt to first conf */ | ||
1139 | div_ant_conf->main_lna_conf = antcomb->main_conf; | ||
1140 | div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; | ||
1141 | antcomb->rssi_first = main_rssi_avg; | ||
1142 | antcomb->rssi_second = alt_rssi_avg; | ||
1143 | |||
1144 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1145 | /* main is LNA1 */ | ||
1146 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1147 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1148 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1149 | main_rssi_avg, alt_rssi_avg, | ||
1150 | antcomb->total_pkt_count)) | ||
1151 | antcomb->first_ratio = true; | ||
1152 | else | ||
1153 | antcomb->first_ratio = false; | ||
1154 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1155 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1156 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1157 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1158 | main_rssi_avg, alt_rssi_avg, | ||
1159 | antcomb->total_pkt_count)) | ||
1160 | antcomb->first_ratio = true; | ||
1161 | else | ||
1162 | antcomb->first_ratio = false; | ||
1163 | } else { | ||
1164 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1165 | (alt_rssi_avg > main_rssi_avg + | ||
1166 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1167 | (alt_rssi_avg > main_rssi_avg)) && | ||
1168 | (antcomb->total_pkt_count > 50)) | ||
1169 | antcomb->first_ratio = true; | ||
1170 | else | ||
1171 | antcomb->first_ratio = false; | ||
1172 | } | ||
1173 | break; | ||
1174 | case 2: | ||
1175 | antcomb->alt_good = false; | ||
1176 | antcomb->scan_not_start = false; | ||
1177 | antcomb->scan = false; | ||
1178 | antcomb->rssi_first = main_rssi_avg; | ||
1179 | antcomb->rssi_third = alt_rssi_avg; | ||
1180 | |||
1181 | if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1182 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1183 | else if (antcomb->second_quick_scan_conf == | ||
1184 | ATH_ANT_DIV_COMB_LNA2) | ||
1185 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1186 | else if (antcomb->second_quick_scan_conf == | ||
1187 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { | ||
1188 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) | ||
1189 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1190 | else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) | ||
1191 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1192 | } | ||
1193 | |||
1194 | if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + | ||
1195 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) | ||
1196 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1197 | else | ||
1198 | div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; | ||
1199 | |||
1200 | if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { | ||
1201 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1202 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI, | ||
1203 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1204 | main_rssi_avg, alt_rssi_avg, | ||
1205 | antcomb->total_pkt_count)) | ||
1206 | antcomb->second_ratio = true; | ||
1207 | else | ||
1208 | antcomb->second_ratio = false; | ||
1209 | } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { | ||
1210 | if (ath_is_alt_ant_ratio_better(alt_ratio, | ||
1211 | ATH_ANT_DIV_COMB_LNA1_DELTA_MID, | ||
1212 | ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, | ||
1213 | main_rssi_avg, alt_rssi_avg, | ||
1214 | antcomb->total_pkt_count)) | ||
1215 | antcomb->second_ratio = true; | ||
1216 | else | ||
1217 | antcomb->second_ratio = false; | ||
1218 | } else { | ||
1219 | if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && | ||
1220 | (alt_rssi_avg > main_rssi_avg + | ||
1221 | ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || | ||
1222 | (alt_rssi_avg > main_rssi_avg)) && | ||
1223 | (antcomb->total_pkt_count > 50)) | ||
1224 | antcomb->second_ratio = true; | ||
1225 | else | ||
1226 | antcomb->second_ratio = false; | ||
1227 | } | ||
1228 | |||
1229 | /* set alt to the conf with maximun ratio */ | ||
1230 | if (antcomb->first_ratio && antcomb->second_ratio) { | ||
1231 | if (antcomb->rssi_second > antcomb->rssi_third) { | ||
1232 | /* first alt*/ | ||
1233 | if ((antcomb->first_quick_scan_conf == | ||
1234 | ATH_ANT_DIV_COMB_LNA1) || | ||
1235 | (antcomb->first_quick_scan_conf == | ||
1236 | ATH_ANT_DIV_COMB_LNA2)) | ||
1237 | /* Set alt LNA1 or LNA2*/ | ||
1238 | if (div_ant_conf->main_lna_conf == | ||
1239 | ATH_ANT_DIV_COMB_LNA2) | ||
1240 | div_ant_conf->alt_lna_conf = | ||
1241 | ATH_ANT_DIV_COMB_LNA1; | ||
1242 | else | ||
1243 | div_ant_conf->alt_lna_conf = | ||
1244 | ATH_ANT_DIV_COMB_LNA2; | ||
1245 | else | ||
1246 | /* Set alt to A+B or A-B */ | ||
1247 | div_ant_conf->alt_lna_conf = | ||
1248 | antcomb->first_quick_scan_conf; | ||
1249 | } else if ((antcomb->second_quick_scan_conf == | ||
1250 | ATH_ANT_DIV_COMB_LNA1) || | ||
1251 | (antcomb->second_quick_scan_conf == | ||
1252 | ATH_ANT_DIV_COMB_LNA2)) { | ||
1253 | /* Set alt LNA1 or LNA2 */ | ||
1254 | if (div_ant_conf->main_lna_conf == | ||
1255 | ATH_ANT_DIV_COMB_LNA2) | ||
1256 | div_ant_conf->alt_lna_conf = | ||
1257 | ATH_ANT_DIV_COMB_LNA1; | ||
1258 | else | ||
1259 | div_ant_conf->alt_lna_conf = | ||
1260 | ATH_ANT_DIV_COMB_LNA2; | ||
1261 | } else { | ||
1262 | /* Set alt to A+B or A-B */ | ||
1263 | div_ant_conf->alt_lna_conf = | ||
1264 | antcomb->second_quick_scan_conf; | ||
1265 | } | ||
1266 | } else if (antcomb->first_ratio) { | ||
1267 | /* first alt */ | ||
1268 | if ((antcomb->first_quick_scan_conf == | ||
1269 | ATH_ANT_DIV_COMB_LNA1) || | ||
1270 | (antcomb->first_quick_scan_conf == | ||
1271 | ATH_ANT_DIV_COMB_LNA2)) | ||
1272 | /* Set alt LNA1 or LNA2 */ | ||
1273 | if (div_ant_conf->main_lna_conf == | ||
1274 | ATH_ANT_DIV_COMB_LNA2) | ||
1275 | div_ant_conf->alt_lna_conf = | ||
1276 | ATH_ANT_DIV_COMB_LNA1; | ||
1277 | else | ||
1278 | div_ant_conf->alt_lna_conf = | ||
1279 | ATH_ANT_DIV_COMB_LNA2; | ||
1280 | else | ||
1281 | /* Set alt to A+B or A-B */ | ||
1282 | div_ant_conf->alt_lna_conf = | ||
1283 | antcomb->first_quick_scan_conf; | ||
1284 | } else if (antcomb->second_ratio) { | ||
1285 | /* second alt */ | ||
1286 | if ((antcomb->second_quick_scan_conf == | ||
1287 | ATH_ANT_DIV_COMB_LNA1) || | ||
1288 | (antcomb->second_quick_scan_conf == | ||
1289 | ATH_ANT_DIV_COMB_LNA2)) | ||
1290 | /* Set alt LNA1 or LNA2 */ | ||
1291 | if (div_ant_conf->main_lna_conf == | ||
1292 | ATH_ANT_DIV_COMB_LNA2) | ||
1293 | div_ant_conf->alt_lna_conf = | ||
1294 | ATH_ANT_DIV_COMB_LNA1; | ||
1295 | else | ||
1296 | div_ant_conf->alt_lna_conf = | ||
1297 | ATH_ANT_DIV_COMB_LNA2; | ||
1298 | else | ||
1299 | /* Set alt to A+B or A-B */ | ||
1300 | div_ant_conf->alt_lna_conf = | ||
1301 | antcomb->second_quick_scan_conf; | ||
1302 | } else { | ||
1303 | /* main is largest */ | ||
1304 | if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || | ||
1305 | (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) | ||
1306 | /* Set alt LNA1 or LNA2 */ | ||
1307 | if (div_ant_conf->main_lna_conf == | ||
1308 | ATH_ANT_DIV_COMB_LNA2) | ||
1309 | div_ant_conf->alt_lna_conf = | ||
1310 | ATH_ANT_DIV_COMB_LNA1; | ||
1311 | else | ||
1312 | div_ant_conf->alt_lna_conf = | ||
1313 | ATH_ANT_DIV_COMB_LNA2; | ||
1314 | else | ||
1315 | /* Set alt to A+B or A-B */ | ||
1316 | div_ant_conf->alt_lna_conf = antcomb->main_conf; | ||
1317 | } | ||
1318 | break; | ||
1319 | default: | ||
1320 | break; | ||
1321 | } | ||
1322 | } | ||
1323 | |||
1324 | static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, | ||
1325 | struct ath_ant_comb *antcomb, int alt_ratio) | ||
1326 | { | ||
1327 | if (ant_conf->div_group == 0) { | ||
1328 | /* Adjust the fast_div_bias based on main and alt lna conf */ | ||
1329 | switch ((ant_conf->main_lna_conf << 4) | | ||
1330 | ant_conf->alt_lna_conf) { | ||
1331 | case 0x01: /* A-B LNA2 */ | ||
1332 | ant_conf->fast_div_bias = 0x3b; | ||
1333 | break; | ||
1334 | case 0x02: /* A-B LNA1 */ | ||
1335 | ant_conf->fast_div_bias = 0x3d; | ||
1336 | break; | ||
1337 | case 0x03: /* A-B A+B */ | ||
1338 | ant_conf->fast_div_bias = 0x1; | ||
1339 | break; | ||
1340 | case 0x10: /* LNA2 A-B */ | ||
1341 | ant_conf->fast_div_bias = 0x7; | ||
1342 | break; | ||
1343 | case 0x12: /* LNA2 LNA1 */ | ||
1344 | ant_conf->fast_div_bias = 0x2; | ||
1345 | break; | ||
1346 | case 0x13: /* LNA2 A+B */ | ||
1347 | ant_conf->fast_div_bias = 0x7; | ||
1348 | break; | ||
1349 | case 0x20: /* LNA1 A-B */ | ||
1350 | ant_conf->fast_div_bias = 0x6; | ||
1351 | break; | ||
1352 | case 0x21: /* LNA1 LNA2 */ | ||
1353 | ant_conf->fast_div_bias = 0x0; | ||
1354 | break; | ||
1355 | case 0x23: /* LNA1 A+B */ | ||
1356 | ant_conf->fast_div_bias = 0x6; | ||
1357 | break; | ||
1358 | case 0x30: /* A+B A-B */ | ||
1359 | ant_conf->fast_div_bias = 0x1; | ||
1360 | break; | ||
1361 | case 0x31: /* A+B LNA2 */ | ||
1362 | ant_conf->fast_div_bias = 0x3b; | ||
1363 | break; | ||
1364 | case 0x32: /* A+B LNA1 */ | ||
1365 | ant_conf->fast_div_bias = 0x3d; | ||
1366 | break; | ||
1367 | default: | ||
1368 | break; | ||
1369 | } | ||
1370 | } else if (ant_conf->div_group == 1) { | ||
1371 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1372 | switch ((ant_conf->main_lna_conf << 4) | | ||
1373 | ant_conf->alt_lna_conf) { | ||
1374 | case 0x01: /* A-B LNA2 */ | ||
1375 | ant_conf->fast_div_bias = 0x1; | ||
1376 | ant_conf->main_gaintb = 0; | ||
1377 | ant_conf->alt_gaintb = 0; | ||
1378 | break; | ||
1379 | case 0x02: /* A-B LNA1 */ | ||
1380 | ant_conf->fast_div_bias = 0x1; | ||
1381 | ant_conf->main_gaintb = 0; | ||
1382 | ant_conf->alt_gaintb = 0; | ||
1383 | break; | ||
1384 | case 0x03: /* A-B A+B */ | ||
1385 | ant_conf->fast_div_bias = 0x1; | ||
1386 | ant_conf->main_gaintb = 0; | ||
1387 | ant_conf->alt_gaintb = 0; | ||
1388 | break; | ||
1389 | case 0x10: /* LNA2 A-B */ | ||
1390 | if (!(antcomb->scan) && | ||
1391 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1392 | ant_conf->fast_div_bias = 0x3f; | ||
1393 | else | ||
1394 | ant_conf->fast_div_bias = 0x1; | ||
1395 | ant_conf->main_gaintb = 0; | ||
1396 | ant_conf->alt_gaintb = 0; | ||
1397 | break; | ||
1398 | case 0x12: /* LNA2 LNA1 */ | ||
1399 | ant_conf->fast_div_bias = 0x1; | ||
1400 | ant_conf->main_gaintb = 0; | ||
1401 | ant_conf->alt_gaintb = 0; | ||
1402 | break; | ||
1403 | case 0x13: /* LNA2 A+B */ | ||
1404 | if (!(antcomb->scan) && | ||
1405 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1406 | ant_conf->fast_div_bias = 0x3f; | ||
1407 | else | ||
1408 | ant_conf->fast_div_bias = 0x1; | ||
1409 | ant_conf->main_gaintb = 0; | ||
1410 | ant_conf->alt_gaintb = 0; | ||
1411 | break; | ||
1412 | case 0x20: /* LNA1 A-B */ | ||
1413 | if (!(antcomb->scan) && | ||
1414 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1415 | ant_conf->fast_div_bias = 0x3f; | ||
1416 | else | ||
1417 | ant_conf->fast_div_bias = 0x1; | ||
1418 | ant_conf->main_gaintb = 0; | ||
1419 | ant_conf->alt_gaintb = 0; | ||
1420 | break; | ||
1421 | case 0x21: /* LNA1 LNA2 */ | ||
1422 | ant_conf->fast_div_bias = 0x1; | ||
1423 | ant_conf->main_gaintb = 0; | ||
1424 | ant_conf->alt_gaintb = 0; | ||
1425 | break; | ||
1426 | case 0x23: /* LNA1 A+B */ | ||
1427 | if (!(antcomb->scan) && | ||
1428 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1429 | ant_conf->fast_div_bias = 0x3f; | ||
1430 | else | ||
1431 | ant_conf->fast_div_bias = 0x1; | ||
1432 | ant_conf->main_gaintb = 0; | ||
1433 | ant_conf->alt_gaintb = 0; | ||
1434 | break; | ||
1435 | case 0x30: /* A+B A-B */ | ||
1436 | ant_conf->fast_div_bias = 0x1; | ||
1437 | ant_conf->main_gaintb = 0; | ||
1438 | ant_conf->alt_gaintb = 0; | ||
1439 | break; | ||
1440 | case 0x31: /* A+B LNA2 */ | ||
1441 | ant_conf->fast_div_bias = 0x1; | ||
1442 | ant_conf->main_gaintb = 0; | ||
1443 | ant_conf->alt_gaintb = 0; | ||
1444 | break; | ||
1445 | case 0x32: /* A+B LNA1 */ | ||
1446 | ant_conf->fast_div_bias = 0x1; | ||
1447 | ant_conf->main_gaintb = 0; | ||
1448 | ant_conf->alt_gaintb = 0; | ||
1449 | break; | ||
1450 | default: | ||
1451 | break; | ||
1452 | } | ||
1453 | } else if (ant_conf->div_group == 2) { | ||
1454 | /* Adjust the fast_div_bias based on main and alt_lna_conf */ | ||
1455 | switch ((ant_conf->main_lna_conf << 4) | | ||
1456 | ant_conf->alt_lna_conf) { | ||
1457 | case 0x01: /* A-B LNA2 */ | ||
1458 | ant_conf->fast_div_bias = 0x1; | ||
1459 | ant_conf->main_gaintb = 0; | ||
1460 | ant_conf->alt_gaintb = 0; | ||
1461 | break; | ||
1462 | case 0x02: /* A-B LNA1 */ | ||
1463 | ant_conf->fast_div_bias = 0x1; | ||
1464 | ant_conf->main_gaintb = 0; | ||
1465 | ant_conf->alt_gaintb = 0; | ||
1466 | break; | ||
1467 | case 0x03: /* A-B A+B */ | ||
1468 | ant_conf->fast_div_bias = 0x1; | ||
1469 | ant_conf->main_gaintb = 0; | ||
1470 | ant_conf->alt_gaintb = 0; | ||
1471 | break; | ||
1472 | case 0x10: /* LNA2 A-B */ | ||
1473 | if (!(antcomb->scan) && | ||
1474 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1475 | ant_conf->fast_div_bias = 0x1; | ||
1476 | else | ||
1477 | ant_conf->fast_div_bias = 0x2; | ||
1478 | ant_conf->main_gaintb = 0; | ||
1479 | ant_conf->alt_gaintb = 0; | ||
1480 | break; | ||
1481 | case 0x12: /* LNA2 LNA1 */ | ||
1482 | ant_conf->fast_div_bias = 0x1; | ||
1483 | ant_conf->main_gaintb = 0; | ||
1484 | ant_conf->alt_gaintb = 0; | ||
1485 | break; | ||
1486 | case 0x13: /* LNA2 A+B */ | ||
1487 | if (!(antcomb->scan) && | ||
1488 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1489 | ant_conf->fast_div_bias = 0x1; | ||
1490 | else | ||
1491 | ant_conf->fast_div_bias = 0x2; | ||
1492 | ant_conf->main_gaintb = 0; | ||
1493 | ant_conf->alt_gaintb = 0; | ||
1494 | break; | ||
1495 | case 0x20: /* LNA1 A-B */ | ||
1496 | if (!(antcomb->scan) && | ||
1497 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1498 | ant_conf->fast_div_bias = 0x1; | ||
1499 | else | ||
1500 | ant_conf->fast_div_bias = 0x2; | ||
1501 | ant_conf->main_gaintb = 0; | ||
1502 | ant_conf->alt_gaintb = 0; | ||
1503 | break; | ||
1504 | case 0x21: /* LNA1 LNA2 */ | ||
1505 | ant_conf->fast_div_bias = 0x1; | ||
1506 | ant_conf->main_gaintb = 0; | ||
1507 | ant_conf->alt_gaintb = 0; | ||
1508 | break; | ||
1509 | case 0x23: /* LNA1 A+B */ | ||
1510 | if (!(antcomb->scan) && | ||
1511 | (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) | ||
1512 | ant_conf->fast_div_bias = 0x1; | ||
1513 | else | ||
1514 | ant_conf->fast_div_bias = 0x2; | ||
1515 | ant_conf->main_gaintb = 0; | ||
1516 | ant_conf->alt_gaintb = 0; | ||
1517 | break; | ||
1518 | case 0x30: /* A+B A-B */ | ||
1519 | ant_conf->fast_div_bias = 0x1; | ||
1520 | ant_conf->main_gaintb = 0; | ||
1521 | ant_conf->alt_gaintb = 0; | ||
1522 | break; | ||
1523 | case 0x31: /* A+B LNA2 */ | ||
1524 | ant_conf->fast_div_bias = 0x1; | ||
1525 | ant_conf->main_gaintb = 0; | ||
1526 | ant_conf->alt_gaintb = 0; | ||
1527 | break; | ||
1528 | case 0x32: /* A+B LNA1 */ | ||
1529 | ant_conf->fast_div_bias = 0x1; | ||
1530 | ant_conf->main_gaintb = 0; | ||
1531 | ant_conf->alt_gaintb = 0; | ||
1532 | break; | ||
1533 | default: | ||
1534 | break; | ||
1535 | } | ||
1536 | } | ||
1537 | } | ||
1538 | |||
1539 | /* Antenna diversity and combining */ | ||
1540 | static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | ||
1541 | { | ||
1542 | struct ath_hw_antcomb_conf div_ant_conf; | ||
1543 | struct ath_ant_comb *antcomb = &sc->ant_comb; | ||
1544 | int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||
1545 | int curr_main_set; | ||
1546 | int main_rssi = rs->rs_rssi_ctl0; | ||
1547 | int alt_rssi = rs->rs_rssi_ctl1; | ||
1548 | int rx_ant_conf, main_ant_conf; | ||
1549 | bool short_scan = false; | ||
1550 | |||
1551 | rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & | ||
1552 | ATH_ANT_RX_MASK; | ||
1553 | main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & | ||
1554 | ATH_ANT_RX_MASK; | ||
1555 | |||
1556 | /* Record packet only when both main_rssi and alt_rssi is positive */ | ||
1557 | if (main_rssi > 0 && alt_rssi > 0) { | ||
1558 | antcomb->total_pkt_count++; | ||
1559 | antcomb->main_total_rssi += main_rssi; | ||
1560 | antcomb->alt_total_rssi += alt_rssi; | ||
1561 | if (main_ant_conf == rx_ant_conf) | ||
1562 | antcomb->main_recv_cnt++; | ||
1563 | else | ||
1564 | antcomb->alt_recv_cnt++; | ||
1565 | } | ||
1566 | |||
1567 | /* Short scan check */ | ||
1568 | if (antcomb->scan && antcomb->alt_good) { | ||
1569 | if (time_after(jiffies, antcomb->scan_start_time + | ||
1570 | msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) | ||
1571 | short_scan = true; | ||
1572 | else | ||
1573 | if (antcomb->total_pkt_count == | ||
1574 | ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { | ||
1575 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1576 | antcomb->total_pkt_count); | ||
1577 | if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) | ||
1578 | short_scan = true; | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1582 | if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || | ||
1583 | rs->rs_moreaggr) && !short_scan) | ||
1584 | return; | ||
1585 | |||
1586 | if (antcomb->total_pkt_count) { | ||
1587 | alt_ratio = ((antcomb->alt_recv_cnt * 100) / | ||
1588 | antcomb->total_pkt_count); | ||
1589 | main_rssi_avg = (antcomb->main_total_rssi / | ||
1590 | antcomb->total_pkt_count); | ||
1591 | alt_rssi_avg = (antcomb->alt_total_rssi / | ||
1592 | antcomb->total_pkt_count); | ||
1593 | } | ||
1594 | |||
1595 | |||
1596 | ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||
1597 | curr_alt_set = div_ant_conf.alt_lna_conf; | ||
1598 | curr_main_set = div_ant_conf.main_lna_conf; | ||
1599 | |||
1600 | antcomb->count++; | ||
1601 | |||
1602 | if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { | ||
1603 | if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { | ||
1604 | ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, | ||
1605 | main_rssi_avg); | ||
1606 | antcomb->alt_good = true; | ||
1607 | } else { | ||
1608 | antcomb->alt_good = false; | ||
1609 | } | ||
1610 | |||
1611 | antcomb->count = 0; | ||
1612 | antcomb->scan = true; | ||
1613 | antcomb->scan_not_start = true; | ||
1614 | } | ||
1615 | |||
1616 | if (!antcomb->scan) { | ||
1617 | if (ath_ant_div_comb_alt_check(div_ant_conf.div_group, | ||
1618 | alt_ratio, curr_main_set, curr_alt_set, | ||
1619 | alt_rssi_avg, main_rssi_avg)) { | ||
1620 | if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1621 | /* Switch main and alt LNA */ | ||
1622 | div_ant_conf.main_lna_conf = | ||
1623 | ATH_ANT_DIV_COMB_LNA2; | ||
1624 | div_ant_conf.alt_lna_conf = | ||
1625 | ATH_ANT_DIV_COMB_LNA1; | ||
1626 | } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1627 | div_ant_conf.main_lna_conf = | ||
1628 | ATH_ANT_DIV_COMB_LNA1; | ||
1629 | div_ant_conf.alt_lna_conf = | ||
1630 | ATH_ANT_DIV_COMB_LNA2; | ||
1631 | } | ||
1632 | |||
1633 | goto div_comb_done; | ||
1634 | } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && | ||
1635 | (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { | ||
1636 | /* Set alt to another LNA */ | ||
1637 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) | ||
1638 | div_ant_conf.alt_lna_conf = | ||
1639 | ATH_ANT_DIV_COMB_LNA1; | ||
1640 | else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) | ||
1641 | div_ant_conf.alt_lna_conf = | ||
1642 | ATH_ANT_DIV_COMB_LNA2; | ||
1643 | |||
1644 | goto div_comb_done; | ||
1645 | } | ||
1646 | |||
1647 | if ((alt_rssi_avg < (main_rssi_avg + | ||
1648 | div_ant_conf.lna1_lna2_delta))) | ||
1649 | goto div_comb_done; | ||
1650 | } | ||
1651 | |||
1652 | if (!antcomb->scan_not_start) { | ||
1653 | switch (curr_alt_set) { | ||
1654 | case ATH_ANT_DIV_COMB_LNA2: | ||
1655 | antcomb->rssi_lna2 = alt_rssi_avg; | ||
1656 | antcomb->rssi_lna1 = main_rssi_avg; | ||
1657 | antcomb->scan = true; | ||
1658 | /* set to A+B */ | ||
1659 | div_ant_conf.main_lna_conf = | ||
1660 | ATH_ANT_DIV_COMB_LNA1; | ||
1661 | div_ant_conf.alt_lna_conf = | ||
1662 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1663 | break; | ||
1664 | case ATH_ANT_DIV_COMB_LNA1: | ||
1665 | antcomb->rssi_lna1 = alt_rssi_avg; | ||
1666 | antcomb->rssi_lna2 = main_rssi_avg; | ||
1667 | antcomb->scan = true; | ||
1668 | /* set to A+B */ | ||
1669 | div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; | ||
1670 | div_ant_conf.alt_lna_conf = | ||
1671 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1672 | break; | ||
1673 | case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: | ||
1674 | antcomb->rssi_add = alt_rssi_avg; | ||
1675 | antcomb->scan = true; | ||
1676 | /* set to A-B */ | ||
1677 | div_ant_conf.alt_lna_conf = | ||
1678 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1679 | break; | ||
1680 | case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: | ||
1681 | antcomb->rssi_sub = alt_rssi_avg; | ||
1682 | antcomb->scan = false; | ||
1683 | if (antcomb->rssi_lna2 > | ||
1684 | (antcomb->rssi_lna1 + | ||
1685 | ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { | ||
1686 | /* use LNA2 as main LNA */ | ||
1687 | if ((antcomb->rssi_add > antcomb->rssi_lna1) && | ||
1688 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1689 | /* set to A+B */ | ||
1690 | div_ant_conf.main_lna_conf = | ||
1691 | ATH_ANT_DIV_COMB_LNA2; | ||
1692 | div_ant_conf.alt_lna_conf = | ||
1693 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1694 | } else if (antcomb->rssi_sub > | ||
1695 | antcomb->rssi_lna1) { | ||
1696 | /* set to A-B */ | ||
1697 | div_ant_conf.main_lna_conf = | ||
1698 | ATH_ANT_DIV_COMB_LNA2; | ||
1699 | div_ant_conf.alt_lna_conf = | ||
1700 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1701 | } else { | ||
1702 | /* set to LNA1 */ | ||
1703 | div_ant_conf.main_lna_conf = | ||
1704 | ATH_ANT_DIV_COMB_LNA2; | ||
1705 | div_ant_conf.alt_lna_conf = | ||
1706 | ATH_ANT_DIV_COMB_LNA1; | ||
1707 | } | ||
1708 | } else { | ||
1709 | /* use LNA1 as main LNA */ | ||
1710 | if ((antcomb->rssi_add > antcomb->rssi_lna2) && | ||
1711 | (antcomb->rssi_add > antcomb->rssi_sub)) { | ||
1712 | /* set to A+B */ | ||
1713 | div_ant_conf.main_lna_conf = | ||
1714 | ATH_ANT_DIV_COMB_LNA1; | ||
1715 | div_ant_conf.alt_lna_conf = | ||
1716 | ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; | ||
1717 | } else if (antcomb->rssi_sub > | ||
1718 | antcomb->rssi_lna1) { | ||
1719 | /* set to A-B */ | ||
1720 | div_ant_conf.main_lna_conf = | ||
1721 | ATH_ANT_DIV_COMB_LNA1; | ||
1722 | div_ant_conf.alt_lna_conf = | ||
1723 | ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; | ||
1724 | } else { | ||
1725 | /* set to LNA2 */ | ||
1726 | div_ant_conf.main_lna_conf = | ||
1727 | ATH_ANT_DIV_COMB_LNA1; | ||
1728 | div_ant_conf.alt_lna_conf = | ||
1729 | ATH_ANT_DIV_COMB_LNA2; | ||
1730 | } | ||
1731 | } | ||
1732 | break; | ||
1733 | default: | ||
1734 | break; | ||
1735 | } | ||
1736 | } else { | ||
1737 | if (!antcomb->alt_good) { | ||
1738 | antcomb->scan_not_start = false; | ||
1739 | /* Set alt to another LNA */ | ||
1740 | if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { | ||
1741 | div_ant_conf.main_lna_conf = | ||
1742 | ATH_ANT_DIV_COMB_LNA2; | ||
1743 | div_ant_conf.alt_lna_conf = | ||
1744 | ATH_ANT_DIV_COMB_LNA1; | ||
1745 | } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { | ||
1746 | div_ant_conf.main_lna_conf = | ||
1747 | ATH_ANT_DIV_COMB_LNA1; | ||
1748 | div_ant_conf.alt_lna_conf = | ||
1749 | ATH_ANT_DIV_COMB_LNA2; | ||
1750 | } | ||
1751 | goto div_comb_done; | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, | ||
1756 | main_rssi_avg, alt_rssi_avg, | ||
1757 | alt_ratio); | ||
1758 | |||
1759 | antcomb->quick_scan_cnt++; | ||
1760 | |||
1761 | div_comb_done: | ||
1762 | ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio); | ||
1763 | ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); | ||
1764 | |||
1765 | antcomb->scan_start_time = jiffies; | ||
1766 | antcomb->total_pkt_count = 0; | ||
1767 | antcomb->main_total_rssi = 0; | ||
1768 | antcomb->alt_total_rssi = 0; | ||
1769 | antcomb->main_recv_cnt = 0; | ||
1770 | antcomb->alt_recv_cnt = 0; | ||
1771 | } | ||
1772 | |||
1773 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1033 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
1774 | { | 1034 | { |
1775 | struct ath_buf *bf; | 1035 | struct ath_buf *bf; |
@@ -1803,7 +1063,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1803 | 1063 | ||
1804 | do { | 1064 | do { |
1805 | /* If handling rx interrupt and flush is in progress => exit */ | 1065 | /* If handling rx interrupt and flush is in progress => exit */ |
1806 | if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) | 1066 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) |
1807 | break; | 1067 | break; |
1808 | 1068 | ||
1809 | memset(&rs, 0, sizeof(rs)); | 1069 | memset(&rs, 0, sizeof(rs)); |
@@ -1841,13 +1101,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1841 | else | 1101 | else |
1842 | rs.is_mybeacon = false; | 1102 | rs.is_mybeacon = false; |
1843 | 1103 | ||
1104 | sc->rx.num_pkts++; | ||
1844 | ath_debug_stat_rx(sc, &rs); | 1105 | ath_debug_stat_rx(sc, &rs); |
1845 | 1106 | ||
1846 | /* | 1107 | /* |
1847 | * If we're asked to flush receive queue, directly | 1108 | * If we're asked to flush receive queue, directly |
1848 | * chain it back at the queue without processing it. | 1109 | * chain it back at the queue without processing it. |
1849 | */ | 1110 | */ |
1850 | if (sc->sc_flags & SC_OP_RXFLUSH) { | 1111 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) { |
1851 | RX_STAT_INC(rx_drop_rxflush); | 1112 | RX_STAT_INC(rx_drop_rxflush); |
1852 | goto requeue_drop_frag; | 1113 | goto requeue_drop_frag; |
1853 | } | 1114 | } |
@@ -1968,7 +1229,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1968 | skb_trim(skb, skb->len - 8); | 1229 | skb_trim(skb, skb->len - 8); |
1969 | 1230 | ||
1970 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | 1231 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
1971 | |||
1972 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1232 | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1973 | PS_WAIT_FOR_CAB | | 1233 | PS_WAIT_FOR_CAB | |
1974 | PS_WAIT_FOR_PSPOLL_DATA)) || | 1234 | PS_WAIT_FOR_PSPOLL_DATA)) || |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 458f81b4a7cb..560d6effac7a 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -2211,5 +2211,7 @@ enum { | |||
2211 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff | 2211 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff |
2212 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0 | 2212 | #define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0 |
2213 | 2213 | ||
2214 | #define AR_GLB_SWREG_DISCONT_MODE 0x2002c | ||
2215 | #define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3 | ||
2214 | 2216 | ||
2215 | #endif | 2217 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01d6cde..f777ddcd1172 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -105,19 +105,19 @@ static int ath_max_4ms_framelen[4][32] = { | |||
105 | /* Aggregation logic */ | 105 | /* Aggregation logic */ |
106 | /*********************/ | 106 | /*********************/ |
107 | 107 | ||
108 | static void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) | 108 | void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) |
109 | __acquires(&txq->axq_lock) | 109 | __acquires(&txq->axq_lock) |
110 | { | 110 | { |
111 | spin_lock_bh(&txq->axq_lock); | 111 | spin_lock_bh(&txq->axq_lock); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) | 114 | void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq) |
115 | __releases(&txq->axq_lock) | 115 | __releases(&txq->axq_lock) |
116 | { | 116 | { |
117 | spin_unlock_bh(&txq->axq_lock); | 117 | spin_unlock_bh(&txq->axq_lock); |
118 | } | 118 | } |
119 | 119 | ||
120 | static void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) | 120 | void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) |
121 | __releases(&txq->axq_lock) | 121 | __releases(&txq->axq_lock) |
122 | { | 122 | { |
123 | struct sk_buff_head q; | 123 | struct sk_buff_head q; |
@@ -1536,7 +1536,7 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1536 | int i; | 1536 | int i; |
1537 | u32 npend = 0; | 1537 | u32 npend = 0; |
1538 | 1538 | ||
1539 | if (sc->sc_flags & SC_OP_INVALID) | 1539 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) |
1540 | return true; | 1540 | return true; |
1541 | 1541 | ||
1542 | ath9k_hw_abort_tx_dma(ah); | 1542 | ath9k_hw_abort_tx_dma(ah); |
@@ -1994,6 +1994,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1994 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1995 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 1995 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1996 | int q, padpos, padsize; | 1996 | int q, padpos, padsize; |
1997 | unsigned long flags; | ||
1997 | 1998 | ||
1998 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 1999 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
1999 | 2000 | ||
@@ -2012,6 +2013,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2012 | skb_pull(skb, padsize); | 2013 | skb_pull(skb, padsize); |
2013 | } | 2014 | } |
2014 | 2015 | ||
2016 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
2015 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { | 2017 | if ((sc->ps_flags & PS_WAIT_FOR_TX_ACK) && !txq->axq_depth) { |
2016 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; | 2018 | sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; |
2017 | ath_dbg(common, PS, | 2019 | ath_dbg(common, PS, |
@@ -2021,6 +2023,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2021 | PS_WAIT_FOR_PSPOLL_DATA | | 2023 | PS_WAIT_FOR_PSPOLL_DATA | |
2022 | PS_WAIT_FOR_TX_ACK)); | 2024 | PS_WAIT_FOR_TX_ACK)); |
2023 | } | 2025 | } |
2026 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
2024 | 2027 | ||
2025 | q = skb_get_queue_mapping(skb); | 2028 | q = skb_get_queue_mapping(skb); |
2026 | if (txq == sc->tx.txq_map[q]) { | 2029 | if (txq == sc->tx.txq_map[q]) { |
@@ -2231,46 +2234,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2231 | ath_txq_unlock_complete(sc, txq); | 2234 | ath_txq_unlock_complete(sc, txq); |
2232 | } | 2235 | } |
2233 | 2236 | ||
2234 | static void ath_tx_complete_poll_work(struct work_struct *work) | ||
2235 | { | ||
2236 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2237 | tx_complete_work.work); | ||
2238 | struct ath_txq *txq; | ||
2239 | int i; | ||
2240 | bool needreset = false; | ||
2241 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
2242 | sc->tx_complete_poll_work_seen++; | ||
2243 | #endif | ||
2244 | |||
2245 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | ||
2246 | if (ATH_TXQ_SETUP(sc, i)) { | ||
2247 | txq = &sc->tx.txq[i]; | ||
2248 | ath_txq_lock(sc, txq); | ||
2249 | if (txq->axq_depth) { | ||
2250 | if (txq->axq_tx_inprogress) { | ||
2251 | needreset = true; | ||
2252 | ath_txq_unlock(sc, txq); | ||
2253 | break; | ||
2254 | } else { | ||
2255 | txq->axq_tx_inprogress = true; | ||
2256 | } | ||
2257 | } | ||
2258 | ath_txq_unlock_complete(sc, txq); | ||
2259 | } | ||
2260 | |||
2261 | if (needreset) { | ||
2262 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, | ||
2263 | "tx hung, resetting the chip\n"); | ||
2264 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | ||
2265 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
2266 | } | ||
2267 | |||
2268 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
2269 | msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | ||
2270 | } | ||
2271 | |||
2272 | |||
2273 | |||
2274 | void ath_tx_tasklet(struct ath_softc *sc) | 2237 | void ath_tx_tasklet(struct ath_softc *sc) |
2275 | { | 2238 | { |
2276 | struct ath_hw *ah = sc->sc_ah; | 2239 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index 195dc6538110..39a63874b275 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c | |||
@@ -138,7 +138,7 @@ int carl9170_reboot(struct ar9170 *ar) | |||
138 | if (!cmd) | 138 | if (!cmd) |
139 | return -ENOMEM; | 139 | return -ENOMEM; |
140 | 140 | ||
141 | err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true); | 141 | err = __carl9170_exec_cmd(ar, cmd, true); |
142 | return err; | 142 | return err; |
143 | } | 143 | } |
144 | 144 | ||
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 84b22eec7abd..7a8e90eaad83 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c | |||
@@ -161,7 +161,7 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) | |||
161 | 161 | ||
162 | void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | 162 | void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) |
163 | { | 163 | { |
164 | struct carl9170_rsp *cmd = (void *) buf; | 164 | struct carl9170_rsp *cmd = buf; |
165 | struct ieee80211_vif *vif; | 165 | struct ieee80211_vif *vif; |
166 | 166 | ||
167 | if (carl9170_check_sequence(ar, cmd->hdr.seq)) | 167 | if (carl9170_check_sequence(ar, cmd->hdr.seq)) |
@@ -520,7 +520,7 @@ static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie) | |||
520 | */ | 520 | */ |
521 | static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) | 521 | static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) |
522 | { | 522 | { |
523 | struct ieee80211_hdr *hdr = (void *) data; | 523 | struct ieee80211_hdr *hdr = data; |
524 | struct ieee80211_tim_ie *tim_ie; | 524 | struct ieee80211_tim_ie *tim_ie; |
525 | u8 *tim; | 525 | u8 *tim; |
526 | u8 tim_len; | 526 | u8 tim_len; |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index d07c0301da6a..4a4e98f71807 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -2952,10 +2952,10 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) | |||
2952 | /* current AP address - only in reassoc frame */ | 2952 | /* current AP address - only in reassoc frame */ |
2953 | if (is_reassoc) { | 2953 | if (is_reassoc) { |
2954 | memcpy(body.ap, priv->CurrentBSSID, 6); | 2954 | memcpy(body.ap, priv->CurrentBSSID, 6); |
2955 | ssid_el_p = (u8 *)&body.ssid_el_id; | 2955 | ssid_el_p = &body.ssid_el_id; |
2956 | bodysize = 18 + priv->SSID_size; | 2956 | bodysize = 18 + priv->SSID_size; |
2957 | } else { | 2957 | } else { |
2958 | ssid_el_p = (u8 *)&body.ap[0]; | 2958 | ssid_el_p = &body.ap[0]; |
2959 | bodysize = 12 + priv->SSID_size; | 2959 | bodysize = 12 + priv->SSID_size; |
2960 | } | 2960 | } |
2961 | 2961 | ||
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index f1f8bd09bd87..ff50cb4290e4 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -52,7 +52,7 @@ struct b43legacy_dmadesc32 *op32_idx2desc(struct b43legacy_dmaring *ring, | |||
52 | desc = ring->descbase; | 52 | desc = ring->descbase; |
53 | desc = &(desc[slot]); | 53 | desc = &(desc[slot]); |
54 | 54 | ||
55 | return (struct b43legacy_dmadesc32 *)desc; | 55 | return desc; |
56 | } | 56 | } |
57 | 57 | ||
58 | static void op32_fill_descriptor(struct b43legacy_dmaring *ring, | 58 | static void op32_fill_descriptor(struct b43legacy_dmaring *ring, |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..8b06ca56125e 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -1508,7 +1508,7 @@ static void b43legacy_release_firmware(struct b43legacy_wldev *dev) | |||
1508 | 1508 | ||
1509 | static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) | 1509 | static void b43legacy_print_fw_helptext(struct b43legacy_wl *wl) |
1510 | { | 1510 | { |
1511 | b43legacyerr(wl, "You must go to http://linuxwireless.org/en/users/" | 1511 | b43legacyerr(wl, "You must go to http://wireless.kernel.org/en/users/" |
1512 | "Drivers/b43#devicefirmware " | 1512 | "Drivers/b43#devicefirmware " |
1513 | "and download the correct firmware (version 3).\n"); | 1513 | "and download the correct firmware (version 3).\n"); |
1514 | } | 1514 | } |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index a8012f2749ee..b8ffea6f5c64 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -269,8 +269,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
269 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 269 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) |
270 | (&txhdr->plcp), plcp_fragment_len, | 270 | (&txhdr->plcp), plcp_fragment_len, |
271 | rate); | 271 | rate); |
272 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 272 | b43legacy_generate_plcp_hdr(&txhdr->plcp_fb, plcp_fragment_len, |
273 | (&txhdr->plcp_fb), plcp_fragment_len, | ||
274 | rate_fb->hw_value); | 273 | rate_fb->hw_value); |
275 | 274 | ||
276 | /* PHY TX Control word */ | 275 | /* PHY TX Control word */ |
@@ -340,8 +339,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
340 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 339 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) |
341 | (&txhdr->rts_plcp), | 340 | (&txhdr->rts_plcp), |
342 | len, rts_rate); | 341 | len, rts_rate); |
343 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 342 | b43legacy_generate_plcp_hdr(&txhdr->rts_plcp_fb, |
344 | (&txhdr->rts_plcp_fb), | ||
345 | len, rts_rate_fb); | 343 | len, rts_rate_fb); |
346 | hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); | 344 | hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); |
347 | txhdr->rts_dur_fb = hdr->duration_id; | 345 | txhdr->rts_dur_fb = hdr->duration_id; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1dbf2be478c8..4deae28fc211 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -2502,7 +2502,7 @@ clkwait: | |||
2502 | int ret, i; | 2502 | int ret, i; |
2503 | 2503 | ||
2504 | ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, | 2504 | ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, |
2505 | SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf, | 2505 | SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, |
2506 | (u32) bus->ctrl_frame_len); | 2506 | (u32) bus->ctrl_frame_len); |
2507 | 2507 | ||
2508 | if (ret < 0) { | 2508 | if (ret < 0) { |
@@ -3327,7 +3327,7 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) | |||
3327 | len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); | 3327 | len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); |
3328 | 3328 | ||
3329 | if (len > 0 && len < MEMBLOCK) { | 3329 | if (len > 0 && len < MEMBLOCK) { |
3330 | bufp = (char *)memblock; | 3330 | bufp = memblock; |
3331 | bufp[len] = 0; | 3331 | bufp[len] = 0; |
3332 | len = brcmf_process_nvram_vars(bufp, len); | 3332 | len = brcmf_process_nvram_vars(bufp, len); |
3333 | bufp += len; | 3333 | bufp += len; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index 6d8b7213643a..3c6f9b1e8d05 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | |||
@@ -631,9 +631,8 @@ uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val) | |||
631 | cc = sii->icbus->drv_cc.core; | 631 | cc = sii->icbus->drv_cc.core; |
632 | 632 | ||
633 | /* mask and set */ | 633 | /* mask and set */ |
634 | if (mask || val) { | 634 | if (mask || val) |
635 | bcma_maskset32(cc, regoff, ~mask, val); | 635 | bcma_maskset32(cc, regoff, ~mask, val); |
636 | } | ||
637 | 636 | ||
638 | /* readback */ | 637 | /* readback */ |
639 | w = bcma_read32(cc, regoff); | 638 | w = bcma_read32(cc, regoff); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index d9f04a683bdb..d6fa9829af9a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h | |||
@@ -193,7 +193,7 @@ extern void ai_detach(struct si_pub *sih); | |||
193 | extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); | 193 | extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); |
194 | extern void ai_clkctl_init(struct si_pub *sih); | 194 | extern void ai_clkctl_init(struct si_pub *sih); |
195 | extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); | 195 | extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); |
196 | extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); | 196 | extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); |
197 | extern bool ai_deviceremoved(struct si_pub *sih); | 197 | extern bool ai_deviceremoved(struct si_pub *sih); |
198 | 198 | ||
199 | extern void ai_pci_down(struct si_pub *sih); | 199 | extern void ai_pci_down(struct si_pub *sih); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 11054ae9d4f6..7516639412ec 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -1433,7 +1433,7 @@ void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) | |||
1433 | struct ieee80211_tx_info *tx_info; | 1433 | struct ieee80211_tx_info *tx_info; |
1434 | 1434 | ||
1435 | while (i != end) { | 1435 | while (i != end) { |
1436 | skb = (struct sk_buff *)di->txp[i]; | 1436 | skb = di->txp[i]; |
1437 | if (skb != NULL) { | 1437 | if (skb != NULL) { |
1438 | tx_info = (struct ieee80211_tx_info *)skb->cb; | 1438 | tx_info = (struct ieee80211_tx_info *)skb->cb; |
1439 | (callback_fnc)(tx_info, arg_a); | 1439 | (callback_fnc)(tx_info, arg_a); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 19db4052c44c..e67556780a31 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -8318,7 +8318,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, | |||
8318 | struct brcms_pub *pub; | 8318 | struct brcms_pub *pub; |
8319 | 8319 | ||
8320 | /* allocate struct brcms_c_info state and its substructures */ | 8320 | /* allocate struct brcms_c_info state and its substructures */ |
8321 | wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, 0); | 8321 | wlc = brcms_c_attach_malloc(unit, &err, 0); |
8322 | if (wlc == NULL) | 8322 | if (wlc == NULL) |
8323 | goto fail; | 8323 | goto fail; |
8324 | wlc->wiphy = wl->wiphy; | 8324 | wlc->wiphy = wl->wiphy; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index 13b261517cce..366718146418 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | |||
@@ -14358,7 +14358,7 @@ void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs) | |||
14358 | 14358 | ||
14359 | wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); | 14359 | wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); |
14360 | 14360 | ||
14361 | if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) | 14361 | if (pi->sh && (pi->sh->_rifs_phy != rifs)) |
14362 | pi->sh->_rifs_phy = rifs; | 14362 | pi->sh->_rifs_phy = rifs; |
14363 | } | 14363 | } |
14364 | 14364 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index b45ab34cdfdc..3e6405e06ac0 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c | |||
@@ -43,6 +43,8 @@ EXPORT_SYMBOL(brcmu_pkt_buf_get_skb); | |||
43 | /* Free the driver packet. Free the tag if present */ | 43 | /* Free the driver packet. Free the tag if present */ |
44 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) | 44 | void brcmu_pkt_buf_free_skb(struct sk_buff *skb) |
45 | { | 45 | { |
46 | if (!skb) | ||
47 | return; | ||
46 | WARN_ON(skb->next); | 48 | WARN_ON(skb->next); |
47 | if (skb->destructor) | 49 | if (skb->destructor) |
48 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if | 50 | /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if |
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 75ef8f04aabe..dc447c1b5abe 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -58,8 +58,7 @@ static int prism2_stats_proc_read(char *page, char **start, off_t off, | |||
58 | { | 58 | { |
59 | char *p = page; | 59 | char *p = page; |
60 | local_info_t *local = (local_info_t *) data; | 60 | local_info_t *local = (local_info_t *) data; |
61 | struct comm_tallies_sums *sums = (struct comm_tallies_sums *) | 61 | struct comm_tallies_sums *sums = &local->comm_tallies; |
62 | &local->comm_tallies; | ||
63 | 62 | ||
64 | if (off != 0) { | 63 | if (off != 0) { |
65 | *eof = 1; | 64 | *eof = 1; |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 0036737fe8e3..0df459147394 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -2701,6 +2701,20 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) | |||
2701 | memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6); | 2701 | memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6); |
2702 | } | 2702 | } |
2703 | 2703 | ||
2704 | static void ipw_read_eeprom(struct ipw_priv *priv) | ||
2705 | { | ||
2706 | int i; | ||
2707 | __le16 *eeprom = (__le16 *) priv->eeprom; | ||
2708 | |||
2709 | IPW_DEBUG_TRACE(">>\n"); | ||
2710 | |||
2711 | /* read entire contents of eeprom into private buffer */ | ||
2712 | for (i = 0; i < 128; i++) | ||
2713 | eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i)); | ||
2714 | |||
2715 | IPW_DEBUG_TRACE("<<\n"); | ||
2716 | } | ||
2717 | |||
2704 | /* | 2718 | /* |
2705 | * Either the device driver (i.e. the host) or the firmware can | 2719 | * Either the device driver (i.e. the host) or the firmware can |
2706 | * load eeprom data into the designated region in SRAM. If neither | 2720 | * load eeprom data into the designated region in SRAM. If neither |
@@ -2712,14 +2726,9 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) | |||
2712 | static void ipw_eeprom_init_sram(struct ipw_priv *priv) | 2726 | static void ipw_eeprom_init_sram(struct ipw_priv *priv) |
2713 | { | 2727 | { |
2714 | int i; | 2728 | int i; |
2715 | __le16 *eeprom = (__le16 *) priv->eeprom; | ||
2716 | 2729 | ||
2717 | IPW_DEBUG_TRACE(">>\n"); | 2730 | IPW_DEBUG_TRACE(">>\n"); |
2718 | 2731 | ||
2719 | /* read entire contents of eeprom into private buffer */ | ||
2720 | for (i = 0; i < 128; i++) | ||
2721 | eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i)); | ||
2722 | |||
2723 | /* | 2732 | /* |
2724 | If the data looks correct, then copy it to our private | 2733 | If the data looks correct, then copy it to our private |
2725 | copy. Otherwise let the firmware know to perform the operation | 2734 | copy. Otherwise let the firmware know to perform the operation |
@@ -3643,8 +3652,10 @@ static int ipw_load(struct ipw_priv *priv) | |||
3643 | /* ack fw init done interrupt */ | 3652 | /* ack fw init done interrupt */ |
3644 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); | 3653 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); |
3645 | 3654 | ||
3646 | /* read eeprom data and initialize the eeprom region of sram */ | 3655 | /* read eeprom data */ |
3647 | priv->eeprom_delay = 1; | 3656 | priv->eeprom_delay = 1; |
3657 | ipw_read_eeprom(priv); | ||
3658 | /* initialize the eeprom region of sram */ | ||
3648 | ipw_eeprom_init_sram(priv); | 3659 | ipw_eeprom_init_sram(priv); |
3649 | 3660 | ||
3650 | /* enable interrupts */ | 3661 | /* enable interrupts */ |
@@ -7069,9 +7080,7 @@ static int ipw_qos_activate(struct ipw_priv *priv, | |||
7069 | } | 7080 | } |
7070 | 7081 | ||
7071 | IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); | 7082 | IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); |
7072 | err = ipw_send_qos_params_command(priv, | 7083 | err = ipw_send_qos_params_command(priv, &qos_parameters[0]); |
7073 | (struct libipw_qos_parameters *) | ||
7074 | &(qos_parameters[0])); | ||
7075 | if (err) | 7084 | if (err) |
7076 | IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n"); | 7085 | IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n"); |
7077 | 7086 | ||
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 509301a5e7e2..d24eaf89ffb5 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -5724,7 +5724,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) | |||
5724 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); | 5724 | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); |
5725 | 5725 | ||
5726 | hw->wiphy->flags |= | 5726 | hw->wiphy->flags |= |
5727 | WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; | 5727 | WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | |
5728 | WIPHY_FLAG_IBSS_RSN; | ||
5728 | 5729 | ||
5729 | /* | 5730 | /* |
5730 | * For now, disable PS by default because it affects | 5731 | * For now, disable PS by default because it affects |
@@ -5873,6 +5874,16 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
5873 | return -EOPNOTSUPP; | 5874 | return -EOPNOTSUPP; |
5874 | } | 5875 | } |
5875 | 5876 | ||
5877 | /* | ||
5878 | * To support IBSS RSN, don't program group keys in IBSS, the | ||
5879 | * hardware will then not attempt to decrypt the frames. | ||
5880 | */ | ||
5881 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
5882 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
5883 | D_MAC80211("leave - ad-hoc group key\n"); | ||
5884 | return -EOPNOTSUPP; | ||
5885 | } | ||
5886 | |||
5876 | sta_id = il_sta_id_or_broadcast(il, sta); | 5887 | sta_id = il_sta_id_or_broadcast(il, sta); |
5877 | if (sta_id == IL_INVALID_STATION) | 5888 | if (sta_id == IL_INVALID_STATION) |
5878 | return -EINVAL; | 5889 | return -EINVAL; |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 2463c0626438..727fbb5db9da 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -6,6 +6,7 @@ config IWLWIFI | |||
6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
7 | select LEDS_TRIGGERS | 7 | select LEDS_TRIGGERS |
8 | select MAC80211_LEDS | 8 | select MAC80211_LEDS |
9 | select IWLDVM | ||
9 | ---help--- | 10 | ---help--- |
10 | Select to build the driver supporting the: | 11 | Select to build the driver supporting the: |
11 | 12 | ||
@@ -41,6 +42,10 @@ config IWLWIFI | |||
41 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 42 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
42 | module will be called iwlwifi. | 43 | module will be called iwlwifi. |
43 | 44 | ||
45 | config IWLDVM | ||
46 | tristate "Intel Wireless WiFi" | ||
47 | depends on IWLWIFI | ||
48 | |||
44 | menu "Debugging Options" | 49 | menu "Debugging Options" |
45 | depends on IWLWIFI | 50 | depends on IWLWIFI |
46 | 51 | ||
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index d615eacbf050..98c8f6449649 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,27 +1,17 @@ | |||
1 | # WIFI | 1 | obj-$(CONFIG_IWLDVM) += dvm/ |
2 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o | 2 | |
3 | iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o | 3 | CFLAGS_iwl-devtrace.o := -I$(src) |
4 | iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o | ||
5 | iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o | ||
6 | iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o | ||
7 | 4 | ||
8 | iwlwifi-objs += iwl-eeprom.o iwl-power.o | 5 | # common |
9 | iwlwifi-objs += iwl-scan.o iwl-led.o | 6 | obj-$(CONFIG_IWLWIFI) += iwlwifi.o |
10 | iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o | 7 | iwlwifi-objs += iwl-io.o |
11 | iwlwifi-objs += iwl-5000.o | ||
12 | iwlwifi-objs += iwl-6000.o | ||
13 | iwlwifi-objs += iwl-1000.o | ||
14 | iwlwifi-objs += iwl-2000.o | ||
15 | iwlwifi-objs += iwl-pci.o | ||
16 | iwlwifi-objs += iwl-drv.o | 8 | iwlwifi-objs += iwl-drv.o |
9 | iwlwifi-objs += iwl-debug.o | ||
17 | iwlwifi-objs += iwl-notif-wait.o | 10 | iwlwifi-objs += iwl-notif-wait.o |
18 | iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o | 11 | iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o |
12 | iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o | ||
13 | iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o | ||
19 | 14 | ||
20 | |||
21 | iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | ||
22 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | 15 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o |
23 | iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o | ||
24 | |||
25 | CFLAGS_iwl-devtrace.o := -I$(src) | ||
26 | 16 | ||
27 | ccflags-y += -D__CHECK_ENDIAN__ | 17 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src) |
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile new file mode 100644 index 000000000000..5ff76b204141 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # DVM | ||
2 | obj-$(CONFIG_IWLDVM) += iwldvm.o | ||
3 | iwldvm-objs += main.o rs.o mac80211.o ucode.o tx.o | ||
4 | iwldvm-objs += lib.o calib.o tt.o sta.o rx.o | ||
5 | |||
6 | iwldvm-objs += power.o | ||
7 | iwldvm-objs += scan.o led.o | ||
8 | iwldvm-objs += rxon.o devices.o | ||
9 | |||
10 | iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o | ||
11 | iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o | ||
12 | |||
13 | ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 79c0fe06f4db..2ae3608472a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -63,9 +63,10 @@ | |||
63 | #ifndef __iwl_agn_h__ | 63 | #ifndef __iwl_agn_h__ |
64 | #define __iwl_agn_h__ | 64 | #define __iwl_agn_h__ |
65 | 65 | ||
66 | #include "iwl-dev.h" | ||
67 | #include "iwl-config.h" | 66 | #include "iwl-config.h" |
68 | 67 | ||
68 | #include "dev.h" | ||
69 | |||
69 | /* The first 11 queues (0-10) are used otherwise */ | 70 | /* The first 11 queues (0-10) are used otherwise */ |
70 | #define IWLAGN_FIRST_AMPDU_QUEUE 11 | 71 | #define IWLAGN_FIRST_AMPDU_QUEUE 11 |
71 | 72 | ||
@@ -91,7 +92,6 @@ extern struct iwl_lib_ops iwl6030_lib; | |||
91 | #define STATUS_CT_KILL 1 | 92 | #define STATUS_CT_KILL 1 |
92 | #define STATUS_ALIVE 2 | 93 | #define STATUS_ALIVE 2 |
93 | #define STATUS_READY 3 | 94 | #define STATUS_READY 3 |
94 | #define STATUS_GEO_CONFIGURED 4 | ||
95 | #define STATUS_EXIT_PENDING 5 | 95 | #define STATUS_EXIT_PENDING 5 |
96 | #define STATUS_STATISTICS 6 | 96 | #define STATUS_STATISTICS 6 |
97 | #define STATUS_SCANNING 7 | 97 | #define STATUS_SCANNING 7 |
@@ -101,6 +101,7 @@ extern struct iwl_lib_ops iwl6030_lib; | |||
101 | #define STATUS_CHANNEL_SWITCH_PENDING 11 | 101 | #define STATUS_CHANNEL_SWITCH_PENDING 11 |
102 | #define STATUS_SCAN_COMPLETE 12 | 102 | #define STATUS_SCAN_COMPLETE 12 |
103 | #define STATUS_POWER_PMI 13 | 103 | #define STATUS_POWER_PMI 13 |
104 | #define STATUS_SCAN_ROC_EXPIRED 14 | ||
104 | 105 | ||
105 | struct iwl_ucode_capabilities; | 106 | struct iwl_ucode_capabilities; |
106 | 107 | ||
@@ -255,6 +256,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, | |||
255 | enum iwl_scan_type scan_type, | 256 | enum iwl_scan_type scan_type, |
256 | enum ieee80211_band band); | 257 | enum ieee80211_band band); |
257 | 258 | ||
259 | void iwl_scan_roc_expired(struct iwl_priv *priv); | ||
260 | void iwl_scan_offchannel_skb(struct iwl_priv *priv); | ||
261 | void iwl_scan_offchannel_skb_status(struct iwl_priv *priv); | ||
262 | |||
258 | /* For faster active scanning, scan will move to the next channel if fewer than | 263 | /* For faster active scanning, scan will move to the next channel if fewer than |
259 | * PLCP_QUIET_THRESH packets are heard on this channel within | 264 | * PLCP_QUIET_THRESH packets are heard on this channel within |
260 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | 265 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell |
@@ -437,10 +442,8 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
437 | 442 | ||
438 | static inline int iwl_is_ready(struct iwl_priv *priv) | 443 | static inline int iwl_is_ready(struct iwl_priv *priv) |
439 | { | 444 | { |
440 | /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are | 445 | /* The adapter is 'ready' if READY EXIT_PENDING is not set */ |
441 | * set but EXIT_PENDING is not */ | ||
442 | return test_bit(STATUS_READY, &priv->status) && | 446 | return test_bit(STATUS_READY, &priv->status) && |
443 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) && | ||
444 | !test_bit(STATUS_EXIT_PENDING, &priv->status); | 447 | !test_bit(STATUS_EXIT_PENDING, &priv->status); |
445 | } | 448 | } |
446 | 449 | ||
@@ -518,85 +521,4 @@ static inline const char *iwl_dvm_get_cmd_string(u8 cmd) | |||
518 | return s; | 521 | return s; |
519 | return "UNKNOWN"; | 522 | return "UNKNOWN"; |
520 | } | 523 | } |
521 | |||
522 | /* API method exported for mvm hybrid state */ | ||
523 | void iwl_setup_deferred_work(struct iwl_priv *priv); | ||
524 | int iwl_send_wimax_coex(struct iwl_priv *priv); | ||
525 | int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||
526 | void iwl_option_config(struct iwl_priv *priv); | ||
527 | void iwl_set_hw_params(struct iwl_priv *priv); | ||
528 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); | ||
529 | int iwl_init_drv(struct iwl_priv *priv); | ||
530 | void iwl_uninit_drv(struct iwl_priv *priv); | ||
531 | void iwl_send_bt_config(struct iwl_priv *priv); | ||
532 | void iwl_rf_kill_ct_config(struct iwl_priv *priv); | ||
533 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
534 | void iwl_teardown_interface(struct iwl_priv *priv, | ||
535 | struct ieee80211_vif *vif, | ||
536 | bool mode_change); | ||
537 | int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
538 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
539 | void iwlagn_check_needed_chains(struct iwl_priv *priv, | ||
540 | struct iwl_rxon_context *ctx, | ||
541 | struct ieee80211_bss_conf *bss_conf); | ||
542 | void iwlagn_chain_noise_reset(struct iwl_priv *priv); | ||
543 | int iwlagn_update_beacon(struct iwl_priv *priv, | ||
544 | struct ieee80211_vif *vif); | ||
545 | void iwl_tt_handler(struct iwl_priv *priv); | ||
546 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode); | ||
547 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
548 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); | ||
549 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); | ||
550 | void iwl_nic_error(struct iwl_op_mode *op_mode); | ||
551 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode); | ||
552 | void iwl_nic_config(struct iwl_op_mode *op_mode); | ||
553 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | ||
554 | struct ieee80211_sta *sta, bool set); | ||
555 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | ||
556 | enum ieee80211_rssi_event rssi_event); | ||
557 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw); | ||
558 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw); | ||
559 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop); | ||
560 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue); | ||
561 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | ||
562 | struct ieee80211_channel_switch *ch_switch); | ||
563 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | ||
564 | struct ieee80211_vif *vif, | ||
565 | struct ieee80211_sta *sta, | ||
566 | enum ieee80211_sta_state old_state, | ||
567 | enum ieee80211_sta_state new_state); | ||
568 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | ||
569 | struct ieee80211_vif *vif, | ||
570 | enum ieee80211_ampdu_mlme_action action, | ||
571 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | ||
572 | u8 buf_size); | ||
573 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | ||
574 | struct ieee80211_vif *vif, | ||
575 | struct cfg80211_scan_request *req); | ||
576 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | ||
577 | struct ieee80211_vif *vif, | ||
578 | enum sta_notify_cmd cmd, | ||
579 | struct ieee80211_sta *sta); | ||
580 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
581 | unsigned int changed_flags, | ||
582 | unsigned int *total_flags, | ||
583 | u64 multicast); | ||
584 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | ||
585 | struct ieee80211_vif *vif, u16 queue, | ||
586 | const struct ieee80211_tx_queue_params *params); | ||
587 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | ||
588 | struct ieee80211_vif *vif, | ||
589 | struct cfg80211_gtk_rekey_data *data); | ||
590 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | ||
591 | struct ieee80211_vif *vif, | ||
592 | struct ieee80211_key_conf *keyconf, | ||
593 | struct ieee80211_sta *sta, | ||
594 | u32 iv32, u16 *phase1key); | ||
595 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | ||
596 | struct ieee80211_vif *vif, | ||
597 | struct ieee80211_sta *sta, | ||
598 | struct ieee80211_key_conf *key); | ||
599 | void iwlagn_mac_stop(struct ieee80211_hw *hw); | ||
600 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
601 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); | ||
602 | #endif /* __iwl_agn_h__ */ | 524 | #endif /* __iwl_agn_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 95f27f1a423b..f2dd671d7dc8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c | |||
@@ -63,10 +63,11 @@ | |||
63 | #include <linux/slab.h> | 63 | #include <linux/slab.h> |
64 | #include <net/mac80211.h> | 64 | #include <net/mac80211.h> |
65 | 65 | ||
66 | #include "iwl-dev.h" | ||
67 | #include "iwl-agn-calib.h" | ||
68 | #include "iwl-trans.h" | 66 | #include "iwl-trans.h" |
69 | #include "iwl-agn.h" | 67 | |
68 | #include "dev.h" | ||
69 | #include "calib.h" | ||
70 | #include "agn.h" | ||
70 | 71 | ||
71 | /***************************************************************************** | 72 | /***************************************************************************** |
72 | * INIT calibrations framework | 73 | * INIT calibrations framework |
@@ -832,14 +833,14 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
832 | * To be safe, simply mask out any chains that we know | 833 | * To be safe, simply mask out any chains that we know |
833 | * are not on the device. | 834 | * are not on the device. |
834 | */ | 835 | */ |
835 | active_chains &= priv->hw_params.valid_rx_ant; | 836 | active_chains &= priv->eeprom_data->valid_rx_ant; |
836 | 837 | ||
837 | num_tx_chains = 0; | 838 | num_tx_chains = 0; |
838 | for (i = 0; i < NUM_RX_CHAINS; i++) { | 839 | for (i = 0; i < NUM_RX_CHAINS; i++) { |
839 | /* loops on all the bits of | 840 | /* loops on all the bits of |
840 | * priv->hw_setting.valid_tx_ant */ | 841 | * priv->hw_setting.valid_tx_ant */ |
841 | u8 ant_msk = (1 << i); | 842 | u8 ant_msk = (1 << i); |
842 | if (!(priv->hw_params.valid_tx_ant & ant_msk)) | 843 | if (!(priv->eeprom_data->valid_tx_ant & ant_msk)) |
843 | continue; | 844 | continue; |
844 | 845 | ||
845 | num_tx_chains++; | 846 | num_tx_chains++; |
@@ -853,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
853 | * connect the first valid tx chain | 854 | * connect the first valid tx chain |
854 | */ | 855 | */ |
855 | first_chain = | 856 | first_chain = |
856 | find_first_chain(priv->hw_params.valid_tx_ant); | 857 | find_first_chain(priv->eeprom_data->valid_tx_ant); |
857 | data->disconn_array[first_chain] = 0; | 858 | data->disconn_array[first_chain] = 0; |
858 | active_chains |= BIT(first_chain); | 859 | active_chains |= BIT(first_chain); |
859 | IWL_DEBUG_CALIB(priv, | 860 | IWL_DEBUG_CALIB(priv, |
@@ -863,13 +864,13 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, | |||
863 | } | 864 | } |
864 | } | 865 | } |
865 | 866 | ||
866 | if (active_chains != priv->hw_params.valid_rx_ant && | 867 | if (active_chains != priv->eeprom_data->valid_rx_ant && |
867 | active_chains != priv->chain_noise_data.active_chains) | 868 | active_chains != priv->chain_noise_data.active_chains) |
868 | IWL_DEBUG_CALIB(priv, | 869 | IWL_DEBUG_CALIB(priv, |
869 | "Detected that not all antennas are connected! " | 870 | "Detected that not all antennas are connected! " |
870 | "Connected: %#x, valid: %#x.\n", | 871 | "Connected: %#x, valid: %#x.\n", |
871 | active_chains, | 872 | active_chains, |
872 | priv->hw_params.valid_rx_ant); | 873 | priv->eeprom_data->valid_rx_ant); |
873 | 874 | ||
874 | /* Save for use within RXON, TX, SCAN commands, etc. */ | 875 | /* Save for use within RXON, TX, SCAN commands, etc. */ |
875 | data->active_chains = active_chains; | 876 | data->active_chains = active_chains; |
@@ -1054,7 +1055,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1054 | priv->cfg->bt_params->advanced_bt_coexist) { | 1055 | priv->cfg->bt_params->advanced_bt_coexist) { |
1055 | /* Disable disconnected antenna algorithm for advanced | 1056 | /* Disable disconnected antenna algorithm for advanced |
1056 | bt coex, assuming valid antennas are connected */ | 1057 | bt coex, assuming valid antennas are connected */ |
1057 | data->active_chains = priv->hw_params.valid_rx_ant; | 1058 | data->active_chains = priv->eeprom_data->valid_rx_ant; |
1058 | for (i = 0; i < NUM_RX_CHAINS; i++) | 1059 | for (i = 0; i < NUM_RX_CHAINS; i++) |
1059 | if (!(data->active_chains & (1<<i))) | 1060 | if (!(data->active_chains & (1<<i))) |
1060 | data->disconn_array[i] = 1; | 1061 | data->disconn_array[i] = 1; |
@@ -1083,8 +1084,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) | |||
1083 | IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", | 1084 | IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n", |
1084 | min_average_noise, min_average_noise_antenna_i); | 1085 | min_average_noise, min_average_noise_antenna_i); |
1085 | 1086 | ||
1086 | iwlagn_gain_computation(priv, average_noise, | 1087 | iwlagn_gain_computation( |
1087 | find_first_chain(priv->hw_params.valid_rx_ant)); | 1088 | priv, average_noise, |
1089 | find_first_chain(priv->eeprom_data->valid_rx_ant)); | ||
1088 | 1090 | ||
1089 | /* Some power changes may have been made during the calibration. | 1091 | /* Some power changes may have been made during the calibration. |
1090 | * Update and commit the RXON | 1092 | * Update and commit the RXON |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index dbe13787f272..2349f393cc42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h | |||
@@ -62,8 +62,8 @@ | |||
62 | #ifndef __iwl_calib_h__ | 62 | #ifndef __iwl_calib_h__ |
63 | #define __iwl_calib_h__ | 63 | #define __iwl_calib_h__ |
64 | 64 | ||
65 | #include "iwl-dev.h" | 65 | #include "dev.h" |
66 | #include "iwl-commands.h" | 66 | #include "commands.h" |
67 | 67 | ||
68 | void iwl_chain_noise_calibration(struct iwl_priv *priv); | 68 | void iwl_chain_noise_calibration(struct iwl_priv *priv); |
69 | void iwl_sensitivity_calibration(struct iwl_priv *priv); | 69 | void iwl_sensitivity_calibration(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 9af6a239b384..64811cd91635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -61,9 +61,9 @@ | |||
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | /* | 63 | /* |
64 | * Please use this file (iwl-commands.h) only for uCode API definitions. | 64 | * Please use this file (commands.h) only for uCode API definitions. |
65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. | 65 | * Please use iwl-xxxx-hw.h for hardware-related definitions. |
66 | * Please use iwl-dev.h for driver implementation definitions. | 66 | * Please use dev.h for driver implementation definitions. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | #ifndef __iwl_commands_h__ | 69 | #ifndef __iwl_commands_h__ |
@@ -197,9 +197,6 @@ enum { | |||
197 | * | 197 | * |
198 | *****************************************************************************/ | 198 | *****************************************************************************/ |
199 | 199 | ||
200 | /* iwl_cmd_header flags value */ | ||
201 | #define IWL_CMD_FAILED_MSK 0x40 | ||
202 | |||
203 | /** | 200 | /** |
204 | * iwlagn rate_n_flags bit fields | 201 | * iwlagn rate_n_flags bit fields |
205 | * | 202 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index e7c157e5ebeb..8a2d9e643b14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -30,16 +30,12 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
33 | |||
34 | #include <linux/ieee80211.h> | 33 | #include <linux/ieee80211.h> |
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | |||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-debug.h" | 35 | #include "iwl-debug.h" |
40 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
41 | #include "iwl-agn.h" | 37 | #include "dev.h" |
42 | #include "iwl-modparams.h" | 38 | #include "agn.h" |
43 | 39 | ||
44 | /* create and remove of files */ | 40 | /* create and remove of files */ |
45 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ | 41 | #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ |
@@ -307,13 +303,13 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
307 | const u8 *ptr; | 303 | const u8 *ptr; |
308 | char *buf; | 304 | char *buf; |
309 | u16 eeprom_ver; | 305 | u16 eeprom_ver; |
310 | size_t eeprom_len = priv->cfg->base_params->eeprom_size; | 306 | size_t eeprom_len = priv->eeprom_blob_size; |
311 | buf_size = 4 * eeprom_len + 256; | 307 | buf_size = 4 * eeprom_len + 256; |
312 | 308 | ||
313 | if (eeprom_len % 16) | 309 | if (eeprom_len % 16) |
314 | return -ENODATA; | 310 | return -ENODATA; |
315 | 311 | ||
316 | ptr = priv->eeprom; | 312 | ptr = priv->eeprom_blob; |
317 | if (!ptr) | 313 | if (!ptr) |
318 | return -ENOMEM; | 314 | return -ENOMEM; |
319 | 315 | ||
@@ -322,11 +318,9 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, | |||
322 | if (!buf) | 318 | if (!buf) |
323 | return -ENOMEM; | 319 | return -ENOMEM; |
324 | 320 | ||
325 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | 321 | eeprom_ver = priv->eeprom_data->eeprom_version; |
326 | pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " | 322 | pos += scnprintf(buf + pos, buf_size - pos, |
327 | "version: 0x%x\n", | 323 | "NVM version: 0x%x\n", eeprom_ver); |
328 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
329 | ? "OTP" : "EEPROM", eeprom_ver); | ||
330 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { | 324 | for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { |
331 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); | 325 | pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); |
332 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, | 326 | hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, |
@@ -351,9 +345,6 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, | |||
351 | char *buf; | 345 | char *buf; |
352 | ssize_t ret; | 346 | ssize_t ret; |
353 | 347 | ||
354 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
355 | return -EAGAIN; | ||
356 | |||
357 | buf = kzalloc(bufsz, GFP_KERNEL); | 348 | buf = kzalloc(bufsz, GFP_KERNEL); |
358 | if (!buf) | 349 | if (!buf) |
359 | return -ENOMEM; | 350 | return -ENOMEM; |
@@ -426,8 +417,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
426 | test_bit(STATUS_ALIVE, &priv->status)); | 417 | test_bit(STATUS_ALIVE, &priv->status)); |
427 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", | 418 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", |
428 | test_bit(STATUS_READY, &priv->status)); | 419 | test_bit(STATUS_READY, &priv->status)); |
429 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", | ||
430 | test_bit(STATUS_GEO_CONFIGURED, &priv->status)); | ||
431 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", | 420 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", |
432 | test_bit(STATUS_EXIT_PENDING, &priv->status)); | 421 | test_bit(STATUS_EXIT_PENDING, &priv->status)); |
433 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", | 422 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", |
@@ -1341,17 +1330,17 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, | |||
1341 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { | 1330 | if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { |
1342 | pos += scnprintf(buf + pos, bufsz - pos, | 1331 | pos += scnprintf(buf + pos, bufsz - pos, |
1343 | "tx power: (1/2 dB step)\n"); | 1332 | "tx power: (1/2 dB step)\n"); |
1344 | if ((priv->hw_params.valid_tx_ant & ANT_A) && | 1333 | if ((priv->eeprom_data->valid_tx_ant & ANT_A) && |
1345 | tx->tx_power.ant_a) | 1334 | tx->tx_power.ant_a) |
1346 | pos += scnprintf(buf + pos, bufsz - pos, | 1335 | pos += scnprintf(buf + pos, bufsz - pos, |
1347 | fmt_hex, "antenna A:", | 1336 | fmt_hex, "antenna A:", |
1348 | tx->tx_power.ant_a); | 1337 | tx->tx_power.ant_a); |
1349 | if ((priv->hw_params.valid_tx_ant & ANT_B) && | 1338 | if ((priv->eeprom_data->valid_tx_ant & ANT_B) && |
1350 | tx->tx_power.ant_b) | 1339 | tx->tx_power.ant_b) |
1351 | pos += scnprintf(buf + pos, bufsz - pos, | 1340 | pos += scnprintf(buf + pos, bufsz - pos, |
1352 | fmt_hex, "antenna B:", | 1341 | fmt_hex, "antenna B:", |
1353 | tx->tx_power.ant_b); | 1342 | tx->tx_power.ant_b); |
1354 | if ((priv->hw_params.valid_tx_ant & ANT_C) && | 1343 | if ((priv->eeprom_data->valid_tx_ant & ANT_C) && |
1355 | tx->tx_power.ant_c) | 1344 | tx->tx_power.ant_c) |
1356 | pos += scnprintf(buf + pos, bufsz - pos, | 1345 | pos += scnprintf(buf + pos, bufsz - pos, |
1357 | fmt_hex, "antenna C:", | 1346 | fmt_hex, "antenna C:", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 70062379d0ec..89f2e1040e7f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h | |||
@@ -24,8 +24,8 @@ | |||
24 | * | 24 | * |
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | /* | 26 | /* |
27 | * Please use this file (iwl-dev.h) for driver implementation definitions. | 27 | * Please use this file (dev.h) for driver implementation definitions. |
28 | * Please use iwl-commands.h for uCode API definitions. | 28 | * Please use commands.h for uCode API definitions. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #ifndef __iwl_dev_h__ | 31 | #ifndef __iwl_dev_h__ |
@@ -39,17 +39,18 @@ | |||
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | 40 | ||
41 | #include "iwl-fw.h" | 41 | #include "iwl-fw.h" |
42 | #include "iwl-eeprom.h" | 42 | #include "iwl-eeprom-parse.h" |
43 | #include "iwl-csr.h" | 43 | #include "iwl-csr.h" |
44 | #include "iwl-debug.h" | 44 | #include "iwl-debug.h" |
45 | #include "iwl-agn-hw.h" | 45 | #include "iwl-agn-hw.h" |
46 | #include "iwl-led.h" | ||
47 | #include "iwl-power.h" | ||
48 | #include "iwl-agn-rs.h" | ||
49 | #include "iwl-agn-tt.h" | ||
50 | #include "iwl-trans.h" | ||
51 | #include "iwl-op-mode.h" | 46 | #include "iwl-op-mode.h" |
52 | #include "iwl-notif-wait.h" | 47 | #include "iwl-notif-wait.h" |
48 | #include "iwl-trans.h" | ||
49 | |||
50 | #include "led.h" | ||
51 | #include "power.h" | ||
52 | #include "rs.h" | ||
53 | #include "tt.h" | ||
53 | 54 | ||
54 | /* CT-KILL constants */ | 55 | /* CT-KILL constants */ |
55 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ | 56 | #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ |
@@ -88,33 +89,6 @@ | |||
88 | #define IWL_NUM_SCAN_RATES (2) | 89 | #define IWL_NUM_SCAN_RATES (2) |
89 | 90 | ||
90 | /* | 91 | /* |
91 | * One for each channel, holds all channel setup data | ||
92 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant | ||
93 | * with one another! | ||
94 | */ | ||
95 | struct iwl_channel_info { | ||
96 | struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ | ||
97 | struct iwl_eeprom_channel ht40_eeprom; /* EEPROM regulatory limit for | ||
98 | * HT40 channel */ | ||
99 | |||
100 | u8 channel; /* channel number */ | ||
101 | u8 flags; /* flags copied from EEPROM */ | ||
102 | s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | ||
103 | s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) limit */ | ||
104 | s8 min_power; /* always 0 */ | ||
105 | s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ | ||
106 | |||
107 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | ||
108 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | ||
109 | enum ieee80211_band band; | ||
110 | |||
111 | /* HT40 channel info */ | ||
112 | s8 ht40_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | ||
113 | u8 ht40_flags; /* flags copied from EEPROM */ | ||
114 | u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */ | ||
115 | }; | ||
116 | |||
117 | /* | ||
118 | * Minimum number of queues. MAX_NUM is defined in hw specific files. | 92 | * Minimum number of queues. MAX_NUM is defined in hw specific files. |
119 | * Set the minimum to accommodate | 93 | * Set the minimum to accommodate |
120 | * - 4 standard TX queues | 94 | * - 4 standard TX queues |
@@ -153,29 +127,6 @@ union iwl_ht_rate_supp { | |||
153 | }; | 127 | }; |
154 | }; | 128 | }; |
155 | 129 | ||
156 | #define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) | ||
157 | #define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) | ||
158 | #define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) | ||
159 | #define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) | ||
160 | #define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K | ||
161 | #define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K | ||
162 | #define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K | ||
163 | |||
164 | /* | ||
165 | * Maximal MPDU density for TX aggregation | ||
166 | * 4 - 2us density | ||
167 | * 5 - 4us density | ||
168 | * 6 - 8us density | ||
169 | * 7 - 16us density | ||
170 | */ | ||
171 | #define CFG_HT_MPDU_DENSITY_2USEC (0x4) | ||
172 | #define CFG_HT_MPDU_DENSITY_4USEC (0x5) | ||
173 | #define CFG_HT_MPDU_DENSITY_8USEC (0x6) | ||
174 | #define CFG_HT_MPDU_DENSITY_16USEC (0x7) | ||
175 | #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC | ||
176 | #define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC | ||
177 | #define CFG_HT_MPDU_DENSITY_MIN (0x1) | ||
178 | |||
179 | struct iwl_ht_config { | 130 | struct iwl_ht_config { |
180 | bool single_chain_sufficient; | 131 | bool single_chain_sufficient; |
181 | enum ieee80211_smps_mode smps; /* current smps mode */ | 132 | enum ieee80211_smps_mode smps; /* current smps mode */ |
@@ -445,23 +396,6 @@ enum { | |||
445 | MEASUREMENT_ACTIVE = (1 << 1), | 396 | MEASUREMENT_ACTIVE = (1 << 1), |
446 | }; | 397 | }; |
447 | 398 | ||
448 | enum iwl_nvm_type { | ||
449 | NVM_DEVICE_TYPE_EEPROM = 0, | ||
450 | NVM_DEVICE_TYPE_OTP, | ||
451 | }; | ||
452 | |||
453 | /* | ||
454 | * Two types of OTP memory access modes | ||
455 | * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode, | ||
456 | * based on physical memory addressing | ||
457 | * IWL_OTP_ACCESS_RELATIVE - relative address mode, | ||
458 | * based on logical memory addressing | ||
459 | */ | ||
460 | enum iwl_access_mode { | ||
461 | IWL_OTP_ACCESS_ABSOLUTE, | ||
462 | IWL_OTP_ACCESS_RELATIVE, | ||
463 | }; | ||
464 | |||
465 | /* reply_tx_statistics (for _agn devices) */ | 399 | /* reply_tx_statistics (for _agn devices) */ |
466 | struct reply_tx_error_statistics { | 400 | struct reply_tx_error_statistics { |
467 | u32 pp_delay; | 401 | u32 pp_delay; |
@@ -632,9 +566,6 @@ enum iwl_scan_type { | |||
632 | * | 566 | * |
633 | * @tx_chains_num: Number of TX chains | 567 | * @tx_chains_num: Number of TX chains |
634 | * @rx_chains_num: Number of RX chains | 568 | * @rx_chains_num: Number of RX chains |
635 | * @valid_tx_ant: usable antennas for TX | ||
636 | * @valid_rx_ant: usable antennas for RX | ||
637 | * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) | ||
638 | * @sku: sku read from EEPROM | 569 | * @sku: sku read from EEPROM |
639 | * @ct_kill_threshold: temperature threshold - in hw dependent unit | 570 | * @ct_kill_threshold: temperature threshold - in hw dependent unit |
640 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit | 571 | * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit |
@@ -645,9 +576,6 @@ enum iwl_scan_type { | |||
645 | struct iwl_hw_params { | 576 | struct iwl_hw_params { |
646 | u8 tx_chains_num; | 577 | u8 tx_chains_num; |
647 | u8 rx_chains_num; | 578 | u8 rx_chains_num; |
648 | u8 valid_tx_ant; | ||
649 | u8 valid_rx_ant; | ||
650 | u8 ht40_channel; | ||
651 | bool use_rts_for_aggregation; | 579 | bool use_rts_for_aggregation; |
652 | u16 sku; | 580 | u16 sku; |
653 | u32 ct_kill_threshold; | 581 | u32 ct_kill_threshold; |
@@ -664,9 +592,6 @@ struct iwl_lib_ops { | |||
664 | /* device specific configuration */ | 592 | /* device specific configuration */ |
665 | void (*nic_config)(struct iwl_priv *priv); | 593 | void (*nic_config)(struct iwl_priv *priv); |
666 | 594 | ||
667 | /* eeprom operations (as defined in iwl-eeprom.h) */ | ||
668 | struct iwl_eeprom_ops eeprom_ops; | ||
669 | |||
670 | /* temperature */ | 595 | /* temperature */ |
671 | void (*temperature)(struct iwl_priv *priv); | 596 | void (*temperature)(struct iwl_priv *priv); |
672 | }; | 597 | }; |
@@ -735,8 +660,6 @@ struct iwl_priv { | |||
735 | 660 | ||
736 | /* ieee device used by generic ieee processing code */ | 661 | /* ieee device used by generic ieee processing code */ |
737 | struct ieee80211_hw *hw; | 662 | struct ieee80211_hw *hw; |
738 | struct ieee80211_channel *ieee_channels; | ||
739 | struct ieee80211_rate *ieee_rates; | ||
740 | 663 | ||
741 | struct list_head calib_results; | 664 | struct list_head calib_results; |
742 | 665 | ||
@@ -755,8 +678,6 @@ struct iwl_priv { | |||
755 | 678 | ||
756 | struct iwl_notif_wait_data notif_wait; | 679 | struct iwl_notif_wait_data notif_wait; |
757 | 680 | ||
758 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | ||
759 | |||
760 | /* spectrum measurement report caching */ | 681 | /* spectrum measurement report caching */ |
761 | struct iwl_spectrum_notification measure_report; | 682 | struct iwl_spectrum_notification measure_report; |
762 | u8 measurement_status; | 683 | u8 measurement_status; |
@@ -787,11 +708,6 @@ struct iwl_priv { | |||
787 | bool ucode_loaded; | 708 | bool ucode_loaded; |
788 | bool init_ucode_run; /* Don't run init uCode again */ | 709 | bool init_ucode_run; /* Don't run init uCode again */ |
789 | 710 | ||
790 | /* we allocate array of iwl_channel_info for NIC's valid channels. | ||
791 | * Access via channel # using indirect index array */ | ||
792 | struct iwl_channel_info *channel_info; /* channel info array */ | ||
793 | u8 channel_count; /* # of channels */ | ||
794 | |||
795 | u8 plcp_delta_threshold; | 711 | u8 plcp_delta_threshold; |
796 | 712 | ||
797 | /* thermal calibration */ | 713 | /* thermal calibration */ |
@@ -846,6 +762,7 @@ struct iwl_priv { | |||
846 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; | 762 | struct iwl_station_entry stations[IWLAGN_STATION_COUNT]; |
847 | unsigned long ucode_key_table; | 763 | unsigned long ucode_key_table; |
848 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; | 764 | struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT]; |
765 | atomic_t num_aux_in_flight; | ||
849 | 766 | ||
850 | u8 mac80211_registered; | 767 | u8 mac80211_registered; |
851 | 768 | ||
@@ -950,10 +867,8 @@ struct iwl_priv { | |||
950 | 867 | ||
951 | struct delayed_work scan_check; | 868 | struct delayed_work scan_check; |
952 | 869 | ||
953 | /* TX Power */ | 870 | /* TX Power settings */ |
954 | s8 tx_power_user_lmt; | 871 | s8 tx_power_user_lmt; |
955 | s8 tx_power_device_lmt; | ||
956 | s8 tx_power_lmt_in_half_dbm; /* max tx power in half-dBm format */ | ||
957 | s8 tx_power_next; | 872 | s8 tx_power_next; |
958 | 873 | ||
959 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 874 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -964,9 +879,10 @@ struct iwl_priv { | |||
964 | void *wowlan_sram; | 879 | void *wowlan_sram; |
965 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ | 880 | #endif /* CONFIG_IWLWIFI_DEBUGFS */ |
966 | 881 | ||
967 | /* eeprom -- this is in the card's little endian byte order */ | 882 | struct iwl_eeprom_data *eeprom_data; |
968 | u8 *eeprom; | 883 | /* eeprom blob for debugfs/testmode */ |
969 | enum iwl_nvm_type nvm_device_type; | 884 | u8 *eeprom_blob; |
885 | size_t eeprom_blob_size; | ||
970 | 886 | ||
971 | struct work_struct txpower_work; | 887 | struct work_struct txpower_work; |
972 | u32 calib_disabled; | 888 | u32 calib_disabled; |
@@ -1001,8 +917,6 @@ struct iwl_priv { | |||
1001 | enum iwl_ucode_type cur_ucode; | 917 | enum iwl_ucode_type cur_ucode; |
1002 | }; /*iwl_priv */ | 918 | }; /*iwl_priv */ |
1003 | 919 | ||
1004 | extern struct kmem_cache *iwl_tx_cmd_pool; | ||
1005 | |||
1006 | static inline struct iwl_rxon_context * | 920 | static inline struct iwl_rxon_context * |
1007 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) | 921 | iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) |
1008 | { | 922 | { |
@@ -1036,36 +950,4 @@ static inline int iwl_is_any_associated(struct iwl_priv *priv) | |||
1036 | return false; | 950 | return false; |
1037 | } | 951 | } |
1038 | 952 | ||
1039 | static inline int is_channel_valid(const struct iwl_channel_info *ch_info) | ||
1040 | { | ||
1041 | if (ch_info == NULL) | ||
1042 | return 0; | ||
1043 | return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; | ||
1044 | } | ||
1045 | |||
1046 | static inline int is_channel_radar(const struct iwl_channel_info *ch_info) | ||
1047 | { | ||
1048 | return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; | ||
1049 | } | ||
1050 | |||
1051 | static inline u8 is_channel_a_band(const struct iwl_channel_info *ch_info) | ||
1052 | { | ||
1053 | return ch_info->band == IEEE80211_BAND_5GHZ; | ||
1054 | } | ||
1055 | |||
1056 | static inline u8 is_channel_bg_band(const struct iwl_channel_info *ch_info) | ||
1057 | { | ||
1058 | return ch_info->band == IEEE80211_BAND_2GHZ; | ||
1059 | } | ||
1060 | |||
1061 | static inline int is_channel_passive(const struct iwl_channel_info *ch) | ||
1062 | { | ||
1063 | return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; | ||
1064 | } | ||
1065 | |||
1066 | static inline int is_channel_ibss(const struct iwl_channel_info *ch) | ||
1067 | { | ||
1068 | return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; | ||
1069 | } | ||
1070 | |||
1071 | #endif /* __iwl_dev_h__ */ | 953 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index 48533b3a0f9a..0521a6be09d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c | |||
@@ -27,11 +27,14 @@ | |||
27 | /* | 27 | /* |
28 | * DVM device-specific data & functions | 28 | * DVM device-specific data & functions |
29 | */ | 29 | */ |
30 | #include "iwl-agn.h" | ||
31 | #include "iwl-dev.h" | ||
32 | #include "iwl-commands.h" | ||
33 | #include "iwl-io.h" | 30 | #include "iwl-io.h" |
34 | #include "iwl-prph.h" | 31 | #include "iwl-prph.h" |
32 | #include "iwl-eeprom-parse.h" | ||
33 | |||
34 | #include "agn.h" | ||
35 | #include "dev.h" | ||
36 | #include "commands.h" | ||
37 | |||
35 | 38 | ||
36 | /* | 39 | /* |
37 | * 1000 series | 40 | * 1000 series |
@@ -58,11 +61,6 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) | |||
58 | /* NIC configuration for 1000 series */ | 61 | /* NIC configuration for 1000 series */ |
59 | static void iwl1000_nic_config(struct iwl_priv *priv) | 62 | static void iwl1000_nic_config(struct iwl_priv *priv) |
60 | { | 63 | { |
61 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
62 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
63 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
64 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
65 | |||
66 | /* Setting digital SVR for 1000 card to 1.32V */ | 64 | /* Setting digital SVR for 1000 card to 1.32V */ |
67 | /* locking is acquired in iwl_set_bits_mask_prph() function */ | 65 | /* locking is acquired in iwl_set_bits_mask_prph() function */ |
68 | iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, | 66 | iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG, |
@@ -170,16 +168,6 @@ static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
170 | 168 | ||
171 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | 169 | static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) |
172 | { | 170 | { |
173 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
174 | |||
175 | priv->hw_params.tx_chains_num = | ||
176 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
177 | if (priv->cfg->rx_with_siso_diversity) | ||
178 | priv->hw_params.rx_chains_num = 1; | ||
179 | else | ||
180 | priv->hw_params.rx_chains_num = | ||
181 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
182 | |||
183 | iwl1000_set_ct_threshold(priv); | 171 | iwl1000_set_ct_threshold(priv); |
184 | 172 | ||
185 | /* Set initial sensitivity parameters */ | 173 | /* Set initial sensitivity parameters */ |
@@ -189,17 +177,6 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) | |||
189 | struct iwl_lib_ops iwl1000_lib = { | 177 | struct iwl_lib_ops iwl1000_lib = { |
190 | .set_hw_params = iwl1000_hw_set_hw_params, | 178 | .set_hw_params = iwl1000_hw_set_hw_params, |
191 | .nic_config = iwl1000_nic_config, | 179 | .nic_config = iwl1000_nic_config, |
192 | .eeprom_ops = { | ||
193 | .regulatory_bands = { | ||
194 | EEPROM_REG_BAND_1_CHANNELS, | ||
195 | EEPROM_REG_BAND_2_CHANNELS, | ||
196 | EEPROM_REG_BAND_3_CHANNELS, | ||
197 | EEPROM_REG_BAND_4_CHANNELS, | ||
198 | EEPROM_REG_BAND_5_CHANNELS, | ||
199 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
200 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
201 | }, | ||
202 | }, | ||
203 | .temperature = iwlagn_temperature, | 180 | .temperature = iwlagn_temperature, |
204 | }; | 181 | }; |
205 | 182 | ||
@@ -219,8 +196,6 @@ static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | |||
219 | /* NIC configuration for 2000 series */ | 196 | /* NIC configuration for 2000 series */ |
220 | static void iwl2000_nic_config(struct iwl_priv *priv) | 197 | static void iwl2000_nic_config(struct iwl_priv *priv) |
221 | { | 198 | { |
222 | iwl_rf_config(priv); | ||
223 | |||
224 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 199 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
225 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); | 200 | CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); |
226 | } | 201 | } |
@@ -251,16 +226,6 @@ static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
251 | 226 | ||
252 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | 227 | static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) |
253 | { | 228 | { |
254 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ); | ||
255 | |||
256 | priv->hw_params.tx_chains_num = | ||
257 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
258 | if (priv->cfg->rx_with_siso_diversity) | ||
259 | priv->hw_params.rx_chains_num = 1; | ||
260 | else | ||
261 | priv->hw_params.rx_chains_num = | ||
262 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
263 | |||
264 | iwl2000_set_ct_threshold(priv); | 229 | iwl2000_set_ct_threshold(priv); |
265 | 230 | ||
266 | /* Set initial sensitivity parameters */ | 231 | /* Set initial sensitivity parameters */ |
@@ -270,36 +235,12 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
270 | struct iwl_lib_ops iwl2000_lib = { | 235 | struct iwl_lib_ops iwl2000_lib = { |
271 | .set_hw_params = iwl2000_hw_set_hw_params, | 236 | .set_hw_params = iwl2000_hw_set_hw_params, |
272 | .nic_config = iwl2000_nic_config, | 237 | .nic_config = iwl2000_nic_config, |
273 | .eeprom_ops = { | ||
274 | .regulatory_bands = { | ||
275 | EEPROM_REG_BAND_1_CHANNELS, | ||
276 | EEPROM_REG_BAND_2_CHANNELS, | ||
277 | EEPROM_REG_BAND_3_CHANNELS, | ||
278 | EEPROM_REG_BAND_4_CHANNELS, | ||
279 | EEPROM_REG_BAND_5_CHANNELS, | ||
280 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
281 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
282 | }, | ||
283 | .enhanced_txpower = true, | ||
284 | }, | ||
285 | .temperature = iwlagn_temperature, | 238 | .temperature = iwlagn_temperature, |
286 | }; | 239 | }; |
287 | 240 | ||
288 | struct iwl_lib_ops iwl2030_lib = { | 241 | struct iwl_lib_ops iwl2030_lib = { |
289 | .set_hw_params = iwl2000_hw_set_hw_params, | 242 | .set_hw_params = iwl2000_hw_set_hw_params, |
290 | .nic_config = iwl2000_nic_config, | 243 | .nic_config = iwl2000_nic_config, |
291 | .eeprom_ops = { | ||
292 | .regulatory_bands = { | ||
293 | EEPROM_REG_BAND_1_CHANNELS, | ||
294 | EEPROM_REG_BAND_2_CHANNELS, | ||
295 | EEPROM_REG_BAND_3_CHANNELS, | ||
296 | EEPROM_REG_BAND_4_CHANNELS, | ||
297 | EEPROM_REG_BAND_5_CHANNELS, | ||
298 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
299 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
300 | }, | ||
301 | .enhanced_txpower = true, | ||
302 | }, | ||
303 | .temperature = iwlagn_temperature, | 244 | .temperature = iwlagn_temperature, |
304 | }; | 245 | }; |
305 | 246 | ||
@@ -311,8 +252,6 @@ struct iwl_lib_ops iwl2030_lib = { | |||
311 | /* NIC configuration for 5000 series */ | 252 | /* NIC configuration for 5000 series */ |
312 | static void iwl5000_nic_config(struct iwl_priv *priv) | 253 | static void iwl5000_nic_config(struct iwl_priv *priv) |
313 | { | 254 | { |
314 | iwl_rf_config(priv); | ||
315 | |||
316 | /* W/A : NIC is stuck in a reset state after Early PCIe power off | 255 | /* W/A : NIC is stuck in a reset state after Early PCIe power off |
317 | * (PCIe power is lost before PERST# is asserted), | 256 | * (PCIe power is lost before PERST# is asserted), |
318 | * causing ME FW to lose ownership and not being able to obtain it back. | 257 | * causing ME FW to lose ownership and not being able to obtain it back. |
@@ -376,11 +315,9 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = { | |||
376 | static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) | 315 | static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv) |
377 | { | 316 | { |
378 | u16 temperature, voltage; | 317 | u16 temperature, voltage; |
379 | __le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv, | ||
380 | EEPROM_KELVIN_TEMPERATURE); | ||
381 | 318 | ||
382 | temperature = le16_to_cpu(temp_calib[0]); | 319 | temperature = le16_to_cpu(priv->eeprom_data->kelvin_temperature); |
383 | voltage = le16_to_cpu(temp_calib[1]); | 320 | voltage = le16_to_cpu(priv->eeprom_data->kelvin_voltage); |
384 | 321 | ||
385 | /* offset = temp - volt / coeff */ | 322 | /* offset = temp - volt / coeff */ |
386 | return (s32)(temperature - | 323 | return (s32)(temperature - |
@@ -404,14 +341,6 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
404 | 341 | ||
405 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 342 | static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) |
406 | { | 343 | { |
407 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
408 | BIT(IEEE80211_BAND_5GHZ); | ||
409 | |||
410 | priv->hw_params.tx_chains_num = | ||
411 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
412 | priv->hw_params.rx_chains_num = | ||
413 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
414 | |||
415 | iwl5000_set_ct_threshold(priv); | 344 | iwl5000_set_ct_threshold(priv); |
416 | 345 | ||
417 | /* Set initial sensitivity parameters */ | 346 | /* Set initial sensitivity parameters */ |
@@ -420,14 +349,6 @@ static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
420 | 349 | ||
421 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) | 350 | static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) |
422 | { | 351 | { |
423 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
424 | BIT(IEEE80211_BAND_5GHZ); | ||
425 | |||
426 | priv->hw_params.tx_chains_num = | ||
427 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
428 | priv->hw_params.rx_chains_num = | ||
429 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
430 | |||
431 | iwl5150_set_ct_threshold(priv); | 352 | iwl5150_set_ct_threshold(priv); |
432 | 353 | ||
433 | /* Set initial sensitivity parameters */ | 354 | /* Set initial sensitivity parameters */ |
@@ -455,7 +376,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
455 | */ | 376 | */ |
456 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 377 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
457 | struct iwl5000_channel_switch_cmd cmd; | 378 | struct iwl5000_channel_switch_cmd cmd; |
458 | const struct iwl_channel_info *ch_info; | ||
459 | u32 switch_time_in_usec, ucode_switch_time; | 379 | u32 switch_time_in_usec, ucode_switch_time; |
460 | u16 ch; | 380 | u16 ch; |
461 | u32 tsf_low; | 381 | u32 tsf_low; |
@@ -505,14 +425,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
505 | } | 425 | } |
506 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 426 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
507 | cmd.switch_time); | 427 | cmd.switch_time); |
508 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | 428 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
509 | if (ch_info) | ||
510 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
511 | else { | ||
512 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
513 | ctx->active.channel, ch); | ||
514 | return -EFAULT; | ||
515 | } | ||
516 | 429 | ||
517 | return iwl_dvm_send_cmd(priv, &hcmd); | 430 | return iwl_dvm_send_cmd(priv, &hcmd); |
518 | } | 431 | } |
@@ -521,17 +434,6 @@ struct iwl_lib_ops iwl5000_lib = { | |||
521 | .set_hw_params = iwl5000_hw_set_hw_params, | 434 | .set_hw_params = iwl5000_hw_set_hw_params, |
522 | .set_channel_switch = iwl5000_hw_channel_switch, | 435 | .set_channel_switch = iwl5000_hw_channel_switch, |
523 | .nic_config = iwl5000_nic_config, | 436 | .nic_config = iwl5000_nic_config, |
524 | .eeprom_ops = { | ||
525 | .regulatory_bands = { | ||
526 | EEPROM_REG_BAND_1_CHANNELS, | ||
527 | EEPROM_REG_BAND_2_CHANNELS, | ||
528 | EEPROM_REG_BAND_3_CHANNELS, | ||
529 | EEPROM_REG_BAND_4_CHANNELS, | ||
530 | EEPROM_REG_BAND_5_CHANNELS, | ||
531 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
532 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
533 | }, | ||
534 | }, | ||
535 | .temperature = iwlagn_temperature, | 437 | .temperature = iwlagn_temperature, |
536 | }; | 438 | }; |
537 | 439 | ||
@@ -539,17 +441,6 @@ struct iwl_lib_ops iwl5150_lib = { | |||
539 | .set_hw_params = iwl5150_hw_set_hw_params, | 441 | .set_hw_params = iwl5150_hw_set_hw_params, |
540 | .set_channel_switch = iwl5000_hw_channel_switch, | 442 | .set_channel_switch = iwl5000_hw_channel_switch, |
541 | .nic_config = iwl5000_nic_config, | 443 | .nic_config = iwl5000_nic_config, |
542 | .eeprom_ops = { | ||
543 | .regulatory_bands = { | ||
544 | EEPROM_REG_BAND_1_CHANNELS, | ||
545 | EEPROM_REG_BAND_2_CHANNELS, | ||
546 | EEPROM_REG_BAND_3_CHANNELS, | ||
547 | EEPROM_REG_BAND_4_CHANNELS, | ||
548 | EEPROM_REG_BAND_5_CHANNELS, | ||
549 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
550 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
551 | }, | ||
552 | }, | ||
553 | .temperature = iwl5150_temperature, | 444 | .temperature = iwl5150_temperature, |
554 | }; | 445 | }; |
555 | 446 | ||
@@ -570,8 +461,6 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | |||
570 | /* NIC configuration for 6000 series */ | 461 | /* NIC configuration for 6000 series */ |
571 | static void iwl6000_nic_config(struct iwl_priv *priv) | 462 | static void iwl6000_nic_config(struct iwl_priv *priv) |
572 | { | 463 | { |
573 | iwl_rf_config(priv); | ||
574 | |||
575 | switch (priv->cfg->device_family) { | 464 | switch (priv->cfg->device_family) { |
576 | case IWL_DEVICE_FAMILY_6005: | 465 | case IWL_DEVICE_FAMILY_6005: |
577 | case IWL_DEVICE_FAMILY_6030: | 466 | case IWL_DEVICE_FAMILY_6030: |
@@ -584,13 +473,13 @@ static void iwl6000_nic_config(struct iwl_priv *priv) | |||
584 | break; | 473 | break; |
585 | case IWL_DEVICE_FAMILY_6050: | 474 | case IWL_DEVICE_FAMILY_6050: |
586 | /* Indicate calibration version to uCode. */ | 475 | /* Indicate calibration version to uCode. */ |
587 | if (iwl_eeprom_calib_version(priv) >= 6) | 476 | if (priv->eeprom_data->calib_version >= 6) |
588 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 477 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
589 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 478 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
590 | break; | 479 | break; |
591 | case IWL_DEVICE_FAMILY_6150: | 480 | case IWL_DEVICE_FAMILY_6150: |
592 | /* Indicate calibration version to uCode. */ | 481 | /* Indicate calibration version to uCode. */ |
593 | if (iwl_eeprom_calib_version(priv) >= 6) | 482 | if (priv->eeprom_data->calib_version >= 6) |
594 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 483 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
595 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | 484 | CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); |
596 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, | 485 | iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG, |
@@ -627,17 +516,6 @@ static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
627 | 516 | ||
628 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) | 517 | static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) |
629 | { | 518 | { |
630 | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | | ||
631 | BIT(IEEE80211_BAND_5GHZ); | ||
632 | |||
633 | priv->hw_params.tx_chains_num = | ||
634 | num_of_ant(priv->hw_params.valid_tx_ant); | ||
635 | if (priv->cfg->rx_with_siso_diversity) | ||
636 | priv->hw_params.rx_chains_num = 1; | ||
637 | else | ||
638 | priv->hw_params.rx_chains_num = | ||
639 | num_of_ant(priv->hw_params.valid_rx_ant); | ||
640 | |||
641 | iwl6000_set_ct_threshold(priv); | 519 | iwl6000_set_ct_threshold(priv); |
642 | 520 | ||
643 | /* Set initial sensitivity parameters */ | 521 | /* Set initial sensitivity parameters */ |
@@ -654,7 +532,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
654 | */ | 532 | */ |
655 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 533 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
656 | struct iwl6000_channel_switch_cmd cmd; | 534 | struct iwl6000_channel_switch_cmd cmd; |
657 | const struct iwl_channel_info *ch_info; | ||
658 | u32 switch_time_in_usec, ucode_switch_time; | 535 | u32 switch_time_in_usec, ucode_switch_time; |
659 | u16 ch; | 536 | u16 ch; |
660 | u32 tsf_low; | 537 | u32 tsf_low; |
@@ -704,14 +581,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
704 | } | 581 | } |
705 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | 582 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", |
706 | cmd.switch_time); | 583 | cmd.switch_time); |
707 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | 584 | cmd.expect_beacon = ch_switch->channel->flags & IEEE80211_CHAN_RADAR; |
708 | if (ch_info) | ||
709 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
710 | else { | ||
711 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
712 | ctx->active.channel, ch); | ||
713 | return -EFAULT; | ||
714 | } | ||
715 | 585 | ||
716 | return iwl_dvm_send_cmd(priv, &hcmd); | 586 | return iwl_dvm_send_cmd(priv, &hcmd); |
717 | } | 587 | } |
@@ -720,18 +590,6 @@ struct iwl_lib_ops iwl6000_lib = { | |||
720 | .set_hw_params = iwl6000_hw_set_hw_params, | 590 | .set_hw_params = iwl6000_hw_set_hw_params, |
721 | .set_channel_switch = iwl6000_hw_channel_switch, | 591 | .set_channel_switch = iwl6000_hw_channel_switch, |
722 | .nic_config = iwl6000_nic_config, | 592 | .nic_config = iwl6000_nic_config, |
723 | .eeprom_ops = { | ||
724 | .regulatory_bands = { | ||
725 | EEPROM_REG_BAND_1_CHANNELS, | ||
726 | EEPROM_REG_BAND_2_CHANNELS, | ||
727 | EEPROM_REG_BAND_3_CHANNELS, | ||
728 | EEPROM_REG_BAND_4_CHANNELS, | ||
729 | EEPROM_REG_BAND_5_CHANNELS, | ||
730 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
731 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
732 | }, | ||
733 | .enhanced_txpower = true, | ||
734 | }, | ||
735 | .temperature = iwlagn_temperature, | 593 | .temperature = iwlagn_temperature, |
736 | }; | 594 | }; |
737 | 595 | ||
@@ -739,17 +597,5 @@ struct iwl_lib_ops iwl6030_lib = { | |||
739 | .set_hw_params = iwl6000_hw_set_hw_params, | 597 | .set_hw_params = iwl6000_hw_set_hw_params, |
740 | .set_channel_switch = iwl6000_hw_channel_switch, | 598 | .set_channel_switch = iwl6000_hw_channel_switch, |
741 | .nic_config = iwl6000_nic_config, | 599 | .nic_config = iwl6000_nic_config, |
742 | .eeprom_ops = { | ||
743 | .regulatory_bands = { | ||
744 | EEPROM_REG_BAND_1_CHANNELS, | ||
745 | EEPROM_REG_BAND_2_CHANNELS, | ||
746 | EEPROM_REG_BAND_3_CHANNELS, | ||
747 | EEPROM_REG_BAND_4_CHANNELS, | ||
748 | EEPROM_REG_BAND_5_CHANNELS, | ||
749 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
750 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
751 | }, | ||
752 | .enhanced_txpower = true, | ||
753 | }, | ||
754 | .temperature = iwlagn_temperature, | 600 | .temperature = iwlagn_temperature, |
755 | }; | 601 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/dvm/led.c index 47000419f916..bf479f709091 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/dvm/led.c | |||
@@ -34,12 +34,11 @@ | |||
34 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
37 | |||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
41 | #include "iwl-trans.h" | 38 | #include "iwl-trans.h" |
42 | #include "iwl-modparams.h" | 39 | #include "iwl-modparams.h" |
40 | #include "dev.h" | ||
41 | #include "agn.h" | ||
43 | 42 | ||
44 | /* Throughput OFF time(ms) ON time (ms) | 43 | /* Throughput OFF time(ms) ON time (ms) |
45 | * >300 25 25 | 44 | * >300 25 25 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/dvm/led.h index b02a853103d3..b02a853103d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/dvm/led.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index e55ec6c8a920..cb1ca7a25dd5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -33,13 +33,14 @@ | |||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
35 | 35 | ||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
38 | #include "iwl-agn-hw.h" | 37 | #include "iwl-agn-hw.h" |
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-trans.h" | 38 | #include "iwl-trans.h" |
41 | #include "iwl-modparams.h" | 39 | #include "iwl-modparams.h" |
42 | 40 | ||
41 | #include "dev.h" | ||
42 | #include "agn.h" | ||
43 | |||
43 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) | 44 | int iwlagn_hw_valid_rtc_data_addr(u32 addr) |
44 | { | 45 | { |
45 | return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) && | 46 | return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) && |
@@ -58,8 +59,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
58 | /* half dBm need to multiply */ | 59 | /* half dBm need to multiply */ |
59 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); | 60 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); |
60 | 61 | ||
61 | if (priv->tx_power_lmt_in_half_dbm && | 62 | if (tx_power_cmd.global_lmt > priv->eeprom_data->max_tx_pwr_half_dbm) { |
62 | priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) { | ||
63 | /* | 63 | /* |
64 | * For the newer devices which using enhanced/extend tx power | 64 | * For the newer devices which using enhanced/extend tx power |
65 | * table in EEPROM, the format is in half dBm. driver need to | 65 | * table in EEPROM, the format is in half dBm. driver need to |
@@ -71,7 +71,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) | |||
71 | * "tx_power_user_lmt" is higher than EEPROM value (in | 71 | * "tx_power_user_lmt" is higher than EEPROM value (in |
72 | * half-dBm format), lower the tx power based on EEPROM | 72 | * half-dBm format), lower the tx power based on EEPROM |
73 | */ | 73 | */ |
74 | tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; | 74 | tx_power_cmd.global_lmt = |
75 | priv->eeprom_data->max_tx_pwr_half_dbm; | ||
75 | } | 76 | } |
76 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; | 77 | tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; |
77 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; | 78 | tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; |
@@ -617,6 +618,11 @@ static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv, | |||
617 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 618 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
618 | int ave_rssi; | 619 | int ave_rssi; |
619 | 620 | ||
621 | if (!ctx->vif || (ctx->vif->type != NL80211_IFTYPE_STATION)) { | ||
622 | IWL_DEBUG_INFO(priv, "BSS ctx not active or not in sta mode\n"); | ||
623 | return false; | ||
624 | } | ||
625 | |||
620 | ave_rssi = ieee80211_ave_rssi(ctx->vif); | 626 | ave_rssi = ieee80211_ave_rssi(ctx->vif); |
621 | if (!ave_rssi) { | 627 | if (!ave_rssi) { |
622 | /* no rssi data, no changes to reduce tx power */ | 628 | /* no rssi data, no changes to reduce tx power */ |
@@ -818,7 +824,7 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
818 | if (priv->chain_noise_data.active_chains) | 824 | if (priv->chain_noise_data.active_chains) |
819 | active_chains = priv->chain_noise_data.active_chains; | 825 | active_chains = priv->chain_noise_data.active_chains; |
820 | else | 826 | else |
821 | active_chains = priv->hw_params.valid_rx_ant; | 827 | active_chains = priv->eeprom_data->valid_rx_ant; |
822 | 828 | ||
823 | if (priv->cfg->bt_params && | 829 | if (priv->cfg->bt_params && |
824 | priv->cfg->bt_params->advanced_bt_coexist && | 830 | priv->cfg->bt_params->advanced_bt_coexist && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 3ee23134c02b..599e8b41f5a8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -38,19 +38,20 @@ | |||
38 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
39 | #include <linux/if_arp.h> | 39 | #include <linux/if_arp.h> |
40 | 40 | ||
41 | #include <net/ieee80211_radiotap.h> | ||
41 | #include <net/mac80211.h> | 42 | #include <net/mac80211.h> |
42 | 43 | ||
43 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
44 | 45 | ||
45 | #include "iwl-eeprom.h" | ||
46 | #include "iwl-dev.h" | ||
47 | #include "iwl-io.h" | 46 | #include "iwl-io.h" |
48 | #include "iwl-agn-calib.h" | ||
49 | #include "iwl-agn.h" | ||
50 | #include "iwl-trans.h" | 47 | #include "iwl-trans.h" |
51 | #include "iwl-op-mode.h" | 48 | #include "iwl-op-mode.h" |
52 | #include "iwl-modparams.h" | 49 | #include "iwl-modparams.h" |
53 | 50 | ||
51 | #include "dev.h" | ||
52 | #include "calib.h" | ||
53 | #include "agn.h" | ||
54 | |||
54 | /***************************************************************************** | 55 | /***************************************************************************** |
55 | * | 56 | * |
56 | * mac80211 entry point functions | 57 | * mac80211 entry point functions |
@@ -154,6 +155,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
154 | IEEE80211_HW_SCAN_WHILE_IDLE; | 155 | IEEE80211_HW_SCAN_WHILE_IDLE; |
155 | 156 | ||
156 | hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; | 157 | hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE; |
158 | hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT; | ||
157 | 159 | ||
158 | /* | 160 | /* |
159 | * Including the following line will crash some AP's. This | 161 | * Including the following line will crash some AP's. This |
@@ -237,12 +239,12 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
237 | 239 | ||
238 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; | 240 | hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; |
239 | 241 | ||
240 | if (priv->bands[IEEE80211_BAND_2GHZ].n_channels) | 242 | if (priv->eeprom_data->bands[IEEE80211_BAND_2GHZ].n_channels) |
241 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 243 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
242 | &priv->bands[IEEE80211_BAND_2GHZ]; | 244 | &priv->eeprom_data->bands[IEEE80211_BAND_2GHZ]; |
243 | if (priv->bands[IEEE80211_BAND_5GHZ].n_channels) | 245 | if (priv->eeprom_data->bands[IEEE80211_BAND_5GHZ].n_channels) |
244 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 246 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
245 | &priv->bands[IEEE80211_BAND_5GHZ]; | 247 | &priv->eeprom_data->bands[IEEE80211_BAND_5GHZ]; |
246 | 248 | ||
247 | hw->wiphy->hw_version = priv->trans->hw_id; | 249 | hw->wiphy->hw_version = priv->trans->hw_id; |
248 | 250 | ||
@@ -341,7 +343,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
341 | return 0; | 343 | return 0; |
342 | } | 344 | } |
343 | 345 | ||
344 | void iwlagn_mac_stop(struct ieee80211_hw *hw) | 346 | static void iwlagn_mac_stop(struct ieee80211_hw *hw) |
345 | { | 347 | { |
346 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 348 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
347 | 349 | ||
@@ -369,9 +371,9 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) | |||
369 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 371 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
370 | } | 372 | } |
371 | 373 | ||
372 | void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | 374 | static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, |
373 | struct ieee80211_vif *vif, | 375 | struct ieee80211_vif *vif, |
374 | struct cfg80211_gtk_rekey_data *data) | 376 | struct cfg80211_gtk_rekey_data *data) |
375 | { | 377 | { |
376 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 378 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
377 | 379 | ||
@@ -397,7 +399,8 @@ void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, | |||
397 | 399 | ||
398 | #ifdef CONFIG_PM_SLEEP | 400 | #ifdef CONFIG_PM_SLEEP |
399 | 401 | ||
400 | int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | 402 | static int iwlagn_mac_suspend(struct ieee80211_hw *hw, |
403 | struct cfg80211_wowlan *wowlan) | ||
401 | { | 404 | { |
402 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 405 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
403 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 406 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
@@ -420,8 +423,6 @@ int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
420 | if (ret) | 423 | if (ret) |
421 | goto error; | 424 | goto error; |
422 | 425 | ||
423 | device_set_wakeup_enable(priv->trans->dev, true); | ||
424 | |||
425 | iwl_trans_wowlan_suspend(priv->trans); | 426 | iwl_trans_wowlan_suspend(priv->trans); |
426 | 427 | ||
427 | goto out; | 428 | goto out; |
@@ -488,8 +489,6 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
488 | 489 | ||
489 | priv->wowlan = false; | 490 | priv->wowlan = false; |
490 | 491 | ||
491 | device_set_wakeup_enable(priv->trans->dev, false); | ||
492 | |||
493 | iwlagn_prepare_restart(priv); | 492 | iwlagn_prepare_restart(priv); |
494 | 493 | ||
495 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); | 494 | memset((void *)&ctx->active, 0, sizeof(ctx->active)); |
@@ -504,9 +503,15 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) | |||
504 | return 1; | 503 | return 1; |
505 | } | 504 | } |
506 | 505 | ||
506 | static void iwlagn_mac_set_wakeup(struct ieee80211_hw *hw, bool enabled) | ||
507 | { | ||
508 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | ||
509 | |||
510 | device_set_wakeup_enable(priv->trans->dev, enabled); | ||
511 | } | ||
507 | #endif | 512 | #endif |
508 | 513 | ||
509 | void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 514 | static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
510 | { | 515 | { |
511 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 516 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
512 | 517 | ||
@@ -517,21 +522,21 @@ void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
517 | dev_kfree_skb_any(skb); | 522 | dev_kfree_skb_any(skb); |
518 | } | 523 | } |
519 | 524 | ||
520 | void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, | 525 | static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, |
521 | struct ieee80211_vif *vif, | 526 | struct ieee80211_vif *vif, |
522 | struct ieee80211_key_conf *keyconf, | 527 | struct ieee80211_key_conf *keyconf, |
523 | struct ieee80211_sta *sta, | 528 | struct ieee80211_sta *sta, |
524 | u32 iv32, u16 *phase1key) | 529 | u32 iv32, u16 *phase1key) |
525 | { | 530 | { |
526 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 531 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
527 | 532 | ||
528 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); | 533 | iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); |
529 | } | 534 | } |
530 | 535 | ||
531 | int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 536 | static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
532 | struct ieee80211_vif *vif, | 537 | struct ieee80211_vif *vif, |
533 | struct ieee80211_sta *sta, | 538 | struct ieee80211_sta *sta, |
534 | struct ieee80211_key_conf *key) | 539 | struct ieee80211_key_conf *key) |
535 | { | 540 | { |
536 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 541 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
537 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 542 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -631,11 +636,11 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
631 | return ret; | 636 | return ret; |
632 | } | 637 | } |
633 | 638 | ||
634 | int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 639 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
635 | struct ieee80211_vif *vif, | 640 | struct ieee80211_vif *vif, |
636 | enum ieee80211_ampdu_mlme_action action, | 641 | enum ieee80211_ampdu_mlme_action action, |
637 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, | 642 | struct ieee80211_sta *sta, u16 tid, u16 *ssn, |
638 | u8 buf_size) | 643 | u8 buf_size) |
639 | { | 644 | { |
640 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 645 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
641 | int ret = -EINVAL; | 646 | int ret = -EINVAL; |
@@ -662,7 +667,7 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
662 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); | 667 | ret = iwl_sta_rx_agg_stop(priv, sta, tid); |
663 | break; | 668 | break; |
664 | case IEEE80211_AMPDU_TX_START: | 669 | case IEEE80211_AMPDU_TX_START: |
665 | if (!priv->trans->ops->tx_agg_setup) | 670 | if (!priv->trans->ops->txq_enable) |
666 | break; | 671 | break; |
667 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 672 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) |
668 | break; | 673 | break; |
@@ -757,11 +762,11 @@ static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, | |||
757 | return ret; | 762 | return ret; |
758 | } | 763 | } |
759 | 764 | ||
760 | int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | 765 | static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, |
761 | struct ieee80211_vif *vif, | 766 | struct ieee80211_vif *vif, |
762 | struct ieee80211_sta *sta, | 767 | struct ieee80211_sta *sta, |
763 | enum ieee80211_sta_state old_state, | 768 | enum ieee80211_sta_state old_state, |
764 | enum ieee80211_sta_state new_state) | 769 | enum ieee80211_sta_state new_state) |
765 | { | 770 | { |
766 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 771 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
767 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 772 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -840,11 +845,10 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | |||
840 | return ret; | 845 | return ret; |
841 | } | 846 | } |
842 | 847 | ||
843 | void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | 848 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, |
844 | struct ieee80211_channel_switch *ch_switch) | 849 | struct ieee80211_channel_switch *ch_switch) |
845 | { | 850 | { |
846 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 851 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
847 | const struct iwl_channel_info *ch_info; | ||
848 | struct ieee80211_conf *conf = &hw->conf; | 852 | struct ieee80211_conf *conf = &hw->conf; |
849 | struct ieee80211_channel *channel = ch_switch->channel; | 853 | struct ieee80211_channel *channel = ch_switch->channel; |
850 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | 854 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; |
@@ -881,12 +885,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
881 | if (le16_to_cpu(ctx->active.channel) == ch) | 885 | if (le16_to_cpu(ctx->active.channel) == ch) |
882 | goto out; | 886 | goto out; |
883 | 887 | ||
884 | ch_info = iwl_get_channel_info(priv, channel->band, ch); | ||
885 | if (!is_channel_valid(ch_info)) { | ||
886 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
887 | goto out; | ||
888 | } | ||
889 | |||
890 | priv->current_ht_config.smps = conf->smps_mode; | 888 | priv->current_ht_config.smps = conf->smps_mode; |
891 | 889 | ||
892 | /* Configure HT40 channels */ | 890 | /* Configure HT40 channels */ |
@@ -935,10 +933,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
935 | ieee80211_chswitch_done(ctx->vif, is_success); | 933 | ieee80211_chswitch_done(ctx->vif, is_success); |
936 | } | 934 | } |
937 | 935 | ||
938 | void iwlagn_configure_filter(struct ieee80211_hw *hw, | 936 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, |
939 | unsigned int changed_flags, | 937 | unsigned int changed_flags, |
940 | unsigned int *total_flags, | 938 | unsigned int *total_flags, |
941 | u64 multicast) | 939 | u64 multicast) |
942 | { | 940 | { |
943 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 941 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
944 | __le32 filter_or = 0, filter_nand = 0; | 942 | __le32 filter_or = 0, filter_nand = 0; |
@@ -985,7 +983,7 @@ void iwlagn_configure_filter(struct ieee80211_hw *hw, | |||
985 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | 983 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; |
986 | } | 984 | } |
987 | 985 | ||
988 | void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | 986 | static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) |
989 | { | 987 | { |
990 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 988 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
991 | 989 | ||
@@ -1112,7 +1110,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
1112 | return err; | 1110 | return err; |
1113 | } | 1111 | } |
1114 | 1112 | ||
1115 | int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | 1113 | static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) |
1116 | { | 1114 | { |
1117 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1115 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1118 | 1116 | ||
@@ -1129,8 +1127,8 @@ int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) | |||
1129 | return 0; | 1127 | return 0; |
1130 | } | 1128 | } |
1131 | 1129 | ||
1132 | void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | 1130 | static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, |
1133 | enum ieee80211_rssi_event rssi_event) | 1131 | enum ieee80211_rssi_event rssi_event) |
1134 | { | 1132 | { |
1135 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1133 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1136 | 1134 | ||
@@ -1154,8 +1152,8 @@ void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, | |||
1154 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 1152 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
1155 | } | 1153 | } |
1156 | 1154 | ||
1157 | int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | 1155 | static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, |
1158 | struct ieee80211_sta *sta, bool set) | 1156 | struct ieee80211_sta *sta, bool set) |
1159 | { | 1157 | { |
1160 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1158 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1161 | 1159 | ||
@@ -1164,9 +1162,9 @@ int iwlagn_mac_set_tim(struct ieee80211_hw *hw, | |||
1164 | return 0; | 1162 | return 0; |
1165 | } | 1163 | } |
1166 | 1164 | ||
1167 | int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | 1165 | static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, |
1168 | struct ieee80211_vif *vif, u16 queue, | 1166 | struct ieee80211_vif *vif, u16 queue, |
1169 | const struct ieee80211_tx_queue_params *params) | 1167 | const struct ieee80211_tx_queue_params *params) |
1170 | { | 1168 | { |
1171 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1169 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1172 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; | 1170 | struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; |
@@ -1208,7 +1206,7 @@ int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, | |||
1208 | return 0; | 1206 | return 0; |
1209 | } | 1207 | } |
1210 | 1208 | ||
1211 | int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) | 1209 | static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) |
1212 | { | 1210 | { |
1213 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1211 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1214 | 1212 | ||
@@ -1224,7 +1222,8 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
1224 | return iwlagn_commit_rxon(priv, ctx); | 1222 | return iwlagn_commit_rxon(priv, ctx); |
1225 | } | 1223 | } |
1226 | 1224 | ||
1227 | int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 1225 | static int iwl_setup_interface(struct iwl_priv *priv, |
1226 | struct iwl_rxon_context *ctx) | ||
1228 | { | 1227 | { |
1229 | struct ieee80211_vif *vif = ctx->vif; | 1228 | struct ieee80211_vif *vif = ctx->vif; |
1230 | int err, ac; | 1229 | int err, ac; |
@@ -1344,9 +1343,9 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, | |||
1344 | return err; | 1343 | return err; |
1345 | } | 1344 | } |
1346 | 1345 | ||
1347 | void iwl_teardown_interface(struct iwl_priv *priv, | 1346 | static void iwl_teardown_interface(struct iwl_priv *priv, |
1348 | struct ieee80211_vif *vif, | 1347 | struct ieee80211_vif *vif, |
1349 | bool mode_change) | 1348 | bool mode_change) |
1350 | { | 1349 | { |
1351 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1350 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1352 | 1351 | ||
@@ -1487,9 +1486,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, | |||
1487 | return err; | 1486 | return err; |
1488 | } | 1487 | } |
1489 | 1488 | ||
1490 | int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, | 1489 | static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, |
1491 | struct ieee80211_vif *vif, | 1490 | struct ieee80211_vif *vif, |
1492 | struct cfg80211_scan_request *req) | 1491 | struct cfg80211_scan_request *req) |
1493 | { | 1492 | { |
1494 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1493 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1495 | int ret; | 1494 | int ret; |
@@ -1544,10 +1543,10 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) | |||
1544 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); | 1543 | iwl_send_add_sta(priv, &cmd, CMD_ASYNC); |
1545 | } | 1544 | } |
1546 | 1545 | ||
1547 | void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, | 1546 | static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, |
1548 | struct ieee80211_vif *vif, | 1547 | struct ieee80211_vif *vif, |
1549 | enum sta_notify_cmd cmd, | 1548 | enum sta_notify_cmd cmd, |
1550 | struct ieee80211_sta *sta) | 1549 | struct ieee80211_sta *sta) |
1551 | { | 1550 | { |
1552 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1551 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
1553 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 1552 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; |
@@ -1584,6 +1583,7 @@ struct ieee80211_ops iwlagn_hw_ops = { | |||
1584 | #ifdef CONFIG_PM_SLEEP | 1583 | #ifdef CONFIG_PM_SLEEP |
1585 | .suspend = iwlagn_mac_suspend, | 1584 | .suspend = iwlagn_mac_suspend, |
1586 | .resume = iwlagn_mac_resume, | 1585 | .resume = iwlagn_mac_resume, |
1586 | .set_wakeup = iwlagn_mac_set_wakeup, | ||
1587 | #endif | 1587 | #endif |
1588 | .add_interface = iwlagn_mac_add_interface, | 1588 | .add_interface = iwlagn_mac_add_interface, |
1589 | .remove_interface = iwlagn_mac_remove_interface, | 1589 | .remove_interface = iwlagn_mac_remove_interface, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/dvm/main.c index ec36e2b020b6..1c2d0233a405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -44,16 +44,18 @@ | |||
44 | 44 | ||
45 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
46 | 46 | ||
47 | #include "iwl-eeprom.h" | 47 | #include "iwl-eeprom-read.h" |
48 | #include "iwl-dev.h" | 48 | #include "iwl-eeprom-parse.h" |
49 | #include "iwl-io.h" | 49 | #include "iwl-io.h" |
50 | #include "iwl-agn-calib.h" | ||
51 | #include "iwl-agn.h" | ||
52 | #include "iwl-trans.h" | 50 | #include "iwl-trans.h" |
53 | #include "iwl-op-mode.h" | 51 | #include "iwl-op-mode.h" |
54 | #include "iwl-drv.h" | 52 | #include "iwl-drv.h" |
55 | #include "iwl-modparams.h" | 53 | #include "iwl-modparams.h" |
56 | 54 | ||
55 | #include "dev.h" | ||
56 | #include "calib.h" | ||
57 | #include "agn.h" | ||
58 | |||
57 | /****************************************************************************** | 59 | /****************************************************************************** |
58 | * | 60 | * |
59 | * module boiler plate | 61 | * module boiler plate |
@@ -78,7 +80,8 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
78 | MODULE_VERSION(DRV_VERSION); | 80 | MODULE_VERSION(DRV_VERSION); |
79 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | 81 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); |
80 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
81 | MODULE_ALIAS("iwlagn"); | 83 | |
84 | static const struct iwl_op_mode_ops iwl_dvm_ops; | ||
82 | 85 | ||
83 | void iwl_update_chain_flags(struct iwl_priv *priv) | 86 | void iwl_update_chain_flags(struct iwl_priv *priv) |
84 | { | 87 | { |
@@ -180,7 +183,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) | |||
180 | rate = info->control.rates[0].idx; | 183 | rate = info->control.rates[0].idx; |
181 | 184 | ||
182 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 185 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
183 | priv->hw_params.valid_tx_ant); | 186 | priv->eeprom_data->valid_tx_ant); |
184 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 187 | rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
185 | 188 | ||
186 | /* In mac80211, rates for 5 GHz start at 0 */ | 189 | /* In mac80211, rates for 5 GHz start at 0 */ |
@@ -578,7 +581,7 @@ static const u8 iwlagn_pan_ac_to_queue[] = { | |||
578 | 7, 6, 5, 4, | 581 | 7, 6, 5, 4, |
579 | }; | 582 | }; |
580 | 583 | ||
581 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 584 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
582 | { | 585 | { |
583 | int i; | 586 | int i; |
584 | 587 | ||
@@ -645,7 +648,7 @@ void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
645 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 648 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
646 | } | 649 | } |
647 | 650 | ||
648 | void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 651 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) |
649 | { | 652 | { |
650 | struct iwl_ct_kill_config cmd; | 653 | struct iwl_ct_kill_config cmd; |
651 | struct iwl_ct_kill_throttling_config adv_cmd; | 654 | struct iwl_ct_kill_throttling_config adv_cmd; |
@@ -726,7 +729,7 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | |||
726 | } | 729 | } |
727 | } | 730 | } |
728 | 731 | ||
729 | void iwl_send_bt_config(struct iwl_priv *priv) | 732 | static void iwl_send_bt_config(struct iwl_priv *priv) |
730 | { | 733 | { |
731 | struct iwl_bt_cmd bt_cmd = { | 734 | struct iwl_bt_cmd bt_cmd = { |
732 | .lead_time = BT_LEAD_TIME_DEF, | 735 | .lead_time = BT_LEAD_TIME_DEF, |
@@ -814,7 +817,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
814 | ieee80211_wake_queues(priv->hw); | 817 | ieee80211_wake_queues(priv->hw); |
815 | 818 | ||
816 | /* Configure Tx antenna selection based on H/W config */ | 819 | /* Configure Tx antenna selection based on H/W config */ |
817 | iwlagn_send_tx_ant_config(priv, priv->hw_params.valid_tx_ant); | 820 | iwlagn_send_tx_ant_config(priv, priv->eeprom_data->valid_tx_ant); |
818 | 821 | ||
819 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { | 822 | if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { |
820 | struct iwl_rxon_cmd *active_rxon = | 823 | struct iwl_rxon_cmd *active_rxon = |
@@ -932,11 +935,12 @@ void iwl_down(struct iwl_priv *priv) | |||
932 | priv->ucode_loaded = false; | 935 | priv->ucode_loaded = false; |
933 | iwl_trans_stop_device(priv->trans); | 936 | iwl_trans_stop_device(priv->trans); |
934 | 937 | ||
938 | /* Set num_aux_in_flight must be done after the transport is stopped */ | ||
939 | atomic_set(&priv->num_aux_in_flight, 0); | ||
940 | |||
935 | /* Clear out all status bits but a few that are stable across reset */ | 941 | /* Clear out all status bits but a few that are stable across reset */ |
936 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 942 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
937 | STATUS_RF_KILL_HW | | 943 | STATUS_RF_KILL_HW | |
938 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | ||
939 | STATUS_GEO_CONFIGURED | | ||
940 | test_bit(STATUS_FW_ERROR, &priv->status) << | 944 | test_bit(STATUS_FW_ERROR, &priv->status) << |
941 | STATUS_FW_ERROR | | 945 | STATUS_FW_ERROR | |
942 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 946 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -1078,7 +1082,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work) | |||
1078 | * | 1082 | * |
1079 | *****************************************************************************/ | 1083 | *****************************************************************************/ |
1080 | 1084 | ||
1081 | void iwl_setup_deferred_work(struct iwl_priv *priv) | 1085 | static void iwl_setup_deferred_work(struct iwl_priv *priv) |
1082 | { | 1086 | { |
1083 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); | 1087 | priv->workqueue = create_singlethread_workqueue(DRV_NAME); |
1084 | 1088 | ||
@@ -1123,224 +1127,14 @@ void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
1123 | del_timer_sync(&priv->ucode_trace); | 1127 | del_timer_sync(&priv->ucode_trace); |
1124 | } | 1128 | } |
1125 | 1129 | ||
1126 | static void iwl_init_hw_rates(struct ieee80211_rate *rates) | 1130 | static int iwl_init_drv(struct iwl_priv *priv) |
1127 | { | ||
1128 | int i; | ||
1129 | |||
1130 | for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) { | ||
1131 | rates[i].bitrate = iwl_rates[i].ieee * 5; | ||
1132 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ | ||
1133 | rates[i].hw_value_short = i; | ||
1134 | rates[i].flags = 0; | ||
1135 | if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) { | ||
1136 | /* | ||
1137 | * If CCK != 1M then set short preamble rate flag. | ||
1138 | */ | ||
1139 | rates[i].flags |= | ||
1140 | (iwl_rates[i].plcp == IWL_RATE_1M_PLCP) ? | ||
1141 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; | ||
1142 | } | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | ||
1147 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | ||
1148 | static void iwl_init_ht_hw_capab(const struct iwl_priv *priv, | ||
1149 | struct ieee80211_sta_ht_cap *ht_info, | ||
1150 | enum ieee80211_band band) | ||
1151 | { | ||
1152 | u16 max_bit_rate = 0; | ||
1153 | u8 rx_chains_num = priv->hw_params.rx_chains_num; | ||
1154 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | ||
1155 | |||
1156 | ht_info->cap = 0; | ||
1157 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
1158 | |||
1159 | ht_info->ht_supported = true; | ||
1160 | |||
1161 | if (priv->cfg->ht_params && | ||
1162 | priv->cfg->ht_params->ht_greenfield_support) | ||
1163 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | ||
1164 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
1165 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | ||
1166 | if (priv->hw_params.ht40_channel & BIT(band)) { | ||
1167 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
1168 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
1169 | ht_info->mcs.rx_mask[4] = 0x01; | ||
1170 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||
1171 | } | ||
1172 | |||
1173 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
1174 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||
1175 | |||
1176 | ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||
1177 | ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; | ||
1178 | |||
1179 | ht_info->mcs.rx_mask[0] = 0xFF; | ||
1180 | if (rx_chains_num >= 2) | ||
1181 | ht_info->mcs.rx_mask[1] = 0xFF; | ||
1182 | if (rx_chains_num >= 3) | ||
1183 | ht_info->mcs.rx_mask[2] = 0xFF; | ||
1184 | |||
1185 | /* Highest supported Rx data rate */ | ||
1186 | max_bit_rate *= rx_chains_num; | ||
1187 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); | ||
1188 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); | ||
1189 | |||
1190 | /* Tx MCS capabilities */ | ||
1191 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
1192 | if (tx_chains_num != rx_chains_num) { | ||
1193 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
1194 | ht_info->mcs.tx_params |= ((tx_chains_num - 1) << | ||
1195 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
1196 | } | ||
1197 | } | ||
1198 | |||
1199 | /** | ||
1200 | * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom | ||
1201 | */ | ||
1202 | static int iwl_init_geos(struct iwl_priv *priv) | ||
1203 | { | ||
1204 | struct iwl_channel_info *ch; | ||
1205 | struct ieee80211_supported_band *sband; | ||
1206 | struct ieee80211_channel *channels; | ||
1207 | struct ieee80211_channel *geo_ch; | ||
1208 | struct ieee80211_rate *rates; | ||
1209 | int i = 0; | ||
1210 | s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||
1211 | |||
1212 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||
1213 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
1214 | IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); | ||
1215 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | channels = kcalloc(priv->channel_count, | ||
1220 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
1221 | if (!channels) | ||
1222 | return -ENOMEM; | ||
1223 | |||
1224 | rates = kcalloc(IWL_RATE_COUNT_LEGACY, sizeof(struct ieee80211_rate), | ||
1225 | GFP_KERNEL); | ||
1226 | if (!rates) { | ||
1227 | kfree(channels); | ||
1228 | return -ENOMEM; | ||
1229 | } | ||
1230 | |||
1231 | /* 5.2GHz channels start after the 2.4GHz channels */ | ||
1232 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; | ||
1233 | sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; | ||
1234 | /* just OFDM */ | ||
1235 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; | ||
1236 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE; | ||
1237 | |||
1238 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1239 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
1240 | IEEE80211_BAND_5GHZ); | ||
1241 | |||
1242 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; | ||
1243 | sband->channels = channels; | ||
1244 | /* OFDM & CCK */ | ||
1245 | sband->bitrates = rates; | ||
1246 | sband->n_bitrates = IWL_RATE_COUNT_LEGACY; | ||
1247 | |||
1248 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) | ||
1249 | iwl_init_ht_hw_capab(priv, &sband->ht_cap, | ||
1250 | IEEE80211_BAND_2GHZ); | ||
1251 | |||
1252 | priv->ieee_channels = channels; | ||
1253 | priv->ieee_rates = rates; | ||
1254 | |||
1255 | for (i = 0; i < priv->channel_count; i++) { | ||
1256 | ch = &priv->channel_info[i]; | ||
1257 | |||
1258 | /* FIXME: might be removed if scan is OK */ | ||
1259 | if (!is_channel_valid(ch)) | ||
1260 | continue; | ||
1261 | |||
1262 | sband = &priv->bands[ch->band]; | ||
1263 | |||
1264 | geo_ch = &sband->channels[sband->n_channels++]; | ||
1265 | |||
1266 | geo_ch->center_freq = | ||
1267 | ieee80211_channel_to_frequency(ch->channel, ch->band); | ||
1268 | geo_ch->max_power = ch->max_power_avg; | ||
1269 | geo_ch->max_antenna_gain = 0xff; | ||
1270 | geo_ch->hw_value = ch->channel; | ||
1271 | |||
1272 | if (is_channel_valid(ch)) { | ||
1273 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) | ||
1274 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; | ||
1275 | |||
1276 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
1277 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
1278 | |||
1279 | if (ch->flags & EEPROM_CHANNEL_RADAR) | ||
1280 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | ||
1281 | |||
1282 | geo_ch->flags |= ch->ht40_extension_channel; | ||
1283 | |||
1284 | if (ch->max_power_avg > max_tx_power) | ||
1285 | max_tx_power = ch->max_power_avg; | ||
1286 | } else { | ||
1287 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
1288 | } | ||
1289 | |||
1290 | IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", | ||
1291 | ch->channel, geo_ch->center_freq, | ||
1292 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
1293 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
1294 | "restricted" : "valid", | ||
1295 | geo_ch->flags); | ||
1296 | } | ||
1297 | |||
1298 | priv->tx_power_device_lmt = max_tx_power; | ||
1299 | priv->tx_power_user_lmt = max_tx_power; | ||
1300 | priv->tx_power_next = max_tx_power; | ||
1301 | |||
1302 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||
1303 | priv->hw_params.sku & EEPROM_SKU_CAP_BAND_52GHZ) { | ||
1304 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | ||
1305 | "Please send your %s to maintainer.\n", | ||
1306 | priv->trans->hw_id_str); | ||
1307 | priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; | ||
1308 | } | ||
1309 | |||
1310 | if (iwlwifi_mod_params.disable_5ghz) | ||
1311 | priv->bands[IEEE80211_BAND_5GHZ].n_channels = 0; | ||
1312 | |||
1313 | IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", | ||
1314 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, | ||
1315 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | ||
1316 | |||
1317 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | /* | ||
1323 | * iwl_free_geos - undo allocations in iwl_init_geos | ||
1324 | */ | ||
1325 | static void iwl_free_geos(struct iwl_priv *priv) | ||
1326 | { | 1131 | { |
1327 | kfree(priv->ieee_channels); | ||
1328 | kfree(priv->ieee_rates); | ||
1329 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | ||
1330 | } | ||
1331 | |||
1332 | int iwl_init_drv(struct iwl_priv *priv) | ||
1333 | { | ||
1334 | int ret; | ||
1335 | |||
1336 | spin_lock_init(&priv->sta_lock); | 1132 | spin_lock_init(&priv->sta_lock); |
1337 | 1133 | ||
1338 | mutex_init(&priv->mutex); | 1134 | mutex_init(&priv->mutex); |
1339 | 1135 | ||
1340 | INIT_LIST_HEAD(&priv->calib_results); | 1136 | INIT_LIST_HEAD(&priv->calib_results); |
1341 | 1137 | ||
1342 | priv->ieee_channels = NULL; | ||
1343 | priv->ieee_rates = NULL; | ||
1344 | priv->band = IEEE80211_BAND_2GHZ; | 1138 | priv->band = IEEE80211_BAND_2GHZ; |
1345 | 1139 | ||
1346 | priv->plcp_delta_threshold = | 1140 | priv->plcp_delta_threshold = |
@@ -1371,31 +1165,11 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
1371 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; | 1165 | priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; |
1372 | } | 1166 | } |
1373 | 1167 | ||
1374 | ret = iwl_init_channel_map(priv); | ||
1375 | if (ret) { | ||
1376 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | ||
1377 | goto err; | ||
1378 | } | ||
1379 | |||
1380 | ret = iwl_init_geos(priv); | ||
1381 | if (ret) { | ||
1382 | IWL_ERR(priv, "initializing geos failed: %d\n", ret); | ||
1383 | goto err_free_channel_map; | ||
1384 | } | ||
1385 | iwl_init_hw_rates(priv->ieee_rates); | ||
1386 | |||
1387 | return 0; | 1168 | return 0; |
1388 | |||
1389 | err_free_channel_map: | ||
1390 | iwl_free_channel_map(priv); | ||
1391 | err: | ||
1392 | return ret; | ||
1393 | } | 1169 | } |
1394 | 1170 | ||
1395 | void iwl_uninit_drv(struct iwl_priv *priv) | 1171 | static void iwl_uninit_drv(struct iwl_priv *priv) |
1396 | { | 1172 | { |
1397 | iwl_free_geos(priv); | ||
1398 | iwl_free_channel_map(priv); | ||
1399 | kfree(priv->scan_cmd); | 1173 | kfree(priv->scan_cmd); |
1400 | kfree(priv->beacon_cmd); | 1174 | kfree(priv->beacon_cmd); |
1401 | kfree(rcu_dereference_raw(priv->noa_data)); | 1175 | kfree(rcu_dereference_raw(priv->noa_data)); |
@@ -1405,7 +1179,7 @@ void iwl_uninit_drv(struct iwl_priv *priv) | |||
1405 | #endif | 1179 | #endif |
1406 | } | 1180 | } |
1407 | 1181 | ||
1408 | void iwl_set_hw_params(struct iwl_priv *priv) | 1182 | static void iwl_set_hw_params(struct iwl_priv *priv) |
1409 | { | 1183 | { |
1410 | if (priv->cfg->ht_params) | 1184 | if (priv->cfg->ht_params) |
1411 | priv->hw_params.use_rts_for_aggregation = | 1185 | priv->hw_params.use_rts_for_aggregation = |
@@ -1421,7 +1195,7 @@ void iwl_set_hw_params(struct iwl_priv *priv) | |||
1421 | 1195 | ||
1422 | 1196 | ||
1423 | /* show what optional capabilities we have */ | 1197 | /* show what optional capabilities we have */ |
1424 | void iwl_option_config(struct iwl_priv *priv) | 1198 | static void iwl_option_config(struct iwl_priv *priv) |
1425 | { | 1199 | { |
1426 | #ifdef CONFIG_IWLWIFI_DEBUG | 1200 | #ifdef CONFIG_IWLWIFI_DEBUG |
1427 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n"); | 1201 | IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n"); |
@@ -1454,6 +1228,42 @@ void iwl_option_config(struct iwl_priv *priv) | |||
1454 | #endif | 1228 | #endif |
1455 | } | 1229 | } |
1456 | 1230 | ||
1231 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | ||
1232 | { | ||
1233 | u16 radio_cfg; | ||
1234 | |||
1235 | priv->hw_params.sku = priv->eeprom_data->sku; | ||
1236 | |||
1237 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && | ||
1238 | !priv->cfg->ht_params) { | ||
1239 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
1240 | return -EINVAL; | ||
1241 | } | ||
1242 | |||
1243 | if (!priv->hw_params.sku) { | ||
1244 | IWL_ERR(priv, "Invalid device sku\n"); | ||
1245 | return -EINVAL; | ||
1246 | } | ||
1247 | |||
1248 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); | ||
1249 | |||
1250 | radio_cfg = priv->eeprom_data->radio_cfg; | ||
1251 | |||
1252 | priv->hw_params.tx_chains_num = | ||
1253 | num_of_ant(priv->eeprom_data->valid_tx_ant); | ||
1254 | if (priv->cfg->rx_with_siso_diversity) | ||
1255 | priv->hw_params.rx_chains_num = 1; | ||
1256 | else | ||
1257 | priv->hw_params.rx_chains_num = | ||
1258 | num_of_ant(priv->eeprom_data->valid_rx_ant); | ||
1259 | |||
1260 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | ||
1261 | priv->eeprom_data->valid_tx_ant, | ||
1262 | priv->eeprom_data->valid_rx_ant); | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | |||
1457 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | 1267 | static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, |
1458 | const struct iwl_cfg *cfg, | 1268 | const struct iwl_cfg *cfg, |
1459 | const struct iwl_fw *fw) | 1269 | const struct iwl_fw *fw) |
@@ -1539,7 +1349,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1539 | trans_cfg.queue_watchdog_timeout = | 1349 | trans_cfg.queue_watchdog_timeout = |
1540 | priv->cfg->base_params->wd_timeout; | 1350 | priv->cfg->base_params->wd_timeout; |
1541 | else | 1351 | else |
1542 | trans_cfg.queue_watchdog_timeout = IWL_WATCHHDOG_DISABLED; | 1352 | trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; |
1543 | trans_cfg.command_names = iwl_dvm_cmd_strings; | 1353 | trans_cfg.command_names = iwl_dvm_cmd_strings; |
1544 | 1354 | ||
1545 | ucode_flags = fw->ucode_capa.flags; | 1355 | ucode_flags = fw->ucode_capa.flags; |
@@ -1599,25 +1409,33 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1599 | goto out_free_hw; | 1409 | goto out_free_hw; |
1600 | 1410 | ||
1601 | /* Read the EEPROM */ | 1411 | /* Read the EEPROM */ |
1602 | if (iwl_eeprom_init(priv, priv->trans->hw_rev)) { | 1412 | if (iwl_read_eeprom(priv->trans, &priv->eeprom_blob, |
1413 | &priv->eeprom_blob_size)) { | ||
1603 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 1414 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
1604 | goto out_free_hw; | 1415 | goto out_free_hw; |
1605 | } | 1416 | } |
1417 | |||
1606 | /* Reset chip to save power until we load uCode during "up". */ | 1418 | /* Reset chip to save power until we load uCode during "up". */ |
1607 | iwl_trans_stop_hw(priv->trans, false); | 1419 | iwl_trans_stop_hw(priv->trans, false); |
1608 | 1420 | ||
1609 | if (iwl_eeprom_check_version(priv)) | 1421 | priv->eeprom_data = iwl_parse_eeprom_data(priv->trans->dev, priv->cfg, |
1422 | priv->eeprom_blob, | ||
1423 | priv->eeprom_blob_size); | ||
1424 | if (!priv->eeprom_data) | ||
1425 | goto out_free_eeprom_blob; | ||
1426 | |||
1427 | if (iwl_eeprom_check_version(priv->eeprom_data, priv->trans)) | ||
1610 | goto out_free_eeprom; | 1428 | goto out_free_eeprom; |
1611 | 1429 | ||
1612 | if (iwl_eeprom_init_hw_params(priv)) | 1430 | if (iwl_eeprom_init_hw_params(priv)) |
1613 | goto out_free_eeprom; | 1431 | goto out_free_eeprom; |
1614 | 1432 | ||
1615 | /* extract MAC Address */ | 1433 | /* extract MAC Address */ |
1616 | iwl_eeprom_get_mac(priv, priv->addresses[0].addr); | 1434 | memcpy(priv->addresses[0].addr, priv->eeprom_data->hw_addr, ETH_ALEN); |
1617 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); | 1435 | IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); |
1618 | priv->hw->wiphy->addresses = priv->addresses; | 1436 | priv->hw->wiphy->addresses = priv->addresses; |
1619 | priv->hw->wiphy->n_addresses = 1; | 1437 | priv->hw->wiphy->n_addresses = 1; |
1620 | num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS); | 1438 | num_mac = priv->eeprom_data->n_hw_addrs; |
1621 | if (num_mac > 1) { | 1439 | if (num_mac > 1) { |
1622 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, | 1440 | memcpy(priv->addresses[1].addr, priv->addresses[0].addr, |
1623 | ETH_ALEN); | 1441 | ETH_ALEN); |
@@ -1711,8 +1529,10 @@ out_destroy_workqueue: | |||
1711 | destroy_workqueue(priv->workqueue); | 1529 | destroy_workqueue(priv->workqueue); |
1712 | priv->workqueue = NULL; | 1530 | priv->workqueue = NULL; |
1713 | iwl_uninit_drv(priv); | 1531 | iwl_uninit_drv(priv); |
1532 | out_free_eeprom_blob: | ||
1533 | kfree(priv->eeprom_blob); | ||
1714 | out_free_eeprom: | 1534 | out_free_eeprom: |
1715 | iwl_eeprom_free(priv); | 1535 | iwl_free_eeprom_data(priv->eeprom_data); |
1716 | out_free_hw: | 1536 | out_free_hw: |
1717 | ieee80211_free_hw(priv->hw); | 1537 | ieee80211_free_hw(priv->hw); |
1718 | out: | 1538 | out: |
@@ -1720,7 +1540,7 @@ out: | |||
1720 | return op_mode; | 1540 | return op_mode; |
1721 | } | 1541 | } |
1722 | 1542 | ||
1723 | void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | 1543 | static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) |
1724 | { | 1544 | { |
1725 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 1545 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
1726 | 1546 | ||
@@ -1737,7 +1557,8 @@ void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1737 | priv->ucode_loaded = false; | 1557 | priv->ucode_loaded = false; |
1738 | iwl_trans_stop_device(priv->trans); | 1558 | iwl_trans_stop_device(priv->trans); |
1739 | 1559 | ||
1740 | iwl_eeprom_free(priv); | 1560 | kfree(priv->eeprom_blob); |
1561 | iwl_free_eeprom_data(priv->eeprom_data); | ||
1741 | 1562 | ||
1742 | /*netif_stop_queue(dev); */ | 1563 | /*netif_stop_queue(dev); */ |
1743 | flush_workqueue(priv->workqueue); | 1564 | flush_workqueue(priv->workqueue); |
@@ -2185,7 +2006,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
2185 | } | 2006 | } |
2186 | } | 2007 | } |
2187 | 2008 | ||
2188 | void iwl_nic_error(struct iwl_op_mode *op_mode) | 2009 | static void iwl_nic_error(struct iwl_op_mode *op_mode) |
2189 | { | 2010 | { |
2190 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2011 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2191 | 2012 | ||
@@ -2198,7 +2019,7 @@ void iwl_nic_error(struct iwl_op_mode *op_mode) | |||
2198 | iwlagn_fw_error(priv, false); | 2019 | iwlagn_fw_error(priv, false); |
2199 | } | 2020 | } |
2200 | 2021 | ||
2201 | void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | 2022 | static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) |
2202 | { | 2023 | { |
2203 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2024 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2204 | 2025 | ||
@@ -2208,9 +2029,49 @@ void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) | |||
2208 | } | 2029 | } |
2209 | } | 2030 | } |
2210 | 2031 | ||
2211 | void iwl_nic_config(struct iwl_op_mode *op_mode) | 2032 | #define EEPROM_RF_CONFIG_TYPE_MAX 0x3 |
2033 | |||
2034 | static void iwl_nic_config(struct iwl_op_mode *op_mode) | ||
2212 | { | 2035 | { |
2213 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2036 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2037 | u16 radio_cfg = priv->eeprom_data->radio_cfg; | ||
2038 | |||
2039 | /* SKU Control */ | ||
2040 | iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2041 | CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | | ||
2042 | CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP, | ||
2043 | (CSR_HW_REV_STEP(priv->trans->hw_rev) << | ||
2044 | CSR_HW_IF_CONFIG_REG_POS_MAC_STEP) | | ||
2045 | (CSR_HW_REV_DASH(priv->trans->hw_rev) << | ||
2046 | CSR_HW_IF_CONFIG_REG_POS_MAC_DASH)); | ||
2047 | |||
2048 | /* write radio config values to register */ | ||
2049 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | ||
2050 | u32 reg_val = | ||
2051 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) << | ||
2052 | CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE | | ||
2053 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) << | ||
2054 | CSR_HW_IF_CONFIG_REG_POS_PHY_STEP | | ||
2055 | EEPROM_RF_CFG_DASH_MSK(radio_cfg) << | ||
2056 | CSR_HW_IF_CONFIG_REG_POS_PHY_DASH; | ||
2057 | |||
2058 | iwl_set_bits_mask(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2059 | CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE | | ||
2060 | CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP | | ||
2061 | CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH, reg_val); | ||
2062 | |||
2063 | IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", | ||
2064 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg), | ||
2065 | EEPROM_RF_CFG_STEP_MSK(radio_cfg), | ||
2066 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
2067 | } else { | ||
2068 | WARN_ON(1); | ||
2069 | } | ||
2070 | |||
2071 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
2072 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
2073 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
2074 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
2214 | 2075 | ||
2215 | priv->lib->nic_config(priv); | 2076 | priv->lib->nic_config(priv); |
2216 | } | 2077 | } |
@@ -2223,7 +2084,7 @@ static void iwl_wimax_active(struct iwl_op_mode *op_mode) | |||
2223 | IWL_ERR(priv, "RF is used by WiMAX\n"); | 2084 | IWL_ERR(priv, "RF is used by WiMAX\n"); |
2224 | } | 2085 | } |
2225 | 2086 | ||
2226 | void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2087 | static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) |
2227 | { | 2088 | { |
2228 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2089 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2229 | int mq = priv->queue_to_mac80211[queue]; | 2090 | int mq = priv->queue_to_mac80211[queue]; |
@@ -2242,7 +2103,7 @@ void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) | |||
2242 | ieee80211_stop_queue(priv->hw, mq); | 2103 | ieee80211_stop_queue(priv->hw, mq); |
2243 | } | 2104 | } |
2244 | 2105 | ||
2245 | void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) | 2106 | static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) |
2246 | { | 2107 | { |
2247 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2108 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2248 | int mq = priv->queue_to_mac80211[queue]; | 2109 | int mq = priv->queue_to_mac80211[queue]; |
@@ -2282,16 +2143,17 @@ void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) | |||
2282 | priv->passive_no_rx = false; | 2143 | priv->passive_no_rx = false; |
2283 | } | 2144 | } |
2284 | 2145 | ||
2285 | void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) | 2146 | static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) |
2286 | { | 2147 | { |
2148 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | ||
2287 | struct ieee80211_tx_info *info; | 2149 | struct ieee80211_tx_info *info; |
2288 | 2150 | ||
2289 | info = IEEE80211_SKB_CB(skb); | 2151 | info = IEEE80211_SKB_CB(skb); |
2290 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | 2152 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
2291 | dev_kfree_skb_any(skb); | 2153 | dev_kfree_skb_any(skb); |
2292 | } | 2154 | } |
2293 | 2155 | ||
2294 | void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | 2156 | static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) |
2295 | { | 2157 | { |
2296 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); | 2158 | struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); |
2297 | 2159 | ||
@@ -2303,7 +2165,7 @@ void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) | |||
2303 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); | 2165 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); |
2304 | } | 2166 | } |
2305 | 2167 | ||
2306 | const struct iwl_op_mode_ops iwl_dvm_ops = { | 2168 | static const struct iwl_op_mode_ops iwl_dvm_ops = { |
2307 | .start = iwl_op_mode_dvm_start, | 2169 | .start = iwl_op_mode_dvm_start, |
2308 | .stop = iwl_op_mode_dvm_stop, | 2170 | .stop = iwl_op_mode_dvm_stop, |
2309 | .rx = iwl_rx_dispatch, | 2171 | .rx = iwl_rx_dispatch, |
@@ -2322,9 +2184,6 @@ const struct iwl_op_mode_ops iwl_dvm_ops = { | |||
2322 | * driver and module entry point | 2184 | * driver and module entry point |
2323 | * | 2185 | * |
2324 | *****************************************************************************/ | 2186 | *****************************************************************************/ |
2325 | |||
2326 | struct kmem_cache *iwl_tx_cmd_pool; | ||
2327 | |||
2328 | static int __init iwl_init(void) | 2187 | static int __init iwl_init(void) |
2329 | { | 2188 | { |
2330 | 2189 | ||
@@ -2332,36 +2191,25 @@ static int __init iwl_init(void) | |||
2332 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 2191 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
2333 | pr_info(DRV_COPYRIGHT "\n"); | 2192 | pr_info(DRV_COPYRIGHT "\n"); |
2334 | 2193 | ||
2335 | iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", | ||
2336 | sizeof(struct iwl_device_cmd), | ||
2337 | sizeof(void *), 0, NULL); | ||
2338 | if (!iwl_tx_cmd_pool) | ||
2339 | return -ENOMEM; | ||
2340 | |||
2341 | ret = iwlagn_rate_control_register(); | 2194 | ret = iwlagn_rate_control_register(); |
2342 | if (ret) { | 2195 | if (ret) { |
2343 | pr_err("Unable to register rate control algorithm: %d\n", ret); | 2196 | pr_err("Unable to register rate control algorithm: %d\n", ret); |
2344 | goto error_rc_register; | 2197 | return ret; |
2345 | } | 2198 | } |
2346 | 2199 | ||
2347 | ret = iwl_pci_register_driver(); | 2200 | ret = iwl_opmode_register("iwldvm", &iwl_dvm_ops); |
2348 | if (ret) | 2201 | if (ret) { |
2349 | goto error_pci_register; | 2202 | pr_err("Unable to register op_mode: %d\n", ret); |
2350 | return ret; | 2203 | iwlagn_rate_control_unregister(); |
2204 | } | ||
2351 | 2205 | ||
2352 | error_pci_register: | ||
2353 | iwlagn_rate_control_unregister(); | ||
2354 | error_rc_register: | ||
2355 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
2356 | return ret; | 2206 | return ret; |
2357 | } | 2207 | } |
2208 | module_init(iwl_init); | ||
2358 | 2209 | ||
2359 | static void __exit iwl_exit(void) | 2210 | static void __exit iwl_exit(void) |
2360 | { | 2211 | { |
2361 | iwl_pci_unregister_driver(); | 2212 | iwl_opmode_deregister("iwldvm"); |
2362 | iwlagn_rate_control_unregister(); | 2213 | iwlagn_rate_control_unregister(); |
2363 | kmem_cache_destroy(iwl_tx_cmd_pool); | ||
2364 | } | 2214 | } |
2365 | |||
2366 | module_exit(iwl_exit); | 2215 | module_exit(iwl_exit); |
2367 | module_init(iwl_init); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index 544ddf17f5bd..518cf3715809 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c | |||
@@ -31,18 +31,15 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | |||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | #include "iwl-eeprom.h" | ||
38 | #include "iwl-dev.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
41 | #include "iwl-commands.h" | ||
42 | #include "iwl-debug.h" | 36 | #include "iwl-debug.h" |
43 | #include "iwl-power.h" | ||
44 | #include "iwl-trans.h" | 37 | #include "iwl-trans.h" |
45 | #include "iwl-modparams.h" | 38 | #include "iwl-modparams.h" |
39 | #include "dev.h" | ||
40 | #include "agn.h" | ||
41 | #include "commands.h" | ||
42 | #include "power.h" | ||
46 | 43 | ||
47 | /* | 44 | /* |
48 | * Setting power level allows the card to go to sleep when not busy. | 45 | * Setting power level allows the card to go to sleep when not busy. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/dvm/power.h index 21afc92efacb..a2cee7f04848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/dvm/power.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #ifndef __iwl_power_setting_h__ | 28 | #ifndef __iwl_power_setting_h__ |
29 | #define __iwl_power_setting_h__ | 29 | #define __iwl_power_setting_h__ |
30 | 30 | ||
31 | #include "iwl-commands.h" | 31 | #include "commands.h" |
32 | 32 | ||
33 | struct iwl_power_mgr { | 33 | struct iwl_power_mgr { |
34 | struct iwl_powertable_cmd sleep_cmd; | 34 | struct iwl_powertable_cmd sleep_cmd; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 8cebd7c363fc..6fddd2785e6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -35,10 +35,8 @@ | |||
35 | 35 | ||
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | 37 | ||
38 | #include "iwl-dev.h" | 38 | #include "dev.h" |
39 | #include "iwl-agn.h" | 39 | #include "agn.h" |
40 | #include "iwl-op-mode.h" | ||
41 | #include "iwl-modparams.h" | ||
42 | 40 | ||
43 | #define RS_NAME "iwl-agn-rs" | 41 | #define RS_NAME "iwl-agn-rs" |
44 | 42 | ||
@@ -819,7 +817,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, | |||
819 | 817 | ||
820 | if (num_of_ant(tbl->ant_type) > 1) | 818 | if (num_of_ant(tbl->ant_type) > 1) |
821 | tbl->ant_type = | 819 | tbl->ant_type = |
822 | first_antenna(priv->hw_params.valid_tx_ant); | 820 | first_antenna(priv->eeprom_data->valid_tx_ant); |
823 | 821 | ||
824 | tbl->is_ht40 = 0; | 822 | tbl->is_ht40 = 0; |
825 | tbl->is_SGI = 0; | 823 | tbl->is_SGI = 0; |
@@ -1447,7 +1445,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1447 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1445 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1448 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1446 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1449 | u8 start_action; | 1447 | u8 start_action; |
1450 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1448 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1451 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1449 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1452 | int ret = 0; | 1450 | int ret = 0; |
1453 | u8 update_search_tbl_counter = 0; | 1451 | u8 update_search_tbl_counter = 0; |
@@ -1465,7 +1463,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1465 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1463 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1466 | /* avoid antenna B and MIMO */ | 1464 | /* avoid antenna B and MIMO */ |
1467 | valid_tx_ant = | 1465 | valid_tx_ant = |
1468 | first_antenna(priv->hw_params.valid_tx_ant); | 1466 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1469 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && | 1467 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && |
1470 | tbl->action != IWL_LEGACY_SWITCH_SISO) | 1468 | tbl->action != IWL_LEGACY_SWITCH_SISO) |
1471 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1469 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
@@ -1489,7 +1487,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, | |||
1489 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1487 | else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1490 | tbl->action = IWL_LEGACY_SWITCH_SISO; | 1488 | tbl->action = IWL_LEGACY_SWITCH_SISO; |
1491 | valid_tx_ant = | 1489 | valid_tx_ant = |
1492 | first_antenna(priv->hw_params.valid_tx_ant); | 1490 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1493 | } | 1491 | } |
1494 | 1492 | ||
1495 | start_action = tbl->action; | 1493 | start_action = tbl->action; |
@@ -1623,7 +1621,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1623 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1621 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1624 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1622 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1625 | u8 start_action; | 1623 | u8 start_action; |
1626 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1624 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1627 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1625 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1628 | u8 update_search_tbl_counter = 0; | 1626 | u8 update_search_tbl_counter = 0; |
1629 | int ret; | 1627 | int ret; |
@@ -1641,7 +1639,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1641 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: | 1639 | case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: |
1642 | /* avoid antenna B and MIMO */ | 1640 | /* avoid antenna B and MIMO */ |
1643 | valid_tx_ant = | 1641 | valid_tx_ant = |
1644 | first_antenna(priv->hw_params.valid_tx_ant); | 1642 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1645 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) | 1643 | if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) |
1646 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1644 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1647 | break; | 1645 | break; |
@@ -1659,7 +1657,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, | |||
1659 | /* configure as 1x1 if bt full concurrency */ | 1657 | /* configure as 1x1 if bt full concurrency */ |
1660 | if (priv->bt_full_concurrent) { | 1658 | if (priv->bt_full_concurrent) { |
1661 | valid_tx_ant = | 1659 | valid_tx_ant = |
1662 | first_antenna(priv->hw_params.valid_tx_ant); | 1660 | first_antenna(priv->eeprom_data->valid_tx_ant); |
1663 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) | 1661 | if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) |
1664 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; | 1662 | tbl->action = IWL_SISO_SWITCH_ANTENNA1; |
1665 | } | 1663 | } |
@@ -1795,7 +1793,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, | |||
1795 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1793 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1796 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1794 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1797 | u8 start_action; | 1795 | u8 start_action; |
1798 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1796 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1799 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1797 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1800 | u8 update_search_tbl_counter = 0; | 1798 | u8 update_search_tbl_counter = 0; |
1801 | int ret; | 1799 | int ret; |
@@ -1965,7 +1963,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, | |||
1965 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - | 1963 | u32 sz = (sizeof(struct iwl_scale_tbl_info) - |
1966 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); | 1964 | (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); |
1967 | u8 start_action; | 1965 | u8 start_action; |
1968 | u8 valid_tx_ant = priv->hw_params.valid_tx_ant; | 1966 | u8 valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
1969 | u8 tx_chains_num = priv->hw_params.tx_chains_num; | 1967 | u8 tx_chains_num = priv->hw_params.tx_chains_num; |
1970 | int ret; | 1968 | int ret; |
1971 | u8 update_search_tbl_counter = 0; | 1969 | u8 update_search_tbl_counter = 0; |
@@ -2699,7 +2697,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2699 | 2697 | ||
2700 | i = lq_sta->last_txrate_idx; | 2698 | i = lq_sta->last_txrate_idx; |
2701 | 2699 | ||
2702 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 2700 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
2703 | 2701 | ||
2704 | if (!lq_sta->search_better_tbl) | 2702 | if (!lq_sta->search_better_tbl) |
2705 | active_tbl = lq_sta->active_tbl; | 2703 | active_tbl = lq_sta->active_tbl; |
@@ -2893,15 +2891,15 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i | |||
2893 | 2891 | ||
2894 | /* These values will be overridden later */ | 2892 | /* These values will be overridden later */ |
2895 | lq_sta->lq.general_params.single_stream_ant_msk = | 2893 | lq_sta->lq.general_params.single_stream_ant_msk = |
2896 | first_antenna(priv->hw_params.valid_tx_ant); | 2894 | first_antenna(priv->eeprom_data->valid_tx_ant); |
2897 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2895 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2898 | priv->hw_params.valid_tx_ant & | 2896 | priv->eeprom_data->valid_tx_ant & |
2899 | ~first_antenna(priv->hw_params.valid_tx_ant); | 2897 | ~first_antenna(priv->eeprom_data->valid_tx_ant); |
2900 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { | 2898 | if (!lq_sta->lq.general_params.dual_stream_ant_msk) { |
2901 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; | 2899 | lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB; |
2902 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { | 2900 | } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { |
2903 | lq_sta->lq.general_params.dual_stream_ant_msk = | 2901 | lq_sta->lq.general_params.dual_stream_ant_msk = |
2904 | priv->hw_params.valid_tx_ant; | 2902 | priv->eeprom_data->valid_tx_ant; |
2905 | } | 2903 | } |
2906 | 2904 | ||
2907 | /* as default allow aggregation for all tids */ | 2905 | /* as default allow aggregation for all tids */ |
@@ -2947,7 +2945,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2947 | if (priv && priv->bt_full_concurrent) { | 2945 | if (priv && priv->bt_full_concurrent) { |
2948 | /* 1x1 only */ | 2946 | /* 1x1 only */ |
2949 | tbl_type.ant_type = | 2947 | tbl_type.ant_type = |
2950 | first_antenna(priv->hw_params.valid_tx_ant); | 2948 | first_antenna(priv->eeprom_data->valid_tx_ant); |
2951 | } | 2949 | } |
2952 | 2950 | ||
2953 | /* How many times should we repeat the initial rate? */ | 2951 | /* How many times should we repeat the initial rate? */ |
@@ -2979,7 +2977,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2979 | if (priv->bt_full_concurrent) | 2977 | if (priv->bt_full_concurrent) |
2980 | valid_tx_ant = ANT_A; | 2978 | valid_tx_ant = ANT_A; |
2981 | else | 2979 | else |
2982 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 2980 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
2983 | } | 2981 | } |
2984 | 2982 | ||
2985 | /* Fill rest of rate table */ | 2983 | /* Fill rest of rate table */ |
@@ -3013,7 +3011,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
3013 | if (priv && priv->bt_full_concurrent) { | 3011 | if (priv && priv->bt_full_concurrent) { |
3014 | /* 1x1 only */ | 3012 | /* 1x1 only */ |
3015 | tbl_type.ant_type = | 3013 | tbl_type.ant_type = |
3016 | first_antenna(priv->hw_params.valid_tx_ant); | 3014 | first_antenna(priv->eeprom_data->valid_tx_ant); |
3017 | } | 3015 | } |
3018 | 3016 | ||
3019 | /* Indicate to uCode which entries might be MIMO. | 3017 | /* Indicate to uCode which entries might be MIMO. |
@@ -3100,7 +3098,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
3100 | u8 ant_sel_tx; | 3098 | u8 ant_sel_tx; |
3101 | 3099 | ||
3102 | priv = lq_sta->drv; | 3100 | priv = lq_sta->drv; |
3103 | valid_tx_ant = priv->hw_params.valid_tx_ant; | 3101 | valid_tx_ant = priv->eeprom_data->valid_tx_ant; |
3104 | if (lq_sta->dbg_fixed_rate) { | 3102 | if (lq_sta->dbg_fixed_rate) { |
3105 | ant_sel_tx = | 3103 | ant_sel_tx = |
3106 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) | 3104 | ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) |
@@ -3171,9 +3169,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3171 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", | 3169 | desc += sprintf(buff+desc, "fixed rate 0x%X\n", |
3172 | lq_sta->dbg_fixed_rate); | 3170 | lq_sta->dbg_fixed_rate); |
3173 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", | 3171 | desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", |
3174 | (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", | 3172 | (priv->eeprom_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", |
3175 | (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", | 3173 | (priv->eeprom_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", |
3176 | (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : ""); | 3174 | (priv->eeprom_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); |
3177 | desc += sprintf(buff+desc, "lq type %s\n", | 3175 | desc += sprintf(buff+desc, "lq type %s\n", |
3178 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); | 3176 | (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); |
3179 | if (is_Ht(tbl->lq_type)) { | 3177 | if (is_Ht(tbl->lq_type)) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h index 82d02e1ae89f..ad3aea8f626a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h | |||
@@ -29,9 +29,10 @@ | |||
29 | 29 | ||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | 31 | ||
32 | #include "iwl-commands.h" | ||
33 | #include "iwl-config.h" | 32 | #include "iwl-config.h" |
34 | 33 | ||
34 | #include "commands.h" | ||
35 | |||
35 | struct iwl_rate_info { | 36 | struct iwl_rate_info { |
36 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ | 37 | u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ |
37 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ | 38 | u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index 403de96f9747..0ed90bb8b56a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -32,12 +32,10 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <net/mac80211.h> | 33 | #include <net/mac80211.h> |
34 | #include <asm/unaligned.h> | 34 | #include <asm/unaligned.h> |
35 | #include "iwl-eeprom.h" | ||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
38 | #include "iwl-agn-calib.h" | 36 | #include "dev.h" |
39 | #include "iwl-agn.h" | 37 | #include "calib.h" |
40 | #include "iwl-modparams.h" | 38 | #include "agn.h" |
41 | 39 | ||
42 | #define IWL_CMD_ENTRY(x) [x] = #x | 40 | #define IWL_CMD_ENTRY(x) [x] = #x |
43 | 41 | ||
@@ -1012,6 +1010,8 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
1012 | rx_status.flag |= RX_FLAG_40MHZ; | 1010 | rx_status.flag |= RX_FLAG_40MHZ; |
1013 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 1011 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
1014 | rx_status.flag |= RX_FLAG_SHORT_GI; | 1012 | rx_status.flag |= RX_FLAG_SHORT_GI; |
1013 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
1014 | rx_status.flag |= RX_FLAG_HT_GF; | ||
1015 | 1015 | ||
1016 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, | 1016 | iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status, |
1017 | rxb, &rx_status); | 1017 | rxb, &rx_status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 0a3aa7c83003..6ee940f497f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
@@ -25,11 +25,11 @@ | |||
25 | *****************************************************************************/ | 25 | *****************************************************************************/ |
26 | 26 | ||
27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
28 | #include "iwl-dev.h" | ||
29 | #include "iwl-agn.h" | ||
30 | #include "iwl-agn-calib.h" | ||
31 | #include "iwl-trans.h" | 28 | #include "iwl-trans.h" |
32 | #include "iwl-modparams.h" | 29 | #include "iwl-modparams.h" |
30 | #include "dev.h" | ||
31 | #include "agn.h" | ||
32 | #include "calib.h" | ||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * initialize rxon structure with default values from eeprom | 35 | * initialize rxon structure with default values from eeprom |
@@ -37,8 +37,6 @@ | |||
37 | void iwl_connection_init_rx_config(struct iwl_priv *priv, | 37 | void iwl_connection_init_rx_config(struct iwl_priv *priv, |
38 | struct iwl_rxon_context *ctx) | 38 | struct iwl_rxon_context *ctx) |
39 | { | 39 | { |
40 | const struct iwl_channel_info *ch_info; | ||
41 | |||
42 | memset(&ctx->staging, 0, sizeof(ctx->staging)); | 40 | memset(&ctx->staging, 0, sizeof(ctx->staging)); |
43 | 41 | ||
44 | if (!ctx->vif) { | 42 | if (!ctx->vif) { |
@@ -80,14 +78,8 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, | |||
80 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 78 | ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
81 | #endif | 79 | #endif |
82 | 80 | ||
83 | ch_info = iwl_get_channel_info(priv, priv->band, | 81 | ctx->staging.channel = cpu_to_le16(priv->hw->conf.channel->hw_value); |
84 | le16_to_cpu(ctx->active.channel)); | 82 | priv->band = priv->hw->conf.channel->band; |
85 | |||
86 | if (!ch_info) | ||
87 | ch_info = &priv->channel_info[0]; | ||
88 | |||
89 | ctx->staging.channel = cpu_to_le16(ch_info->channel); | ||
90 | priv->band = ch_info->band; | ||
91 | 83 | ||
92 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); | 84 | iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); |
93 | 85 | ||
@@ -175,7 +167,8 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, | |||
175 | return ret; | 167 | return ret; |
176 | } | 168 | } |
177 | 169 | ||
178 | void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | 170 | static void iwlagn_update_qos(struct iwl_priv *priv, |
171 | struct iwl_rxon_context *ctx) | ||
179 | { | 172 | { |
180 | int ret; | 173 | int ret; |
181 | 174 | ||
@@ -202,8 +195,8 @@ void iwlagn_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
202 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); | 195 | IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n"); |
203 | } | 196 | } |
204 | 197 | ||
205 | int iwlagn_update_beacon(struct iwl_priv *priv, | 198 | static int iwlagn_update_beacon(struct iwl_priv *priv, |
206 | struct ieee80211_vif *vif) | 199 | struct ieee80211_vif *vif) |
207 | { | 200 | { |
208 | lockdep_assert_held(&priv->mutex); | 201 | lockdep_assert_held(&priv->mutex); |
209 | 202 | ||
@@ -215,7 +208,7 @@ int iwlagn_update_beacon(struct iwl_priv *priv, | |||
215 | } | 208 | } |
216 | 209 | ||
217 | static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | 210 | static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, |
218 | struct iwl_rxon_context *ctx) | 211 | struct iwl_rxon_context *ctx) |
219 | { | 212 | { |
220 | int ret = 0; | 213 | int ret = 0; |
221 | struct iwl_rxon_assoc_cmd rxon_assoc; | 214 | struct iwl_rxon_assoc_cmd rxon_assoc; |
@@ -427,10 +420,10 @@ static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
427 | return -EINVAL; | 420 | return -EINVAL; |
428 | } | 421 | } |
429 | 422 | ||
430 | if (tx_power > priv->tx_power_device_lmt) { | 423 | if (tx_power > DIV_ROUND_UP(priv->eeprom_data->max_tx_pwr_half_dbm, 2)) { |
431 | IWL_WARN(priv, | 424 | IWL_WARN(priv, |
432 | "Requested user TXPOWER %d above upper limit %d.\n", | 425 | "Requested user TXPOWER %d above upper limit %d.\n", |
433 | tx_power, priv->tx_power_device_lmt); | 426 | tx_power, priv->eeprom_data->max_tx_pwr_half_dbm); |
434 | return -EINVAL; | 427 | return -EINVAL; |
435 | } | 428 | } |
436 | 429 | ||
@@ -863,8 +856,8 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv, | |||
863 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 856 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
864 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 857 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
865 | */ | 858 | */ |
866 | int iwl_full_rxon_required(struct iwl_priv *priv, | 859 | static int iwl_full_rxon_required(struct iwl_priv *priv, |
867 | struct iwl_rxon_context *ctx) | 860 | struct iwl_rxon_context *ctx) |
868 | { | 861 | { |
869 | const struct iwl_rxon_cmd *staging = &ctx->staging; | 862 | const struct iwl_rxon_cmd *staging = &ctx->staging; |
870 | const struct iwl_rxon_cmd *active = &ctx->active; | 863 | const struct iwl_rxon_cmd *active = &ctx->active; |
@@ -1189,7 +1182,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1189 | struct iwl_rxon_context *ctx; | 1182 | struct iwl_rxon_context *ctx; |
1190 | struct ieee80211_conf *conf = &hw->conf; | 1183 | struct ieee80211_conf *conf = &hw->conf; |
1191 | struct ieee80211_channel *channel = conf->channel; | 1184 | struct ieee80211_channel *channel = conf->channel; |
1192 | const struct iwl_channel_info *ch_info; | ||
1193 | int ret = 0; | 1185 | int ret = 0; |
1194 | 1186 | ||
1195 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); | 1187 | IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed); |
@@ -1223,14 +1215,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1223 | } | 1215 | } |
1224 | 1216 | ||
1225 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1217 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1226 | ch_info = iwl_get_channel_info(priv, channel->band, | ||
1227 | channel->hw_value); | ||
1228 | if (!is_channel_valid(ch_info)) { | ||
1229 | IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); | ||
1230 | ret = -EINVAL; | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | for_each_context(priv, ctx) { | 1218 | for_each_context(priv, ctx) { |
1235 | /* Configure HT40 channels */ | 1219 | /* Configure HT40 channels */ |
1236 | if (ctx->ht.enabled != conf_is_ht(conf)) | 1220 | if (ctx->ht.enabled != conf_is_ht(conf)) |
@@ -1294,9 +1278,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
1294 | return ret; | 1278 | return ret; |
1295 | } | 1279 | } |
1296 | 1280 | ||
1297 | void iwlagn_check_needed_chains(struct iwl_priv *priv, | 1281 | static void iwlagn_check_needed_chains(struct iwl_priv *priv, |
1298 | struct iwl_rxon_context *ctx, | 1282 | struct iwl_rxon_context *ctx, |
1299 | struct ieee80211_bss_conf *bss_conf) | 1283 | struct ieee80211_bss_conf *bss_conf) |
1300 | { | 1284 | { |
1301 | struct ieee80211_vif *vif = ctx->vif; | 1285 | struct ieee80211_vif *vif = ctx->vif; |
1302 | struct iwl_rxon_context *tmp; | 1286 | struct iwl_rxon_context *tmp; |
@@ -1388,7 +1372,7 @@ void iwlagn_check_needed_chains(struct iwl_priv *priv, | |||
1388 | ht_conf->single_chain_sufficient = !need_multiple; | 1372 | ht_conf->single_chain_sufficient = !need_multiple; |
1389 | } | 1373 | } |
1390 | 1374 | ||
1391 | void iwlagn_chain_noise_reset(struct iwl_priv *priv) | 1375 | static void iwlagn_chain_noise_reset(struct iwl_priv *priv) |
1392 | { | 1376 | { |
1393 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 1377 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
1394 | int ret; | 1378 | int ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 031d8e21f82f..2f271c96ed39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c | |||
@@ -30,11 +30,8 @@ | |||
30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
31 | #include <net/mac80211.h> | 31 | #include <net/mac80211.h> |
32 | 32 | ||
33 | #include "iwl-eeprom.h" | 33 | #include "dev.h" |
34 | #include "iwl-dev.h" | 34 | #include "agn.h" |
35 | #include "iwl-io.h" | ||
36 | #include "iwl-agn.h" | ||
37 | #include "iwl-trans.h" | ||
38 | 35 | ||
39 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | 36 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after |
40 | * sending probe req. This should be set long enough to hear probe responses | 37 | * sending probe req. This should be set long enough to hear probe responses |
@@ -67,7 +64,6 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) | |||
67 | * to receive scan abort command or it does not perform | 64 | * to receive scan abort command or it does not perform |
68 | * hardware scan currently */ | 65 | * hardware scan currently */ |
69 | if (!test_bit(STATUS_READY, &priv->status) || | 66 | if (!test_bit(STATUS_READY, &priv->status) || |
70 | !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || | ||
71 | !test_bit(STATUS_SCAN_HW, &priv->status) || | 67 | !test_bit(STATUS_SCAN_HW, &priv->status) || |
72 | test_bit(STATUS_FW_ERROR, &priv->status)) | 68 | test_bit(STATUS_FW_ERROR, &priv->status)) |
73 | return -EIO; | 69 | return -EIO; |
@@ -101,11 +97,8 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) | |||
101 | ieee80211_scan_completed(priv->hw, aborted); | 97 | ieee80211_scan_completed(priv->hw, aborted); |
102 | } | 98 | } |
103 | 99 | ||
104 | if (priv->scan_type == IWL_SCAN_ROC) { | 100 | if (priv->scan_type == IWL_SCAN_ROC) |
105 | ieee80211_remain_on_channel_expired(priv->hw); | 101 | iwl_scan_roc_expired(priv); |
106 | priv->hw_roc_channel = NULL; | ||
107 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); | ||
108 | } | ||
109 | 102 | ||
110 | priv->scan_type = IWL_SCAN_NORMAL; | 103 | priv->scan_type = IWL_SCAN_NORMAL; |
111 | priv->scan_vif = NULL; | 104 | priv->scan_vif = NULL; |
@@ -134,11 +127,8 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) | |||
134 | goto out_settings; | 127 | goto out_settings; |
135 | } | 128 | } |
136 | 129 | ||
137 | if (priv->scan_type == IWL_SCAN_ROC) { | 130 | if (priv->scan_type == IWL_SCAN_ROC) |
138 | ieee80211_remain_on_channel_expired(priv->hw); | 131 | iwl_scan_roc_expired(priv); |
139 | priv->hw_roc_channel = NULL; | ||
140 | schedule_delayed_work(&priv->hw_roc_disable_work, 10 * HZ); | ||
141 | } | ||
142 | 132 | ||
143 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { | 133 | if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) { |
144 | int err; | 134 | int err; |
@@ -453,27 +443,17 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | |||
453 | 443 | ||
454 | /* Return valid, unused, channel for a passive scan to reset the RF */ | 444 | /* Return valid, unused, channel for a passive scan to reset the RF */ |
455 | static u8 iwl_get_single_channel_number(struct iwl_priv *priv, | 445 | static u8 iwl_get_single_channel_number(struct iwl_priv *priv, |
456 | enum ieee80211_band band) | 446 | enum ieee80211_band band) |
457 | { | 447 | { |
458 | const struct iwl_channel_info *ch_info; | 448 | struct ieee80211_supported_band *sband = priv->hw->wiphy->bands[band]; |
459 | int i; | ||
460 | u8 channel = 0; | ||
461 | u8 min, max; | ||
462 | struct iwl_rxon_context *ctx; | 449 | struct iwl_rxon_context *ctx; |
450 | int i; | ||
463 | 451 | ||
464 | if (band == IEEE80211_BAND_5GHZ) { | 452 | for (i = 0; i < sband->n_channels; i++) { |
465 | min = 14; | ||
466 | max = priv->channel_count; | ||
467 | } else { | ||
468 | min = 0; | ||
469 | max = 14; | ||
470 | } | ||
471 | |||
472 | for (i = min; i < max; i++) { | ||
473 | bool busy = false; | 453 | bool busy = false; |
474 | 454 | ||
475 | for_each_context(priv, ctx) { | 455 | for_each_context(priv, ctx) { |
476 | busy = priv->channel_info[i].channel == | 456 | busy = sband->channels[i].hw_value == |
477 | le16_to_cpu(ctx->staging.channel); | 457 | le16_to_cpu(ctx->staging.channel); |
478 | if (busy) | 458 | if (busy) |
479 | break; | 459 | break; |
@@ -482,13 +462,11 @@ static u8 iwl_get_single_channel_number(struct iwl_priv *priv, | |||
482 | if (busy) | 462 | if (busy) |
483 | continue; | 463 | continue; |
484 | 464 | ||
485 | channel = priv->channel_info[i].channel; | 465 | if (!(sband->channels[i].flags & IEEE80211_CHAN_DISABLED)) |
486 | ch_info = iwl_get_channel_info(priv, band, channel); | 466 | return sband->channels[i].hw_value; |
487 | if (is_channel_valid(ch_info)) | ||
488 | break; | ||
489 | } | 467 | } |
490 | 468 | ||
491 | return channel; | 469 | return 0; |
492 | } | 470 | } |
493 | 471 | ||
494 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, | 472 | static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, |
@@ -540,7 +518,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
540 | { | 518 | { |
541 | struct ieee80211_channel *chan; | 519 | struct ieee80211_channel *chan; |
542 | const struct ieee80211_supported_band *sband; | 520 | const struct ieee80211_supported_band *sband; |
543 | const struct iwl_channel_info *ch_info; | ||
544 | u16 passive_dwell = 0; | 521 | u16 passive_dwell = 0; |
545 | u16 active_dwell = 0; | 522 | u16 active_dwell = 0; |
546 | int added, i; | 523 | int added, i; |
@@ -565,16 +542,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
565 | channel = chan->hw_value; | 542 | channel = chan->hw_value; |
566 | scan_ch->channel = cpu_to_le16(channel); | 543 | scan_ch->channel = cpu_to_le16(channel); |
567 | 544 | ||
568 | ch_info = iwl_get_channel_info(priv, band, channel); | 545 | if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
569 | if (!is_channel_valid(ch_info)) { | ||
570 | IWL_DEBUG_SCAN(priv, | ||
571 | "Channel %d is INVALID for this band.\n", | ||
572 | channel); | ||
573 | continue; | ||
574 | } | ||
575 | |||
576 | if (!is_active || is_channel_passive(ch_info) || | ||
577 | (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) | ||
578 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; | 546 | scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; |
579 | else | 547 | else |
580 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; | 548 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; |
@@ -678,12 +646,12 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
678 | u16 rx_chain = 0; | 646 | u16 rx_chain = 0; |
679 | enum ieee80211_band band; | 647 | enum ieee80211_band band; |
680 | u8 n_probes = 0; | 648 | u8 n_probes = 0; |
681 | u8 rx_ant = priv->hw_params.valid_rx_ant; | 649 | u8 rx_ant = priv->eeprom_data->valid_rx_ant; |
682 | u8 rate; | 650 | u8 rate; |
683 | bool is_active = false; | 651 | bool is_active = false; |
684 | int chan_mod; | 652 | int chan_mod; |
685 | u8 active_chains; | 653 | u8 active_chains; |
686 | u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; | 654 | u8 scan_tx_antennas = priv->eeprom_data->valid_tx_ant; |
687 | int ret; | 655 | int ret; |
688 | int scan_cmd_size = sizeof(struct iwl_scan_cmd) + | 656 | int scan_cmd_size = sizeof(struct iwl_scan_cmd) + |
689 | MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + | 657 | MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) + |
@@ -893,7 +861,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
893 | 861 | ||
894 | /* MIMO is not used here, but value is required */ | 862 | /* MIMO is not used here, but value is required */ |
895 | rx_chain |= | 863 | rx_chain |= |
896 | priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; | 864 | priv->eeprom_data->valid_rx_ant << RXON_RX_CHAIN_VALID_POS; |
897 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | 865 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; |
898 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; | 866 | rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; |
899 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; | 867 | rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; |
@@ -994,8 +962,10 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
994 | set_bit(STATUS_SCAN_HW, &priv->status); | 962 | set_bit(STATUS_SCAN_HW, &priv->status); |
995 | 963 | ||
996 | ret = iwlagn_set_pan_params(priv); | 964 | ret = iwlagn_set_pan_params(priv); |
997 | if (ret) | 965 | if (ret) { |
966 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
998 | return ret; | 967 | return ret; |
968 | } | ||
999 | 969 | ||
1000 | ret = iwl_dvm_send_cmd(priv, &cmd); | 970 | ret = iwl_dvm_send_cmd(priv, &cmd); |
1001 | if (ret) { | 971 | if (ret) { |
@@ -1008,7 +978,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1008 | 978 | ||
1009 | void iwl_init_scan_params(struct iwl_priv *priv) | 979 | void iwl_init_scan_params(struct iwl_priv *priv) |
1010 | { | 980 | { |
1011 | u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1; | 981 | u8 ant_idx = fls(priv->eeprom_data->valid_tx_ant) - 1; |
1012 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) | 982 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) |
1013 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; | 983 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx; |
1014 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) | 984 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) |
@@ -1158,3 +1128,40 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) | |||
1158 | mutex_unlock(&priv->mutex); | 1128 | mutex_unlock(&priv->mutex); |
1159 | } | 1129 | } |
1160 | } | 1130 | } |
1131 | |||
1132 | void iwl_scan_roc_expired(struct iwl_priv *priv) | ||
1133 | { | ||
1134 | /* | ||
1135 | * The status bit should be set here, to prevent a race | ||
1136 | * where the atomic_read returns 1, but before the execution continues | ||
1137 | * iwl_scan_offchannel_skb_status() checks if the status bit is set | ||
1138 | */ | ||
1139 | set_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); | ||
1140 | |||
1141 | if (atomic_read(&priv->num_aux_in_flight) == 0) { | ||
1142 | ieee80211_remain_on_channel_expired(priv->hw); | ||
1143 | priv->hw_roc_channel = NULL; | ||
1144 | schedule_delayed_work(&priv->hw_roc_disable_work, | ||
1145 | 10 * HZ); | ||
1146 | |||
1147 | clear_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status); | ||
1148 | } else { | ||
1149 | IWL_DEBUG_SCAN(priv, "ROC done with %d frames in aux\n", | ||
1150 | atomic_read(&priv->num_aux_in_flight)); | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1154 | void iwl_scan_offchannel_skb(struct iwl_priv *priv) | ||
1155 | { | ||
1156 | WARN_ON(!priv->hw_roc_start_notified); | ||
1157 | atomic_inc(&priv->num_aux_in_flight); | ||
1158 | } | ||
1159 | |||
1160 | void iwl_scan_offchannel_skb_status(struct iwl_priv *priv) | ||
1161 | { | ||
1162 | if (atomic_dec_return(&priv->num_aux_in_flight) == 0 && | ||
1163 | test_bit(STATUS_SCAN_ROC_EXPIRED, &priv->status)) { | ||
1164 | IWL_DEBUG_SCAN(priv, "0 aux frames. Calling ROC expired\n"); | ||
1165 | iwl_scan_roc_expired(priv); | ||
1166 | } | ||
1167 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index eb6a8eaf42fc..b29b798f7550 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
@@ -28,10 +28,9 @@ | |||
28 | *****************************************************************************/ | 28 | *****************************************************************************/ |
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | |||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-agn.h" | ||
34 | #include "iwl-trans.h" | 31 | #include "iwl-trans.h" |
32 | #include "dev.h" | ||
33 | #include "agn.h" | ||
35 | 34 | ||
36 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 35 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
37 | 36 | ||
@@ -171,26 +170,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
171 | return cmd.handler_status; | 170 | return cmd.handler_status; |
172 | } | 171 | } |
173 | 172 | ||
174 | static bool iwl_is_channel_extension(struct iwl_priv *priv, | ||
175 | enum ieee80211_band band, | ||
176 | u16 channel, u8 extension_chan_offset) | ||
177 | { | ||
178 | const struct iwl_channel_info *ch_info; | ||
179 | |||
180 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
181 | if (!is_channel_valid(ch_info)) | ||
182 | return false; | ||
183 | |||
184 | if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) | ||
185 | return !(ch_info->ht40_extension_channel & | ||
186 | IEEE80211_CHAN_NO_HT40PLUS); | ||
187 | else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) | ||
188 | return !(ch_info->ht40_extension_channel & | ||
189 | IEEE80211_CHAN_NO_HT40MINUS); | ||
190 | |||
191 | return false; | ||
192 | } | ||
193 | |||
194 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | 173 | bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, |
195 | struct iwl_rxon_context *ctx, | 174 | struct iwl_rxon_context *ctx, |
196 | struct ieee80211_sta_ht_cap *ht_cap) | 175 | struct ieee80211_sta_ht_cap *ht_cap) |
@@ -198,21 +177,25 @@ bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, | |||
198 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) | 177 | if (!ctx->ht.enabled || !ctx->ht.is_40mhz) |
199 | return false; | 178 | return false; |
200 | 179 | ||
180 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
181 | if (priv->disable_ht40) | ||
182 | return false; | ||
183 | #endif | ||
184 | |||
201 | /* | 185 | /* |
202 | * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 186 | * Remainder of this function checks ht_cap, but if it's |
203 | * the bit will not set if it is pure 40MHz case | 187 | * NULL then we can do HT40 (special case for RXON) |
204 | */ | 188 | */ |
205 | if (ht_cap && !ht_cap->ht_supported) | 189 | if (!ht_cap) |
190 | return true; | ||
191 | |||
192 | if (!ht_cap->ht_supported) | ||
206 | return false; | 193 | return false; |
207 | 194 | ||
208 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 195 | if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) |
209 | if (priv->disable_ht40) | ||
210 | return false; | 196 | return false; |
211 | #endif | ||
212 | 197 | ||
213 | return iwl_is_channel_extension(priv, priv->band, | 198 | return true; |
214 | le16_to_cpu(ctx->staging.channel), | ||
215 | ctx->ht.extension_chan_offset); | ||
216 | } | 199 | } |
217 | 200 | ||
218 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, | 201 | static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, |
@@ -236,6 +219,7 @@ static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, | |||
236 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; | 219 | mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; |
237 | 220 | ||
238 | IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", | 221 | IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", |
222 | sta->addr, | ||
239 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? | 223 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? |
240 | "static" : | 224 | "static" : |
241 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? | 225 | (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? |
@@ -649,23 +633,23 @@ static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
649 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) | 633 | if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) |
650 | rate_flags |= RATE_MCS_CCK_MSK; | 634 | rate_flags |= RATE_MCS_CCK_MSK; |
651 | 635 | ||
652 | rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << | 636 | rate_flags |= first_antenna(priv->eeprom_data->valid_tx_ant) << |
653 | RATE_MCS_ANT_POS; | 637 | RATE_MCS_ANT_POS; |
654 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | 638 | rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); |
655 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) | 639 | for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) |
656 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; | 640 | link_cmd->rs_table[i].rate_n_flags = rate_n_flags; |
657 | 641 | ||
658 | link_cmd->general_params.single_stream_ant_msk = | 642 | link_cmd->general_params.single_stream_ant_msk = |
659 | first_antenna(priv->hw_params.valid_tx_ant); | 643 | first_antenna(priv->eeprom_data->valid_tx_ant); |
660 | 644 | ||
661 | link_cmd->general_params.dual_stream_ant_msk = | 645 | link_cmd->general_params.dual_stream_ant_msk = |
662 | priv->hw_params.valid_tx_ant & | 646 | priv->eeprom_data->valid_tx_ant & |
663 | ~first_antenna(priv->hw_params.valid_tx_ant); | 647 | ~first_antenna(priv->eeprom_data->valid_tx_ant); |
664 | if (!link_cmd->general_params.dual_stream_ant_msk) { | 648 | if (!link_cmd->general_params.dual_stream_ant_msk) { |
665 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; | 649 | link_cmd->general_params.dual_stream_ant_msk = ANT_AB; |
666 | } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { | 650 | } else if (num_of_ant(priv->eeprom_data->valid_tx_ant) == 2) { |
667 | link_cmd->general_params.dual_stream_ant_msk = | 651 | link_cmd->general_params.dual_stream_ant_msk = |
668 | priv->hw_params.valid_tx_ant; | 652 | priv->eeprom_data->valid_tx_ant; |
669 | } | 653 | } |
670 | 654 | ||
671 | link_cmd->agg_params.agg_dis_start_th = | 655 | link_cmd->agg_params.agg_dis_start_th = |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index 060aac3e22f1..e08b1a383594 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c | |||
@@ -69,15 +69,14 @@ | |||
69 | #include <net/cfg80211.h> | 69 | #include <net/cfg80211.h> |
70 | #include <net/mac80211.h> | 70 | #include <net/mac80211.h> |
71 | #include <net/netlink.h> | 71 | #include <net/netlink.h> |
72 | |||
73 | #include "iwl-dev.h" | ||
74 | #include "iwl-debug.h" | 72 | #include "iwl-debug.h" |
75 | #include "iwl-io.h" | 73 | #include "iwl-io.h" |
76 | #include "iwl-agn.h" | ||
77 | #include "iwl-testmode.h" | ||
78 | #include "iwl-trans.h" | 74 | #include "iwl-trans.h" |
79 | #include "iwl-fh.h" | 75 | #include "iwl-fh.h" |
80 | #include "iwl-prph.h" | 76 | #include "iwl-prph.h" |
77 | #include "dev.h" | ||
78 | #include "agn.h" | ||
79 | #include "testmode.h" | ||
81 | 80 | ||
82 | 81 | ||
83 | /* Periphery registers absolute lower bound. This is used in order to | 82 | /* Periphery registers absolute lower bound. This is used in order to |
@@ -89,7 +88,7 @@ | |||
89 | /* The TLVs used in the gnl message policy between the kernel module and | 88 | /* The TLVs used in the gnl message policy between the kernel module and |
90 | * user space application. iwl_testmode_gnl_msg_policy is to be carried | 89 | * user space application. iwl_testmode_gnl_msg_policy is to be carried |
91 | * through the NL80211_CMD_TESTMODE channel regulated by nl80211. | 90 | * through the NL80211_CMD_TESTMODE channel regulated by nl80211. |
92 | * See iwl-testmode.h | 91 | * See testmode.h |
93 | */ | 92 | */ |
94 | static | 93 | static |
95 | struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | 94 | struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { |
@@ -129,7 +128,7 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { | |||
129 | }; | 128 | }; |
130 | 129 | ||
131 | /* | 130 | /* |
132 | * See the struct iwl_rx_packet in iwl-commands.h for the format of the | 131 | * See the struct iwl_rx_packet in commands.h for the format of the |
133 | * received events from the device | 132 | * received events from the device |
134 | */ | 133 | */ |
135 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) | 134 | static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) |
@@ -170,7 +169,7 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, | |||
170 | void *data; | 169 | void *data; |
171 | int length; | 170 | int length; |
172 | 171 | ||
173 | data = (void *)rxb_addr(rxb); | 172 | data = rxb_addr(rxb); |
174 | length = get_event_length(rxb); | 173 | length = get_event_length(rxb); |
175 | 174 | ||
176 | if (!data || length == 0) | 175 | if (!data || length == 0) |
@@ -535,9 +534,9 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
535 | break; | 534 | break; |
536 | 535 | ||
537 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: | 536 | case IWL_TM_CMD_APP2DEV_GET_EEPROM: |
538 | if (priv->eeprom) { | 537 | if (priv->eeprom_blob) { |
539 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, | 538 | skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, |
540 | priv->cfg->base_params->eeprom_size + 20); | 539 | priv->eeprom_blob_size + 20); |
541 | if (!skb) { | 540 | if (!skb) { |
542 | IWL_ERR(priv, "Memory allocation fail\n"); | 541 | IWL_ERR(priv, "Memory allocation fail\n"); |
543 | return -ENOMEM; | 542 | return -ENOMEM; |
@@ -545,15 +544,15 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) | |||
545 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, | 544 | if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, |
546 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || | 545 | IWL_TM_CMD_DEV2APP_EEPROM_RSP) || |
547 | nla_put(skb, IWL_TM_ATTR_EEPROM, | 546 | nla_put(skb, IWL_TM_ATTR_EEPROM, |
548 | priv->cfg->base_params->eeprom_size, | 547 | priv->eeprom_blob_size, |
549 | priv->eeprom)) | 548 | priv->eeprom_blob)) |
550 | goto nla_put_failure; | 549 | goto nla_put_failure; |
551 | status = cfg80211_testmode_reply(skb); | 550 | status = cfg80211_testmode_reply(skb); |
552 | if (status < 0) | 551 | if (status < 0) |
553 | IWL_ERR(priv, "Error sending msg : %d\n", | 552 | IWL_ERR(priv, "Error sending msg : %d\n", |
554 | status); | 553 | status); |
555 | } else | 554 | } else |
556 | return -EFAULT; | 555 | return -ENODATA; |
557 | break; | 556 | break; |
558 | 557 | ||
559 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: | 558 | case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/dvm/testmode.h index 6ba211b09426..6ba211b09426 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index a5cfe0aceedb..eb864433e59d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c | |||
@@ -31,17 +31,14 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | |||
35 | #include <net/mac80211.h> | 34 | #include <net/mac80211.h> |
36 | |||
37 | #include "iwl-agn.h" | ||
38 | #include "iwl-eeprom.h" | ||
39 | #include "iwl-dev.h" | ||
40 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
41 | #include "iwl-commands.h" | ||
42 | #include "iwl-debug.h" | ||
43 | #include "iwl-agn-tt.h" | ||
44 | #include "iwl-modparams.h" | 36 | #include "iwl-modparams.h" |
37 | #include "iwl-debug.h" | ||
38 | #include "agn.h" | ||
39 | #include "dev.h" | ||
40 | #include "commands.h" | ||
41 | #include "tt.h" | ||
45 | 42 | ||
46 | /* default Thermal Throttling transaction table | 43 | /* default Thermal Throttling transaction table |
47 | * Current state | Throttling Down | Throttling Up | 44 | * Current state | Throttling Down | Throttling Up |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/dvm/tt.h index 86bbf47501c1..44c7c8f30a2d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/dvm/tt.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #ifndef __iwl_tt_setting_h__ | 28 | #ifndef __iwl_tt_setting_h__ |
29 | #define __iwl_tt_setting_h__ | 29 | #define __iwl_tt_setting_h__ |
30 | 30 | ||
31 | #include "iwl-commands.h" | 31 | #include "commands.h" |
32 | 32 | ||
33 | #define IWL_ABSOLUTE_ZERO 0 | 33 | #define IWL_ABSOLUTE_ZERO 0 |
34 | #define IWL_ABSOLUTE_MAX 0xFFFFFFFF | 34 | #define IWL_ABSOLUTE_MAX 0xFFFFFFFF |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 3366e2e2f00f..0dfaf649b257 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -32,12 +32,11 @@ | |||
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/ieee80211.h> | 34 | #include <linux/ieee80211.h> |
35 | |||
36 | #include "iwl-dev.h" | ||
37 | #include "iwl-io.h" | 35 | #include "iwl-io.h" |
38 | #include "iwl-agn-hw.h" | ||
39 | #include "iwl-agn.h" | ||
40 | #include "iwl-trans.h" | 36 | #include "iwl-trans.h" |
37 | #include "iwl-agn-hw.h" | ||
38 | #include "dev.h" | ||
39 | #include "agn.h" | ||
41 | 40 | ||
42 | static const u8 tid_to_ac[] = { | 41 | static const u8 tid_to_ac[] = { |
43 | IEEE80211_AC_BE, | 42 | IEEE80211_AC_BE, |
@@ -187,7 +186,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
187 | rate_idx = info->control.rates[0].idx; | 186 | rate_idx = info->control.rates[0].idx; |
188 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || | 187 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS || |
189 | (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) | 188 | (rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY)) |
190 | rate_idx = rate_lowest_index(&priv->bands[info->band], | 189 | rate_idx = rate_lowest_index( |
190 | &priv->eeprom_data->bands[info->band], | ||
191 | info->control.sta); | 191 | info->control.sta); |
192 | /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ | 192 | /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ |
193 | if (info->band == IEEE80211_BAND_5GHZ) | 193 | if (info->band == IEEE80211_BAND_5GHZ) |
@@ -207,10 +207,11 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, | |||
207 | priv->bt_full_concurrent) { | 207 | priv->bt_full_concurrent) { |
208 | /* operated as 1x1 in full concurrency mode */ | 208 | /* operated as 1x1 in full concurrency mode */ |
209 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 209 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, |
210 | first_antenna(priv->hw_params.valid_tx_ant)); | 210 | first_antenna(priv->eeprom_data->valid_tx_ant)); |
211 | } else | 211 | } else |
212 | priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, | 212 | priv->mgmt_tx_ant = iwl_toggle_tx_ant( |
213 | priv->hw_params.valid_tx_ant); | 213 | priv, priv->mgmt_tx_ant, |
214 | priv->eeprom_data->valid_tx_ant); | ||
214 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); | 215 | rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); |
215 | 216 | ||
216 | /* Set the rate in the TX cmd */ | 217 | /* Set the rate in the TX cmd */ |
@@ -296,7 +297,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
296 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 297 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
297 | struct iwl_station_priv *sta_priv = NULL; | 298 | struct iwl_station_priv *sta_priv = NULL; |
298 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 299 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
299 | struct iwl_device_cmd *dev_cmd = NULL; | 300 | struct iwl_device_cmd *dev_cmd; |
300 | struct iwl_tx_cmd *tx_cmd; | 301 | struct iwl_tx_cmd *tx_cmd; |
301 | __le16 fc; | 302 | __le16 fc; |
302 | u8 hdr_len; | 303 | u8 hdr_len; |
@@ -378,7 +379,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
378 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 379 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
379 | is_agg = true; | 380 | is_agg = true; |
380 | 381 | ||
381 | dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); | 382 | dev_cmd = iwl_trans_alloc_tx_cmd(priv->trans); |
382 | 383 | ||
383 | if (unlikely(!dev_cmd)) | 384 | if (unlikely(!dev_cmd)) |
384 | goto drop_unlock_priv; | 385 | goto drop_unlock_priv; |
@@ -486,11 +487,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
486 | if (sta_priv && sta_priv->client && !is_agg) | 487 | if (sta_priv && sta_priv->client && !is_agg) |
487 | atomic_inc(&sta_priv->pending_frames); | 488 | atomic_inc(&sta_priv->pending_frames); |
488 | 489 | ||
490 | if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
491 | iwl_scan_offchannel_skb(priv); | ||
492 | |||
489 | return 0; | 493 | return 0; |
490 | 494 | ||
491 | drop_unlock_sta: | 495 | drop_unlock_sta: |
492 | if (dev_cmd) | 496 | if (dev_cmd) |
493 | kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); | 497 | iwl_trans_free_tx_cmd(priv->trans, dev_cmd); |
494 | spin_unlock(&priv->sta_lock); | 498 | spin_unlock(&priv->sta_lock); |
495 | drop_unlock_priv: | 499 | drop_unlock_priv: |
496 | return -1; | 500 | return -1; |
@@ -597,7 +601,7 @@ turn_off: | |||
597 | * time, or we hadn't time to drain the AC queues. | 601 | * time, or we hadn't time to drain the AC queues. |
598 | */ | 602 | */ |
599 | if (agg_state == IWL_AGG_ON) | 603 | if (agg_state == IWL_AGG_ON) |
600 | iwl_trans_tx_agg_disable(priv->trans, txq_id); | 604 | iwl_trans_txq_disable(priv->trans, txq_id); |
601 | else | 605 | else |
602 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", | 606 | IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n", |
603 | agg_state); | 607 | agg_state); |
@@ -686,9 +690,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
686 | 690 | ||
687 | fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; | 691 | fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; |
688 | 692 | ||
689 | iwl_trans_tx_agg_setup(priv->trans, q, fifo, | 693 | iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid, |
690 | sta_priv->sta_id, tid, | 694 | buf_size, ssn); |
691 | buf_size, ssn); | ||
692 | 695 | ||
693 | /* | 696 | /* |
694 | * If the limit is 0, then it wasn't initialised yet, | 697 | * If the limit is 0, then it wasn't initialised yet, |
@@ -753,8 +756,8 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) | |||
753 | IWL_DEBUG_TX_QUEUES(priv, | 756 | IWL_DEBUG_TX_QUEUES(priv, |
754 | "Can continue DELBA flow ssn = next_recl =" | 757 | "Can continue DELBA flow ssn = next_recl =" |
755 | " %d", tid_data->next_reclaimed); | 758 | " %d", tid_data->next_reclaimed); |
756 | iwl_trans_tx_agg_disable(priv->trans, | 759 | iwl_trans_txq_disable(priv->trans, |
757 | tid_data->agg.txq_id); | 760 | tid_data->agg.txq_id); |
758 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); | 761 | iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); |
759 | tid_data->agg.state = IWL_AGG_OFF; | 762 | tid_data->agg.state = IWL_AGG_OFF; |
760 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); | 763 | ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid); |
@@ -1136,6 +1139,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1136 | struct sk_buff *skb; | 1139 | struct sk_buff *skb; |
1137 | struct iwl_rxon_context *ctx; | 1140 | struct iwl_rxon_context *ctx; |
1138 | bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); | 1141 | bool is_agg = (txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); |
1142 | bool is_offchannel_skb; | ||
1139 | 1143 | ||
1140 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> | 1144 | tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> |
1141 | IWLAGN_TX_RES_TID_POS; | 1145 | IWLAGN_TX_RES_TID_POS; |
@@ -1149,6 +1153,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1149 | 1153 | ||
1150 | __skb_queue_head_init(&skbs); | 1154 | __skb_queue_head_init(&skbs); |
1151 | 1155 | ||
1156 | is_offchannel_skb = false; | ||
1157 | |||
1152 | if (tx_resp->frame_count == 1) { | 1158 | if (tx_resp->frame_count == 1) { |
1153 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); | 1159 | u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); |
1154 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); | 1160 | next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); |
@@ -1189,8 +1195,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1189 | 1195 | ||
1190 | info = IEEE80211_SKB_CB(skb); | 1196 | info = IEEE80211_SKB_CB(skb); |
1191 | ctx = info->driver_data[0]; | 1197 | ctx = info->driver_data[0]; |
1192 | kmem_cache_free(iwl_tx_cmd_pool, | 1198 | iwl_trans_free_tx_cmd(priv->trans, |
1193 | (info->driver_data[1])); | 1199 | info->driver_data[1]); |
1194 | 1200 | ||
1195 | memset(&info->status, 0, sizeof(info->status)); | 1201 | memset(&info->status, 0, sizeof(info->status)); |
1196 | 1202 | ||
@@ -1225,10 +1231,19 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1225 | if (!is_agg) | 1231 | if (!is_agg) |
1226 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1232 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
1227 | 1233 | ||
1234 | is_offchannel_skb = | ||
1235 | (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); | ||
1228 | freed++; | 1236 | freed++; |
1229 | } | 1237 | } |
1230 | 1238 | ||
1231 | WARN_ON(!is_agg && freed != 1); | 1239 | WARN_ON(!is_agg && freed != 1); |
1240 | |||
1241 | /* | ||
1242 | * An offchannel frame can be send only on the AUX queue, where | ||
1243 | * there is no aggregation (and reordering) so it only is single | ||
1244 | * skb is expected to be processed. | ||
1245 | */ | ||
1246 | WARN_ON(is_offchannel_skb && freed != 1); | ||
1232 | } | 1247 | } |
1233 | 1248 | ||
1234 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1249 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
@@ -1239,6 +1254,9 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1239 | ieee80211_tx_status(priv->hw, skb); | 1254 | ieee80211_tx_status(priv->hw, skb); |
1240 | } | 1255 | } |
1241 | 1256 | ||
1257 | if (is_offchannel_skb) | ||
1258 | iwl_scan_offchannel_skb_status(priv); | ||
1259 | |||
1242 | return 0; | 1260 | return 0; |
1243 | } | 1261 | } |
1244 | 1262 | ||
@@ -1341,7 +1359,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1341 | WARN_ON_ONCE(1); | 1359 | WARN_ON_ONCE(1); |
1342 | 1360 | ||
1343 | info = IEEE80211_SKB_CB(skb); | 1361 | info = IEEE80211_SKB_CB(skb); |
1344 | kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); | 1362 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
1345 | 1363 | ||
1346 | if (freed == 1) { | 1364 | if (freed == 1) { |
1347 | /* this is the first skb we deliver in this batch */ | 1365 | /* this is the first skb we deliver in this batch */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index bc40dc68b0f4..b3a314ba48c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -30,15 +30,16 @@ | |||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | 32 | ||
33 | #include "iwl-dev.h" | ||
34 | #include "iwl-io.h" | 33 | #include "iwl-io.h" |
35 | #include "iwl-agn-hw.h" | 34 | #include "iwl-agn-hw.h" |
36 | #include "iwl-agn.h" | ||
37 | #include "iwl-agn-calib.h" | ||
38 | #include "iwl-trans.h" | 35 | #include "iwl-trans.h" |
39 | #include "iwl-fh.h" | 36 | #include "iwl-fh.h" |
40 | #include "iwl-op-mode.h" | 37 | #include "iwl-op-mode.h" |
41 | 38 | ||
39 | #include "dev.h" | ||
40 | #include "agn.h" | ||
41 | #include "calib.h" | ||
42 | |||
42 | /****************************************************************************** | 43 | /****************************************************************************** |
43 | * | 44 | * |
44 | * uCode download functions | 45 | * uCode download functions |
@@ -60,8 +61,7 @@ iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) | |||
60 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) | 61 | static int iwl_set_Xtal_calib(struct iwl_priv *priv) |
61 | { | 62 | { |
62 | struct iwl_calib_xtal_freq_cmd cmd; | 63 | struct iwl_calib_xtal_freq_cmd cmd; |
63 | __le16 *xtal_calib = | 64 | __le16 *xtal_calib = priv->eeprom_data->xtal_calib; |
64 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL); | ||
65 | 65 | ||
66 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); | 66 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD); |
67 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); | 67 | cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]); |
@@ -72,12 +72,10 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv) | |||
72 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | 72 | static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) |
73 | { | 73 | { |
74 | struct iwl_calib_temperature_offset_cmd cmd; | 74 | struct iwl_calib_temperature_offset_cmd cmd; |
75 | __le16 *offset_calib = | ||
76 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); | ||
77 | 75 | ||
78 | memset(&cmd, 0, sizeof(cmd)); | 76 | memset(&cmd, 0, sizeof(cmd)); |
79 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 77 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
80 | memcpy(&cmd.radio_sensor_offset, offset_calib, sizeof(*offset_calib)); | 78 | cmd.radio_sensor_offset = priv->eeprom_data->raw_temperature; |
81 | if (!(cmd.radio_sensor_offset)) | 79 | if (!(cmd.radio_sensor_offset)) |
82 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; | 80 | cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; |
83 | 81 | ||
@@ -89,27 +87,17 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) | |||
89 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) | 87 | static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) |
90 | { | 88 | { |
91 | struct iwl_calib_temperature_offset_v2_cmd cmd; | 89 | struct iwl_calib_temperature_offset_v2_cmd cmd; |
92 | __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv, | ||
93 | EEPROM_KELVIN_TEMPERATURE); | ||
94 | __le16 *offset_calib_low = | ||
95 | (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE); | ||
96 | struct iwl_eeprom_calib_hdr *hdr; | ||
97 | 90 | ||
98 | memset(&cmd, 0, sizeof(cmd)); | 91 | memset(&cmd, 0, sizeof(cmd)); |
99 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); | 92 | iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); |
100 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, | 93 | cmd.radio_sensor_offset_high = priv->eeprom_data->kelvin_temperature; |
101 | EEPROM_CALIB_ALL); | 94 | cmd.radio_sensor_offset_low = priv->eeprom_data->raw_temperature; |
102 | memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, | 95 | if (!cmd.radio_sensor_offset_low) { |
103 | sizeof(*offset_calib_high)); | ||
104 | memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, | ||
105 | sizeof(*offset_calib_low)); | ||
106 | if (!(cmd.radio_sensor_offset_low)) { | ||
107 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); | 96 | IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); |
108 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; | 97 | cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; |
109 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; | 98 | cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; |
110 | } | 99 | } |
111 | memcpy(&cmd.burntVoltageRef, &hdr->voltage, | 100 | cmd.burntVoltageRef = priv->eeprom_data->calib_voltage; |
112 | sizeof(hdr->voltage)); | ||
113 | 101 | ||
114 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", | 102 | IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", |
115 | le16_to_cpu(cmd.radio_sensor_offset_high)); | 103 | le16_to_cpu(cmd.radio_sensor_offset_high)); |
@@ -177,7 +165,7 @@ int iwl_init_alive_start(struct iwl_priv *priv) | |||
177 | return 0; | 165 | return 0; |
178 | } | 166 | } |
179 | 167 | ||
180 | int iwl_send_wimax_coex(struct iwl_priv *priv) | 168 | static int iwl_send_wimax_coex(struct iwl_priv *priv) |
181 | { | 169 | { |
182 | struct iwl_wimax_coex_cmd coex_cmd; | 170 | struct iwl_wimax_coex_cmd coex_cmd; |
183 | 171 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 67b28aa7f9be..10e47938b635 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -113,7 +113,7 @@ enum iwl_led_mode { | |||
113 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0 | 113 | #define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0 |
114 | 114 | ||
115 | /* TX queue watchdog timeouts in mSecs */ | 115 | /* TX queue watchdog timeouts in mSecs */ |
116 | #define IWL_WATCHHDOG_DISABLED 0 | 116 | #define IWL_WATCHDOG_DISABLED 0 |
117 | #define IWL_DEF_WD_TIMEOUT 2000 | 117 | #define IWL_DEF_WD_TIMEOUT 2000 |
118 | #define IWL_LONG_WD_TIMEOUT 10000 | 118 | #define IWL_LONG_WD_TIMEOUT 10000 |
119 | #define IWL_MAX_WD_TIMEOUT 120000 | 119 | #define IWL_MAX_WD_TIMEOUT 120000 |
@@ -143,7 +143,7 @@ enum iwl_led_mode { | |||
143 | * @chain_noise_scale: default chain noise scale used for gain computation | 143 | * @chain_noise_scale: default chain noise scale used for gain computation |
144 | * @wd_timeout: TX queues watchdog timeout | 144 | * @wd_timeout: TX queues watchdog timeout |
145 | * @max_event_log_size: size of event log buffer size for ucode event logging | 145 | * @max_event_log_size: size of event log buffer size for ucode event logging |
146 | * @shadow_reg_enable: HW shadhow register bit | 146 | * @shadow_reg_enable: HW shadow register support |
147 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | 147 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up |
148 | * @no_idle_support: do not support idle mode | 148 | * @no_idle_support: do not support idle mode |
149 | */ | 149 | */ |
@@ -182,13 +182,34 @@ struct iwl_bt_params { | |||
182 | bool bt_sco_disable; | 182 | bool bt_sco_disable; |
183 | bool bt_session_2; | 183 | bool bt_session_2; |
184 | }; | 184 | }; |
185 | |||
185 | /* | 186 | /* |
186 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 187 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
188 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 | ||
187 | */ | 189 | */ |
188 | struct iwl_ht_params { | 190 | struct iwl_ht_params { |
191 | enum ieee80211_smps_mode smps_mode; | ||
189 | const bool ht_greenfield_support; /* if used set to true */ | 192 | const bool ht_greenfield_support; /* if used set to true */ |
190 | bool use_rts_for_aggregation; | 193 | bool use_rts_for_aggregation; |
191 | enum ieee80211_smps_mode smps_mode; | 194 | u8 ht40_bands; |
195 | }; | ||
196 | |||
197 | /* | ||
198 | * information on how to parse the EEPROM | ||
199 | */ | ||
200 | #define EEPROM_REG_BAND_1_CHANNELS 0x08 | ||
201 | #define EEPROM_REG_BAND_2_CHANNELS 0x26 | ||
202 | #define EEPROM_REG_BAND_3_CHANNELS 0x42 | ||
203 | #define EEPROM_REG_BAND_4_CHANNELS 0x5C | ||
204 | #define EEPROM_REG_BAND_5_CHANNELS 0x74 | ||
205 | #define EEPROM_REG_BAND_24_HT40_CHANNELS 0x82 | ||
206 | #define EEPROM_REG_BAND_52_HT40_CHANNELS 0x92 | ||
207 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS 0x80 | ||
208 | #define EEPROM_REGULATORY_BAND_NO_HT40 0 | ||
209 | |||
210 | struct iwl_eeprom_params { | ||
211 | const u8 regulatory_bands[7]; | ||
212 | bool enhanced_txpower; | ||
192 | }; | 213 | }; |
193 | 214 | ||
194 | /** | 215 | /** |
@@ -243,6 +264,7 @@ struct iwl_cfg { | |||
243 | /* params likely to change within a device family */ | 264 | /* params likely to change within a device family */ |
244 | const struct iwl_ht_params *ht_params; | 265 | const struct iwl_ht_params *ht_params; |
245 | const struct iwl_bt_params *bt_params; | 266 | const struct iwl_bt_params *bt_params; |
267 | const struct iwl_eeprom_params *eeprom_params; | ||
246 | const bool need_temp_offset_calib; /* if used set to true */ | 268 | const bool need_temp_offset_calib; /* if used set to true */ |
247 | const bool no_xtal_calib; | 269 | const bool no_xtal_calib; |
248 | enum iwl_led_mode led_mode; | 270 | enum iwl_led_mode led_mode; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 59750543fce7..34a5287dfc2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -97,13 +97,10 @@ | |||
97 | /* | 97 | /* |
98 | * Hardware revision info | 98 | * Hardware revision info |
99 | * Bit fields: | 99 | * Bit fields: |
100 | * 31-8: Reserved | 100 | * 31-16: Reserved |
101 | * 7-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions | 101 | * 15-4: Type of device: see CSR_HW_REV_TYPE_xxx definitions |
102 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D | 102 | * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D |
103 | * 1-0: "Dash" (-) value, as in A-1, etc. | 103 | * 1-0: "Dash" (-) value, as in A-1, etc. |
104 | * | ||
105 | * NOTE: Revision step affects calculation of CCK txpower for 4965. | ||
106 | * NOTE: See also CSR_HW_REV_WA_REG (work-around for bug in 4965). | ||
107 | */ | 104 | */ |
108 | #define CSR_HW_REV (CSR_BASE+0x028) | 105 | #define CSR_HW_REV (CSR_BASE+0x028) |
109 | 106 | ||
@@ -155,9 +152,21 @@ | |||
155 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) | 152 | #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) |
156 | 153 | ||
157 | /* Bits for CSR_HW_IF_CONFIG_REG */ | 154 | /* Bits for CSR_HW_IF_CONFIG_REG */ |
158 | #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) | 155 | #define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) |
159 | #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) | 156 | #define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) |
157 | #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) | ||
158 | #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) | ||
160 | #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) | 159 | #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) |
160 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE (0x00000C00) | ||
161 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_DASH (0x00003000) | ||
162 | #define CSR_HW_IF_CONFIG_REG_MSK_PHY_STEP (0x0000C000) | ||
163 | |||
164 | #define CSR_HW_IF_CONFIG_REG_POS_MAC_DASH (0) | ||
165 | #define CSR_HW_IF_CONFIG_REG_POS_MAC_STEP (2) | ||
166 | #define CSR_HW_IF_CONFIG_REG_POS_BOARD_VER (6) | ||
167 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE (10) | ||
168 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_DASH (12) | ||
169 | #define CSR_HW_IF_CONFIG_REG_POS_PHY_STEP (14) | ||
161 | 170 | ||
162 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) | 171 | #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) |
163 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) | 172 | #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) |
@@ -270,7 +279,10 @@ | |||
270 | 279 | ||
271 | 280 | ||
272 | /* HW REV */ | 281 | /* HW REV */ |
273 | #define CSR_HW_REV_TYPE_MSK (0x00001F0) | 282 | #define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) |
283 | #define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) | ||
284 | |||
285 | #define CSR_HW_REV_TYPE_MSK (0x000FFF0) | ||
274 | #define CSR_HW_REV_TYPE_5300 (0x0000020) | 286 | #define CSR_HW_REV_TYPE_5300 (0x0000020) |
275 | #define CSR_HW_REV_TYPE_5350 (0x0000030) | 287 | #define CSR_HW_REV_TYPE_5350 (0x0000030) |
276 | #define CSR_HW_REV_TYPE_5100 (0x0000050) | 288 | #define CSR_HW_REV_TYPE_5100 (0x0000050) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 2d1b42847b9b..0f8fcd1d4fe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c | |||
@@ -62,6 +62,7 @@ | |||
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | 63 | ||
64 | #include <linux/interrupt.h> | 64 | #include <linux/interrupt.h> |
65 | #include <linux/export.h> | ||
65 | #include "iwl-debug.h" | 66 | #include "iwl-debug.h" |
66 | #include "iwl-devtrace.h" | 67 | #include "iwl-devtrace.h" |
67 | 68 | ||
@@ -81,8 +82,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ | |||
81 | } | 82 | } |
82 | 83 | ||
83 | __iwl_fn(warn) | 84 | __iwl_fn(warn) |
85 | EXPORT_SYMBOL_GPL(__iwl_warn); | ||
84 | __iwl_fn(info) | 86 | __iwl_fn(info) |
87 | EXPORT_SYMBOL_GPL(__iwl_info); | ||
85 | __iwl_fn(crit) | 88 | __iwl_fn(crit) |
89 | EXPORT_SYMBOL_GPL(__iwl_crit); | ||
86 | 90 | ||
87 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | 91 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, |
88 | const char *fmt, ...) | 92 | const char *fmt, ...) |
@@ -103,6 +107,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, | |||
103 | trace_iwlwifi_err(&vaf); | 107 | trace_iwlwifi_err(&vaf); |
104 | va_end(args); | 108 | va_end(args); |
105 | } | 109 | } |
110 | EXPORT_SYMBOL_GPL(__iwl_err); | ||
106 | 111 | ||
107 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 112 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
108 | void __iwl_dbg(struct device *dev, | 113 | void __iwl_dbg(struct device *dev, |
@@ -125,4 +130,5 @@ void __iwl_dbg(struct device *dev, | |||
125 | trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); | 130 | trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); |
126 | va_end(args); | 131 | va_end(args); |
127 | } | 132 | } |
133 | EXPORT_SYMBOL_GPL(__iwl_dbg); | ||
128 | #endif | 134 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 8376b842bdba..42b20b0e83bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -38,13 +38,14 @@ static inline bool iwl_have_debug_level(u32 level) | |||
38 | } | 38 | } |
39 | 39 | ||
40 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, | 40 | void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, |
41 | const char *fmt, ...); | 41 | const char *fmt, ...) __printf(4, 5); |
42 | void __iwl_warn(struct device *dev, const char *fmt, ...); | 42 | void __iwl_warn(struct device *dev, const char *fmt, ...) __printf(2, 3); |
43 | void __iwl_info(struct device *dev, const char *fmt, ...); | 43 | void __iwl_info(struct device *dev, const char *fmt, ...) __printf(2, 3); |
44 | void __iwl_crit(struct device *dev, const char *fmt, ...); | 44 | void __iwl_crit(struct device *dev, const char *fmt, ...) __printf(2, 3); |
45 | 45 | ||
46 | /* No matter what is m (priv, bus, trans), this will work */ | 46 | /* No matter what is m (priv, bus, trans), this will work */ |
47 | #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) | 47 | #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a) |
48 | #define IWL_ERR_DEV(d, f, a...) __iwl_err((d), false, false, f, ## a) | ||
48 | #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a) | 49 | #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a) |
49 | #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a) | 50 | #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a) |
50 | #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a) | 51 | #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a) |
@@ -52,9 +53,9 @@ void __iwl_crit(struct device *dev, const char *fmt, ...); | |||
52 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) | 53 | #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) |
53 | void __iwl_dbg(struct device *dev, | 54 | void __iwl_dbg(struct device *dev, |
54 | u32 level, bool limit, const char *function, | 55 | u32 level, bool limit, const char *function, |
55 | const char *fmt, ...); | 56 | const char *fmt, ...) __printf(5, 6); |
56 | #else | 57 | #else |
57 | static inline void | 58 | __printf(5, 6) static inline void |
58 | __iwl_dbg(struct device *dev, | 59 | __iwl_dbg(struct device *dev, |
59 | u32 level, bool limit, const char *function, | 60 | u32 level, bool limit, const char *function, |
60 | const char *fmt, ...) | 61 | const char *fmt, ...) |
@@ -69,6 +70,8 @@ do { \ | |||
69 | 70 | ||
70 | #define IWL_DEBUG(m, level, fmt, args...) \ | 71 | #define IWL_DEBUG(m, level, fmt, args...) \ |
71 | __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args) | 72 | __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args) |
73 | #define IWL_DEBUG_DEV(dev, level, fmt, args...) \ | ||
74 | __iwl_dbg((dev), level, false, __func__, fmt, ##args) | ||
72 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ | 75 | #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ |
73 | __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args) | 76 | __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args) |
74 | 77 | ||
@@ -153,7 +156,7 @@ do { \ | |||
153 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) | 156 | #define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a) |
154 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) | 157 | #define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a) |
155 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) | 158 | #define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a) |
156 | #define IWL_DEBUG_EEPROM(p, f, a...) IWL_DEBUG(p, IWL_DL_EEPROM, f, ## a) | 159 | #define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a) |
157 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) | 160 | #define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) |
158 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) | 161 | #define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) |
159 | #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) | 162 | #define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 91f45e71e0a2..70191ddbd8f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c | |||
@@ -42,4 +42,9 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); | |||
42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); | 42 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); |
43 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); | 43 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event); |
44 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); | 44 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event); |
45 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info); | ||
46 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn); | ||
47 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit); | ||
48 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err); | ||
49 | EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg); | ||
45 | #endif | 50 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 06203d6a1d86..65364793021f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #define __IWLWIFI_DEVICE_TRACE | 28 | #define __IWLWIFI_DEVICE_TRACE |
29 | 29 | ||
30 | #include <linux/tracepoint.h> | 30 | #include <linux/tracepoint.h> |
31 | #include <linux/device.h> | ||
31 | 32 | ||
32 | 33 | ||
33 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) | 34 | #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index fac67a526a30..49df0e9d5c5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -77,8 +77,33 @@ | |||
77 | /* private includes */ | 77 | /* private includes */ |
78 | #include "iwl-fw-file.h" | 78 | #include "iwl-fw-file.h" |
79 | 79 | ||
80 | /****************************************************************************** | ||
81 | * | ||
82 | * module boiler plate | ||
83 | * | ||
84 | ******************************************************************************/ | ||
85 | |||
86 | /* | ||
87 | * module name, copyright, version, etc. | ||
88 | */ | ||
89 | #define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux" | ||
90 | |||
91 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
92 | #define VD "d" | ||
93 | #else | ||
94 | #define VD | ||
95 | #endif | ||
96 | |||
97 | #define DRV_VERSION IWLWIFI_VERSION VD | ||
98 | |||
99 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | ||
100 | MODULE_VERSION(DRV_VERSION); | ||
101 | MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); | ||
102 | MODULE_LICENSE("GPL"); | ||
103 | |||
80 | /** | 104 | /** |
81 | * struct iwl_drv - drv common data | 105 | * struct iwl_drv - drv common data |
106 | * @list: list of drv structures using this opmode | ||
82 | * @fw: the iwl_fw structure | 107 | * @fw: the iwl_fw structure |
83 | * @op_mode: the running op_mode | 108 | * @op_mode: the running op_mode |
84 | * @trans: transport layer | 109 | * @trans: transport layer |
@@ -89,6 +114,7 @@ | |||
89 | * @request_firmware_complete: the firmware has been obtained from user space | 114 | * @request_firmware_complete: the firmware has been obtained from user space |
90 | */ | 115 | */ |
91 | struct iwl_drv { | 116 | struct iwl_drv { |
117 | struct list_head list; | ||
92 | struct iwl_fw fw; | 118 | struct iwl_fw fw; |
93 | 119 | ||
94 | struct iwl_op_mode *op_mode; | 120 | struct iwl_op_mode *op_mode; |
@@ -102,7 +128,17 @@ struct iwl_drv { | |||
102 | struct completion request_firmware_complete; | 128 | struct completion request_firmware_complete; |
103 | }; | 129 | }; |
104 | 130 | ||
131 | #define DVM_OP_MODE 0 | ||
132 | #define MVM_OP_MODE 1 | ||
105 | 133 | ||
134 | static struct iwlwifi_opmode_table { | ||
135 | const char *name; /* name: iwldvm, iwlmvm, etc */ | ||
136 | const struct iwl_op_mode_ops *ops; /* pointer to op_mode ops */ | ||
137 | struct list_head drv; /* list of devices using this op_mode */ | ||
138 | } iwlwifi_opmode_table[] = { /* ops set when driver is initialized */ | ||
139 | { .name = "iwldvm", .ops = NULL }, | ||
140 | { .name = "iwlmvm", .ops = NULL }, | ||
141 | }; | ||
106 | 142 | ||
107 | /* | 143 | /* |
108 | * struct fw_sec: Just for the image parsing proccess. | 144 | * struct fw_sec: Just for the image parsing proccess. |
@@ -721,7 +757,6 @@ static int validate_sec_sizes(struct iwl_drv *drv, | |||
721 | return 0; | 757 | return 0; |
722 | } | 758 | } |
723 | 759 | ||
724 | |||
725 | /** | 760 | /** |
726 | * iwl_ucode_callback - callback when firmware was loaded | 761 | * iwl_ucode_callback - callback when firmware was loaded |
727 | * | 762 | * |
@@ -733,6 +768,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
733 | struct iwl_drv *drv = context; | 768 | struct iwl_drv *drv = context; |
734 | struct iwl_fw *fw = &drv->fw; | 769 | struct iwl_fw *fw = &drv->fw; |
735 | struct iwl_ucode_header *ucode; | 770 | struct iwl_ucode_header *ucode; |
771 | struct iwlwifi_opmode_table *op; | ||
736 | int err; | 772 | int err; |
737 | struct iwl_firmware_pieces pieces; | 773 | struct iwl_firmware_pieces pieces; |
738 | const unsigned int api_max = drv->cfg->ucode_api_max; | 774 | const unsigned int api_max = drv->cfg->ucode_api_max; |
@@ -862,10 +898,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
862 | /* We have our copies now, allow OS release its copies */ | 898 | /* We have our copies now, allow OS release its copies */ |
863 | release_firmware(ucode_raw); | 899 | release_firmware(ucode_raw); |
864 | 900 | ||
865 | drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw); | 901 | op = &iwlwifi_opmode_table[DVM_OP_MODE]; |
866 | 902 | ||
867 | if (!drv->op_mode) | 903 | /* add this device to the list of devices using this op_mode */ |
868 | goto out_unbind; | 904 | list_add_tail(&drv->list, &op->drv); |
905 | |||
906 | if (op->ops) { | ||
907 | const struct iwl_op_mode_ops *ops = op->ops; | ||
908 | drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); | ||
909 | |||
910 | if (!drv->op_mode) | ||
911 | goto out_unbind; | ||
912 | } else { | ||
913 | request_module_nowait("%s", op->name); | ||
914 | } | ||
869 | 915 | ||
870 | /* | 916 | /* |
871 | * Complete the firmware request last so that | 917 | * Complete the firmware request last so that |
@@ -943,6 +989,67 @@ struct iwl_mod_params iwlwifi_mod_params = { | |||
943 | .auto_agg = true, | 989 | .auto_agg = true, |
944 | /* the rest are 0 by default */ | 990 | /* the rest are 0 by default */ |
945 | }; | 991 | }; |
992 | EXPORT_SYMBOL_GPL(iwlwifi_mod_params); | ||
993 | |||
994 | int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) | ||
995 | { | ||
996 | int i; | ||
997 | struct iwl_drv *drv; | ||
998 | |||
999 | for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { | ||
1000 | if (strcmp(iwlwifi_opmode_table[i].name, name)) | ||
1001 | continue; | ||
1002 | iwlwifi_opmode_table[i].ops = ops; | ||
1003 | list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) | ||
1004 | drv->op_mode = ops->start(drv->trans, drv->cfg, | ||
1005 | &drv->fw); | ||
1006 | return 0; | ||
1007 | } | ||
1008 | return -EIO; | ||
1009 | } | ||
1010 | EXPORT_SYMBOL_GPL(iwl_opmode_register); | ||
1011 | |||
1012 | void iwl_opmode_deregister(const char *name) | ||
1013 | { | ||
1014 | int i; | ||
1015 | struct iwl_drv *drv; | ||
1016 | |||
1017 | for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) { | ||
1018 | if (strcmp(iwlwifi_opmode_table[i].name, name)) | ||
1019 | continue; | ||
1020 | iwlwifi_opmode_table[i].ops = NULL; | ||
1021 | |||
1022 | /* call the stop routine for all devices */ | ||
1023 | list_for_each_entry(drv, &iwlwifi_opmode_table[i].drv, list) { | ||
1024 | if (drv->op_mode) { | ||
1025 | iwl_op_mode_stop(drv->op_mode); | ||
1026 | drv->op_mode = NULL; | ||
1027 | } | ||
1028 | } | ||
1029 | return; | ||
1030 | } | ||
1031 | } | ||
1032 | EXPORT_SYMBOL_GPL(iwl_opmode_deregister); | ||
1033 | |||
1034 | static int __init iwl_drv_init(void) | ||
1035 | { | ||
1036 | int i; | ||
1037 | |||
1038 | for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) | ||
1039 | INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); | ||
1040 | |||
1041 | pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); | ||
1042 | pr_info(DRV_COPYRIGHT "\n"); | ||
1043 | |||
1044 | return iwl_pci_register_driver(); | ||
1045 | } | ||
1046 | module_init(iwl_drv_init); | ||
1047 | |||
1048 | static void __exit iwl_drv_exit(void) | ||
1049 | { | ||
1050 | iwl_pci_unregister_driver(); | ||
1051 | } | ||
1052 | module_exit(iwl_drv_exit); | ||
946 | 1053 | ||
947 | #ifdef CONFIG_IWLWIFI_DEBUG | 1054 | #ifdef CONFIG_IWLWIFI_DEBUG |
948 | module_param_named(debug, iwlwifi_mod_params.debug_level, uint, | 1055 | module_param_named(debug, iwlwifi_mod_params.debug_level, uint, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c new file mode 100644 index 000000000000..c87a05cbec12 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -0,0 +1,900 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | #include <linux/types.h> | ||
63 | #include <linux/slab.h> | ||
64 | #include <linux/export.h> | ||
65 | #include "iwl-modparams.h" | ||
66 | #include "iwl-eeprom-parse.h" | ||
67 | |||
68 | /* EEPROM offset definitions */ | ||
69 | |||
70 | /* indirect access definitions */ | ||
71 | #define ADDRESS_MSK 0x0000FFFF | ||
72 | #define INDIRECT_TYPE_MSK 0x000F0000 | ||
73 | #define INDIRECT_HOST 0x00010000 | ||
74 | #define INDIRECT_GENERAL 0x00020000 | ||
75 | #define INDIRECT_REGULATORY 0x00030000 | ||
76 | #define INDIRECT_CALIBRATION 0x00040000 | ||
77 | #define INDIRECT_PROCESS_ADJST 0x00050000 | ||
78 | #define INDIRECT_OTHERS 0x00060000 | ||
79 | #define INDIRECT_TXP_LIMIT 0x00070000 | ||
80 | #define INDIRECT_TXP_LIMIT_SIZE 0x00080000 | ||
81 | #define INDIRECT_ADDRESS 0x00100000 | ||
82 | |||
83 | /* corresponding link offsets in EEPROM */ | ||
84 | #define EEPROM_LINK_HOST (2*0x64) | ||
85 | #define EEPROM_LINK_GENERAL (2*0x65) | ||
86 | #define EEPROM_LINK_REGULATORY (2*0x66) | ||
87 | #define EEPROM_LINK_CALIBRATION (2*0x67) | ||
88 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) | ||
89 | #define EEPROM_LINK_OTHERS (2*0x69) | ||
90 | #define EEPROM_LINK_TXP_LIMIT (2*0x6a) | ||
91 | #define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) | ||
92 | |||
93 | /* General */ | ||
94 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ | ||
95 | #define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ | ||
96 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ | ||
97 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ | ||
98 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ | ||
99 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ | ||
100 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ | ||
101 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ | ||
102 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ | ||
103 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ | ||
104 | |||
105 | /* calibration */ | ||
106 | struct iwl_eeprom_calib_hdr { | ||
107 | u8 version; | ||
108 | u8 pa_type; | ||
109 | __le16 voltage; | ||
110 | } __packed; | ||
111 | |||
112 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | ||
113 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) | ||
114 | |||
115 | /* temperature */ | ||
116 | #define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) | ||
117 | #define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) | ||
118 | |||
119 | /* | ||
120 | * EEPROM bands | ||
121 | * These are the channel numbers from each band in the order | ||
122 | * that they are stored in the EEPROM band information. Note | ||
123 | * that EEPROM bands aren't the same as mac80211 bands, and | ||
124 | * there are even special "ht40 bands" in the EEPROM. | ||
125 | */ | ||
126 | static const u8 iwl_eeprom_band_1[14] = { /* 2.4 GHz */ | ||
127 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | ||
128 | }; | ||
129 | |||
130 | static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ | ||
131 | 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 | ||
132 | }; | ||
133 | |||
134 | static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ | ||
135 | 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | ||
136 | }; | ||
137 | |||
138 | static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ | ||
139 | 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | ||
140 | }; | ||
141 | |||
142 | static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ | ||
143 | 145, 149, 153, 157, 161, 165 | ||
144 | }; | ||
145 | |||
146 | static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ | ||
147 | 1, 2, 3, 4, 5, 6, 7 | ||
148 | }; | ||
149 | |||
150 | static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | ||
151 | 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 | ||
152 | }; | ||
153 | |||
154 | #define IWL_NUM_CHANNELS (ARRAY_SIZE(iwl_eeprom_band_1) + \ | ||
155 | ARRAY_SIZE(iwl_eeprom_band_2) + \ | ||
156 | ARRAY_SIZE(iwl_eeprom_band_3) + \ | ||
157 | ARRAY_SIZE(iwl_eeprom_band_4) + \ | ||
158 | ARRAY_SIZE(iwl_eeprom_band_5)) | ||
159 | |||
160 | /* rate data (static) */ | ||
161 | static struct ieee80211_rate iwl_cfg80211_rates[] = { | ||
162 | { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, }, | ||
163 | { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1, | ||
164 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
165 | { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2, | ||
166 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
167 | { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3, | ||
168 | .flags = IEEE80211_RATE_SHORT_PREAMBLE, }, | ||
169 | { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, }, | ||
170 | { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, }, | ||
171 | { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, }, | ||
172 | { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, }, | ||
173 | { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, }, | ||
174 | { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, }, | ||
175 | { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, }, | ||
176 | { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, }, | ||
177 | }; | ||
178 | #define RATES_24_OFFS 0 | ||
179 | #define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates) | ||
180 | #define RATES_52_OFFS 4 | ||
181 | #define N_RATES_52 (N_RATES_24 - RATES_52_OFFS) | ||
182 | |||
183 | /* EEPROM reading functions */ | ||
184 | |||
185 | static u16 iwl_eeprom_query16(const u8 *eeprom, size_t eeprom_size, int offset) | ||
186 | { | ||
187 | if (WARN_ON(offset + sizeof(u16) > eeprom_size)) | ||
188 | return 0; | ||
189 | return le16_to_cpup((__le16 *)(eeprom + offset)); | ||
190 | } | ||
191 | |||
192 | static u32 eeprom_indirect_address(const u8 *eeprom, size_t eeprom_size, | ||
193 | u32 address) | ||
194 | { | ||
195 | u16 offset = 0; | ||
196 | |||
197 | if ((address & INDIRECT_ADDRESS) == 0) | ||
198 | return address; | ||
199 | |||
200 | switch (address & INDIRECT_TYPE_MSK) { | ||
201 | case INDIRECT_HOST: | ||
202 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
203 | EEPROM_LINK_HOST); | ||
204 | break; | ||
205 | case INDIRECT_GENERAL: | ||
206 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
207 | EEPROM_LINK_GENERAL); | ||
208 | break; | ||
209 | case INDIRECT_REGULATORY: | ||
210 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
211 | EEPROM_LINK_REGULATORY); | ||
212 | break; | ||
213 | case INDIRECT_TXP_LIMIT: | ||
214 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
215 | EEPROM_LINK_TXP_LIMIT); | ||
216 | break; | ||
217 | case INDIRECT_TXP_LIMIT_SIZE: | ||
218 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
219 | EEPROM_LINK_TXP_LIMIT_SIZE); | ||
220 | break; | ||
221 | case INDIRECT_CALIBRATION: | ||
222 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
223 | EEPROM_LINK_CALIBRATION); | ||
224 | break; | ||
225 | case INDIRECT_PROCESS_ADJST: | ||
226 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
227 | EEPROM_LINK_PROCESS_ADJST); | ||
228 | break; | ||
229 | case INDIRECT_OTHERS: | ||
230 | offset = iwl_eeprom_query16(eeprom, eeprom_size, | ||
231 | EEPROM_LINK_OTHERS); | ||
232 | break; | ||
233 | default: | ||
234 | WARN_ON(1); | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | /* translate the offset from words to byte */ | ||
239 | return (address & ADDRESS_MSK) + (offset << 1); | ||
240 | } | ||
241 | |||
242 | static const u8 *iwl_eeprom_query_addr(const u8 *eeprom, size_t eeprom_size, | ||
243 | u32 offset) | ||
244 | { | ||
245 | u32 address = eeprom_indirect_address(eeprom, eeprom_size, offset); | ||
246 | |||
247 | if (WARN_ON(address >= eeprom_size)) | ||
248 | return NULL; | ||
249 | |||
250 | return &eeprom[address]; | ||
251 | } | ||
252 | |||
253 | static int iwl_eeprom_read_calib(const u8 *eeprom, size_t eeprom_size, | ||
254 | struct iwl_eeprom_data *data) | ||
255 | { | ||
256 | struct iwl_eeprom_calib_hdr *hdr; | ||
257 | |||
258 | hdr = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
259 | EEPROM_CALIB_ALL); | ||
260 | if (!hdr) | ||
261 | return -ENODATA; | ||
262 | data->calib_version = hdr->version; | ||
263 | data->calib_voltage = hdr->voltage; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * enum iwl_eeprom_channel_flags - channel flags in EEPROM | ||
270 | * @EEPROM_CHANNEL_VALID: channel is usable for this SKU/geo | ||
271 | * @EEPROM_CHANNEL_IBSS: usable as an IBSS channel | ||
272 | * @EEPROM_CHANNEL_ACTIVE: active scanning allowed | ||
273 | * @EEPROM_CHANNEL_RADAR: radar detection required | ||
274 | * @EEPROM_CHANNEL_WIDE: 20 MHz channel okay (?) | ||
275 | * @EEPROM_CHANNEL_DFS: dynamic freq selection candidate | ||
276 | */ | ||
277 | enum iwl_eeprom_channel_flags { | ||
278 | EEPROM_CHANNEL_VALID = BIT(0), | ||
279 | EEPROM_CHANNEL_IBSS = BIT(1), | ||
280 | EEPROM_CHANNEL_ACTIVE = BIT(3), | ||
281 | EEPROM_CHANNEL_RADAR = BIT(4), | ||
282 | EEPROM_CHANNEL_WIDE = BIT(5), | ||
283 | EEPROM_CHANNEL_DFS = BIT(7), | ||
284 | }; | ||
285 | |||
286 | /** | ||
287 | * struct iwl_eeprom_channel - EEPROM channel data | ||
288 | * @flags: %EEPROM_CHANNEL_* flags | ||
289 | * @max_power_avg: max power (in dBm) on this channel, at most 31 dBm | ||
290 | */ | ||
291 | struct iwl_eeprom_channel { | ||
292 | u8 flags; | ||
293 | s8 max_power_avg; | ||
294 | } __packed; | ||
295 | |||
296 | |||
297 | enum iwl_eeprom_enhanced_txpwr_flags { | ||
298 | IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), | ||
299 | IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), | ||
300 | IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), | ||
301 | IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), | ||
302 | IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), | ||
303 | IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), | ||
304 | IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), | ||
305 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), | ||
306 | }; | ||
307 | |||
308 | /** | ||
309 | * iwl_eeprom_enhanced_txpwr structure | ||
310 | * @flags: entry flags | ||
311 | * @channel: channel number | ||
312 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | ||
313 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | ||
314 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | ||
315 | * @delta_20_in_40: 20-in-40 deltas (hi/lo) | ||
316 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | ||
317 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | ||
318 | * | ||
319 | * This structure presents the enhanced regulatory tx power limit layout | ||
320 | * in an EEPROM image. | ||
321 | */ | ||
322 | struct iwl_eeprom_enhanced_txpwr { | ||
323 | u8 flags; | ||
324 | u8 channel; | ||
325 | s8 chain_a_max; | ||
326 | s8 chain_b_max; | ||
327 | s8 chain_c_max; | ||
328 | u8 delta_20_in_40; | ||
329 | s8 mimo2_max; | ||
330 | s8 mimo3_max; | ||
331 | } __packed; | ||
332 | |||
333 | static s8 iwl_get_max_txpwr_half_dbm(const struct iwl_eeprom_data *data, | ||
334 | struct iwl_eeprom_enhanced_txpwr *txp) | ||
335 | { | ||
336 | s8 result = 0; /* (.5 dBm) */ | ||
337 | |||
338 | /* Take the highest tx power from any valid chains */ | ||
339 | if (data->valid_tx_ant & ANT_A && txp->chain_a_max > result) | ||
340 | result = txp->chain_a_max; | ||
341 | |||
342 | if (data->valid_tx_ant & ANT_B && txp->chain_b_max > result) | ||
343 | result = txp->chain_b_max; | ||
344 | |||
345 | if (data->valid_tx_ant & ANT_C && txp->chain_c_max > result) | ||
346 | result = txp->chain_c_max; | ||
347 | |||
348 | if ((data->valid_tx_ant == ANT_AB || | ||
349 | data->valid_tx_ant == ANT_BC || | ||
350 | data->valid_tx_ant == ANT_AC) && txp->mimo2_max > result) | ||
351 | result = txp->mimo2_max; | ||
352 | |||
353 | if (data->valid_tx_ant == ANT_ABC && txp->mimo3_max > result) | ||
354 | result = txp->mimo3_max; | ||
355 | |||
356 | return result; | ||
357 | } | ||
358 | |||
359 | #define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) | ||
360 | #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) | ||
361 | #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) | ||
362 | |||
363 | #define TXP_CHECK_AND_PRINT(x) \ | ||
364 | ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) ? # x " " : "") | ||
365 | |||
366 | static void | ||
367 | iwl_eeprom_enh_txp_read_element(struct iwl_eeprom_data *data, | ||
368 | struct iwl_eeprom_enhanced_txpwr *txp, | ||
369 | int n_channels, s8 max_txpower_avg) | ||
370 | { | ||
371 | int ch_idx; | ||
372 | enum ieee80211_band band; | ||
373 | |||
374 | band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? | ||
375 | IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; | ||
376 | |||
377 | for (ch_idx = 0; ch_idx < n_channels; ch_idx++) { | ||
378 | struct ieee80211_channel *chan = &data->channels[ch_idx]; | ||
379 | |||
380 | /* update matching channel or from common data only */ | ||
381 | if (txp->channel != 0 && chan->hw_value != txp->channel) | ||
382 | continue; | ||
383 | |||
384 | /* update matching band only */ | ||
385 | if (band != chan->band) | ||
386 | continue; | ||
387 | |||
388 | if (chan->max_power < max_txpower_avg && | ||
389 | !(txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ)) | ||
390 | chan->max_power = max_txpower_avg; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static void iwl_eeprom_enhanced_txpower(struct device *dev, | ||
395 | struct iwl_eeprom_data *data, | ||
396 | const u8 *eeprom, size_t eeprom_size, | ||
397 | int n_channels) | ||
398 | { | ||
399 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | ||
400 | int idx, entries; | ||
401 | __le16 *txp_len; | ||
402 | s8 max_txp_avg_halfdbm; | ||
403 | |||
404 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | ||
405 | |||
406 | /* the length is in 16-bit words, but we want entries */ | ||
407 | txp_len = (__le16 *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
408 | EEPROM_TXP_SZ_OFFS); | ||
409 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | ||
410 | |||
411 | txp_array = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
412 | EEPROM_TXP_OFFS); | ||
413 | |||
414 | for (idx = 0; idx < entries; idx++) { | ||
415 | txp = &txp_array[idx]; | ||
416 | /* skip invalid entries */ | ||
417 | if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) | ||
418 | continue; | ||
419 | |||
420 | IWL_DEBUG_EEPROM(dev, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", | ||
421 | (txp->channel && (txp->flags & | ||
422 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? | ||
423 | "Common " : (txp->channel) ? | ||
424 | "Channel" : "Common", | ||
425 | (txp->channel), | ||
426 | TXP_CHECK_AND_PRINT(VALID), | ||
427 | TXP_CHECK_AND_PRINT(BAND_52G), | ||
428 | TXP_CHECK_AND_PRINT(OFDM), | ||
429 | TXP_CHECK_AND_PRINT(40MHZ), | ||
430 | TXP_CHECK_AND_PRINT(HT_AP), | ||
431 | TXP_CHECK_AND_PRINT(RES1), | ||
432 | TXP_CHECK_AND_PRINT(RES2), | ||
433 | TXP_CHECK_AND_PRINT(COMMON_TYPE), | ||
434 | txp->flags); | ||
435 | IWL_DEBUG_EEPROM(dev, | ||
436 | "\t\t chain_A: 0x%02x chain_B: 0X%02x chain_C: 0X%02x\n", | ||
437 | txp->chain_a_max, txp->chain_b_max, | ||
438 | txp->chain_c_max); | ||
439 | IWL_DEBUG_EEPROM(dev, | ||
440 | "\t\t MIMO2: 0x%02x MIMO3: 0x%02x High 20_on_40: 0x%02x Low 20_on_40: 0x%02x\n", | ||
441 | txp->mimo2_max, txp->mimo3_max, | ||
442 | ((txp->delta_20_in_40 & 0xf0) >> 4), | ||
443 | (txp->delta_20_in_40 & 0x0f)); | ||
444 | |||
445 | max_txp_avg_halfdbm = iwl_get_max_txpwr_half_dbm(data, txp); | ||
446 | |||
447 | iwl_eeprom_enh_txp_read_element(data, txp, n_channels, | ||
448 | DIV_ROUND_UP(max_txp_avg_halfdbm, 2)); | ||
449 | |||
450 | if (max_txp_avg_halfdbm > data->max_tx_pwr_half_dbm) | ||
451 | data->max_tx_pwr_half_dbm = max_txp_avg_halfdbm; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | static void iwl_init_band_reference(const struct iwl_cfg *cfg, | ||
456 | const u8 *eeprom, size_t eeprom_size, | ||
457 | int eeprom_band, int *eeprom_ch_count, | ||
458 | const struct iwl_eeprom_channel **ch_info, | ||
459 | const u8 **eeprom_ch_array) | ||
460 | { | ||
461 | u32 offset = cfg->eeprom_params->regulatory_bands[eeprom_band - 1]; | ||
462 | |||
463 | offset |= INDIRECT_ADDRESS | INDIRECT_REGULATORY; | ||
464 | |||
465 | *ch_info = (void *)iwl_eeprom_query_addr(eeprom, eeprom_size, offset); | ||
466 | |||
467 | switch (eeprom_band) { | ||
468 | case 1: /* 2.4GHz band */ | ||
469 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); | ||
470 | *eeprom_ch_array = iwl_eeprom_band_1; | ||
471 | break; | ||
472 | case 2: /* 4.9GHz band */ | ||
473 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); | ||
474 | *eeprom_ch_array = iwl_eeprom_band_2; | ||
475 | break; | ||
476 | case 3: /* 5.2GHz band */ | ||
477 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); | ||
478 | *eeprom_ch_array = iwl_eeprom_band_3; | ||
479 | break; | ||
480 | case 4: /* 5.5GHz band */ | ||
481 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); | ||
482 | *eeprom_ch_array = iwl_eeprom_band_4; | ||
483 | break; | ||
484 | case 5: /* 5.7GHz band */ | ||
485 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); | ||
486 | *eeprom_ch_array = iwl_eeprom_band_5; | ||
487 | break; | ||
488 | case 6: /* 2.4GHz ht40 channels */ | ||
489 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); | ||
490 | *eeprom_ch_array = iwl_eeprom_band_6; | ||
491 | break; | ||
492 | case 7: /* 5 GHz ht40 channels */ | ||
493 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); | ||
494 | *eeprom_ch_array = iwl_eeprom_band_7; | ||
495 | break; | ||
496 | default: | ||
497 | *eeprom_ch_count = 0; | ||
498 | *eeprom_ch_array = NULL; | ||
499 | WARN_ON(1); | ||
500 | } | ||
501 | } | ||
502 | |||
503 | #define CHECK_AND_PRINT(x) \ | ||
504 | ((eeprom_ch->flags & EEPROM_CHANNEL_##x) ? # x " " : "") | ||
505 | |||
506 | static void iwl_mod_ht40_chan_info(struct device *dev, | ||
507 | struct iwl_eeprom_data *data, int n_channels, | ||
508 | enum ieee80211_band band, u16 channel, | ||
509 | const struct iwl_eeprom_channel *eeprom_ch, | ||
510 | u8 clear_ht40_extension_channel) | ||
511 | { | ||
512 | struct ieee80211_channel *chan = NULL; | ||
513 | int i; | ||
514 | |||
515 | for (i = 0; i < n_channels; i++) { | ||
516 | if (data->channels[i].band != band) | ||
517 | continue; | ||
518 | if (data->channels[i].hw_value != channel) | ||
519 | continue; | ||
520 | chan = &data->channels[i]; | ||
521 | break; | ||
522 | } | ||
523 | |||
524 | if (!chan) | ||
525 | return; | ||
526 | |||
527 | IWL_DEBUG_EEPROM(dev, | ||
528 | "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", | ||
529 | channel, | ||
530 | band == IEEE80211_BAND_5GHZ ? "5.2" : "2.4", | ||
531 | CHECK_AND_PRINT(IBSS), | ||
532 | CHECK_AND_PRINT(ACTIVE), | ||
533 | CHECK_AND_PRINT(RADAR), | ||
534 | CHECK_AND_PRINT(WIDE), | ||
535 | CHECK_AND_PRINT(DFS), | ||
536 | eeprom_ch->flags, | ||
537 | eeprom_ch->max_power_avg, | ||
538 | ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) && | ||
539 | !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? "" | ||
540 | : "not "); | ||
541 | |||
542 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) | ||
543 | chan->flags &= ~clear_ht40_extension_channel; | ||
544 | } | ||
545 | |||
546 | #define CHECK_AND_PRINT_I(x) \ | ||
547 | ((eeprom_ch_info[ch_idx].flags & EEPROM_CHANNEL_##x) ? # x " " : "") | ||
548 | |||
549 | static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | ||
550 | struct iwl_eeprom_data *data, | ||
551 | const u8 *eeprom, size_t eeprom_size) | ||
552 | { | ||
553 | int band, ch_idx; | ||
554 | const struct iwl_eeprom_channel *eeprom_ch_info; | ||
555 | const u8 *eeprom_ch_array; | ||
556 | int eeprom_ch_count; | ||
557 | int n_channels = 0; | ||
558 | |||
559 | /* | ||
560 | * Loop through the 5 EEPROM bands and add them to the parse list | ||
561 | */ | ||
562 | for (band = 1; band <= 5; band++) { | ||
563 | struct ieee80211_channel *channel; | ||
564 | |||
565 | iwl_init_band_reference(cfg, eeprom, eeprom_size, band, | ||
566 | &eeprom_ch_count, &eeprom_ch_info, | ||
567 | &eeprom_ch_array); | ||
568 | |||
569 | /* Loop through each band adding each of the channels */ | ||
570 | for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { | ||
571 | const struct iwl_eeprom_channel *eeprom_ch; | ||
572 | |||
573 | eeprom_ch = &eeprom_ch_info[ch_idx]; | ||
574 | |||
575 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_VALID)) { | ||
576 | IWL_DEBUG_EEPROM(dev, | ||
577 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | ||
578 | eeprom_ch_array[ch_idx], | ||
579 | eeprom_ch_info[ch_idx].flags, | ||
580 | (band != 1) ? "5.2" : "2.4"); | ||
581 | continue; | ||
582 | } | ||
583 | |||
584 | channel = &data->channels[n_channels]; | ||
585 | n_channels++; | ||
586 | |||
587 | channel->hw_value = eeprom_ch_array[ch_idx]; | ||
588 | channel->band = (band == 1) ? IEEE80211_BAND_2GHZ | ||
589 | : IEEE80211_BAND_5GHZ; | ||
590 | channel->center_freq = | ||
591 | ieee80211_channel_to_frequency( | ||
592 | channel->hw_value, channel->band); | ||
593 | |||
594 | /* set no-HT40, will enable as appropriate later */ | ||
595 | channel->flags = IEEE80211_CHAN_NO_HT40; | ||
596 | |||
597 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) | ||
598 | channel->flags |= IEEE80211_CHAN_NO_IBSS; | ||
599 | |||
600 | if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) | ||
601 | channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
602 | |||
603 | if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) | ||
604 | channel->flags |= IEEE80211_CHAN_RADAR; | ||
605 | |||
606 | /* Initialize regulatory-based run-time data */ | ||
607 | channel->max_power = | ||
608 | eeprom_ch_info[ch_idx].max_power_avg; | ||
609 | IWL_DEBUG_EEPROM(dev, | ||
610 | "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", | ||
611 | channel->hw_value, | ||
612 | (band != 1) ? "5.2" : "2.4", | ||
613 | CHECK_AND_PRINT_I(VALID), | ||
614 | CHECK_AND_PRINT_I(IBSS), | ||
615 | CHECK_AND_PRINT_I(ACTIVE), | ||
616 | CHECK_AND_PRINT_I(RADAR), | ||
617 | CHECK_AND_PRINT_I(WIDE), | ||
618 | CHECK_AND_PRINT_I(DFS), | ||
619 | eeprom_ch_info[ch_idx].flags, | ||
620 | eeprom_ch_info[ch_idx].max_power_avg, | ||
621 | ((eeprom_ch_info[ch_idx].flags & | ||
622 | EEPROM_CHANNEL_IBSS) && | ||
623 | !(eeprom_ch_info[ch_idx].flags & | ||
624 | EEPROM_CHANNEL_RADAR)) | ||
625 | ? "" : "not "); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | if (cfg->eeprom_params->enhanced_txpower) { | ||
630 | /* | ||
631 | * for newer device (6000 series and up) | ||
632 | * EEPROM contain enhanced tx power information | ||
633 | * driver need to process addition information | ||
634 | * to determine the max channel tx power limits | ||
635 | */ | ||
636 | iwl_eeprom_enhanced_txpower(dev, data, eeprom, eeprom_size, | ||
637 | n_channels); | ||
638 | } else { | ||
639 | /* All others use data from channel map */ | ||
640 | int i; | ||
641 | |||
642 | data->max_tx_pwr_half_dbm = -128; | ||
643 | |||
644 | for (i = 0; i < n_channels; i++) | ||
645 | data->max_tx_pwr_half_dbm = | ||
646 | max_t(s8, data->max_tx_pwr_half_dbm, | ||
647 | data->channels[i].max_power * 2); | ||
648 | } | ||
649 | |||
650 | /* Check if we do have HT40 channels */ | ||
651 | if (cfg->eeprom_params->regulatory_bands[5] == | ||
652 | EEPROM_REGULATORY_BAND_NO_HT40 && | ||
653 | cfg->eeprom_params->regulatory_bands[6] == | ||
654 | EEPROM_REGULATORY_BAND_NO_HT40) | ||
655 | return n_channels; | ||
656 | |||
657 | /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ | ||
658 | for (band = 6; band <= 7; band++) { | ||
659 | enum ieee80211_band ieeeband; | ||
660 | |||
661 | iwl_init_band_reference(cfg, eeprom, eeprom_size, band, | ||
662 | &eeprom_ch_count, &eeprom_ch_info, | ||
663 | &eeprom_ch_array); | ||
664 | |||
665 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | ||
666 | ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ | ||
667 | : IEEE80211_BAND_5GHZ; | ||
668 | |||
669 | /* Loop through each band adding each of the channels */ | ||
670 | for (ch_idx = 0; ch_idx < eeprom_ch_count; ch_idx++) { | ||
671 | /* Set up driver's info for lower half */ | ||
672 | iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, | ||
673 | eeprom_ch_array[ch_idx], | ||
674 | &eeprom_ch_info[ch_idx], | ||
675 | IEEE80211_CHAN_NO_HT40PLUS); | ||
676 | |||
677 | /* Set up driver's info for upper half */ | ||
678 | iwl_mod_ht40_chan_info(dev, data, n_channels, ieeeband, | ||
679 | eeprom_ch_array[ch_idx] + 4, | ||
680 | &eeprom_ch_info[ch_idx], | ||
681 | IEEE80211_CHAN_NO_HT40MINUS); | ||
682 | } | ||
683 | } | ||
684 | |||
685 | return n_channels; | ||
686 | } | ||
687 | |||
688 | static int iwl_init_sband_channels(struct iwl_eeprom_data *data, | ||
689 | struct ieee80211_supported_band *sband, | ||
690 | int n_channels, enum ieee80211_band band) | ||
691 | { | ||
692 | struct ieee80211_channel *chan = &data->channels[0]; | ||
693 | int n = 0, idx = 0; | ||
694 | |||
695 | while (chan->band != band && idx < n_channels) | ||
696 | chan = &data->channels[++idx]; | ||
697 | |||
698 | sband->channels = &data->channels[idx]; | ||
699 | |||
700 | while (chan->band == band && idx < n_channels) { | ||
701 | chan = &data->channels[++idx]; | ||
702 | n++; | ||
703 | } | ||
704 | |||
705 | sband->n_channels = n; | ||
706 | |||
707 | return n; | ||
708 | } | ||
709 | |||
710 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | ||
711 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | ||
712 | |||
713 | static void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, | ||
714 | struct iwl_eeprom_data *data, | ||
715 | struct ieee80211_sta_ht_cap *ht_info, | ||
716 | enum ieee80211_band band) | ||
717 | { | ||
718 | int max_bit_rate = 0; | ||
719 | u8 rx_chains; | ||
720 | u8 tx_chains; | ||
721 | |||
722 | tx_chains = hweight8(data->valid_tx_ant); | ||
723 | if (cfg->rx_with_siso_diversity) | ||
724 | rx_chains = 1; | ||
725 | else | ||
726 | rx_chains = hweight8(data->valid_rx_ant); | ||
727 | |||
728 | if (!(data->sku & EEPROM_SKU_CAP_11N_ENABLE) || !cfg->ht_params) { | ||
729 | ht_info->ht_supported = false; | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | ht_info->ht_supported = true; | ||
734 | ht_info->cap = 0; | ||
735 | |||
736 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
737 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||
738 | |||
739 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
740 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; | ||
741 | |||
742 | ht_info->mcs.rx_mask[0] = 0xFF; | ||
743 | if (rx_chains >= 2) | ||
744 | ht_info->mcs.rx_mask[1] = 0xFF; | ||
745 | if (rx_chains >= 3) | ||
746 | ht_info->mcs.rx_mask[2] = 0xFF; | ||
747 | |||
748 | if (cfg->ht_params->ht_greenfield_support) | ||
749 | ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; | ||
750 | ht_info->cap |= IEEE80211_HT_CAP_SGI_20; | ||
751 | |||
752 | max_bit_rate = MAX_BIT_RATE_20_MHZ; | ||
753 | |||
754 | if (cfg->ht_params->ht40_bands & BIT(band)) { | ||
755 | ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
756 | ht_info->cap |= IEEE80211_HT_CAP_SGI_40; | ||
757 | ht_info->mcs.rx_mask[4] = 0x01; | ||
758 | max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||
759 | } | ||
760 | |||
761 | /* Highest supported Rx data rate */ | ||
762 | max_bit_rate *= rx_chains; | ||
763 | WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK); | ||
764 | ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate); | ||
765 | |||
766 | /* Tx MCS capabilities */ | ||
767 | ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | ||
768 | if (tx_chains != rx_chains) { | ||
769 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | ||
770 | ht_info->mcs.tx_params |= ((tx_chains - 1) << | ||
771 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | ||
776 | struct iwl_eeprom_data *data, | ||
777 | const u8 *eeprom, size_t eeprom_size) | ||
778 | { | ||
779 | int n_channels = iwl_init_channel_map(dev, cfg, data, | ||
780 | eeprom, eeprom_size); | ||
781 | int n_used = 0; | ||
782 | struct ieee80211_supported_band *sband; | ||
783 | |||
784 | sband = &data->bands[IEEE80211_BAND_2GHZ]; | ||
785 | sband->band = IEEE80211_BAND_2GHZ; | ||
786 | sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS]; | ||
787 | sband->n_bitrates = N_RATES_24; | ||
788 | n_used += iwl_init_sband_channels(data, sband, n_channels, | ||
789 | IEEE80211_BAND_2GHZ); | ||
790 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ); | ||
791 | |||
792 | sband = &data->bands[IEEE80211_BAND_5GHZ]; | ||
793 | sband->band = IEEE80211_BAND_5GHZ; | ||
794 | sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS]; | ||
795 | sband->n_bitrates = N_RATES_52; | ||
796 | n_used += iwl_init_sband_channels(data, sband, n_channels, | ||
797 | IEEE80211_BAND_5GHZ); | ||
798 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); | ||
799 | |||
800 | if (n_channels != n_used) | ||
801 | IWL_ERR_DEV(dev, "EEPROM: used only %d of %d channels\n", | ||
802 | n_used, n_channels); | ||
803 | } | ||
804 | |||
805 | /* EEPROM data functions */ | ||
806 | |||
807 | struct iwl_eeprom_data * | ||
808 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | ||
809 | const u8 *eeprom, size_t eeprom_size) | ||
810 | { | ||
811 | struct iwl_eeprom_data *data; | ||
812 | const void *tmp; | ||
813 | |||
814 | if (WARN_ON(!cfg || !cfg->eeprom_params)) | ||
815 | return NULL; | ||
816 | |||
817 | data = kzalloc(sizeof(*data) + | ||
818 | sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS, | ||
819 | GFP_KERNEL); | ||
820 | if (!data) | ||
821 | return NULL; | ||
822 | |||
823 | /* get MAC address(es) */ | ||
824 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_MAC_ADDRESS); | ||
825 | if (!tmp) | ||
826 | goto err_free; | ||
827 | memcpy(data->hw_addr, tmp, ETH_ALEN); | ||
828 | data->n_hw_addrs = iwl_eeprom_query16(eeprom, eeprom_size, | ||
829 | EEPROM_NUM_MAC_ADDRESS); | ||
830 | |||
831 | if (iwl_eeprom_read_calib(eeprom, eeprom_size, data)) | ||
832 | goto err_free; | ||
833 | |||
834 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, EEPROM_XTAL); | ||
835 | if (!tmp) | ||
836 | goto err_free; | ||
837 | memcpy(data->xtal_calib, tmp, sizeof(data->xtal_calib)); | ||
838 | |||
839 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
840 | EEPROM_RAW_TEMPERATURE); | ||
841 | if (!tmp) | ||
842 | goto err_free; | ||
843 | data->raw_temperature = *(__le16 *)tmp; | ||
844 | |||
845 | tmp = iwl_eeprom_query_addr(eeprom, eeprom_size, | ||
846 | EEPROM_KELVIN_TEMPERATURE); | ||
847 | if (!tmp) | ||
848 | goto err_free; | ||
849 | data->kelvin_temperature = *(__le16 *)tmp; | ||
850 | data->kelvin_voltage = *((__le16 *)tmp + 1); | ||
851 | |||
852 | data->radio_cfg = iwl_eeprom_query16(eeprom, eeprom_size, | ||
853 | EEPROM_RADIO_CONFIG); | ||
854 | data->sku = iwl_eeprom_query16(eeprom, eeprom_size, | ||
855 | EEPROM_SKU_CAP); | ||
856 | data->eeprom_version = iwl_eeprom_query16(eeprom, eeprom_size, | ||
857 | EEPROM_VERSION); | ||
858 | |||
859 | data->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(data->radio_cfg); | ||
860 | data->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(data->radio_cfg); | ||
861 | |||
862 | /* check overrides (some devices have wrong EEPROM) */ | ||
863 | if (cfg->valid_tx_ant) | ||
864 | data->valid_tx_ant = cfg->valid_tx_ant; | ||
865 | if (cfg->valid_rx_ant) | ||
866 | data->valid_rx_ant = cfg->valid_rx_ant; | ||
867 | |||
868 | if (!data->valid_tx_ant || !data->valid_rx_ant) { | ||
869 | IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n", | ||
870 | data->valid_tx_ant, data->valid_rx_ant); | ||
871 | goto err_free; | ||
872 | } | ||
873 | |||
874 | iwl_init_sbands(dev, cfg, data, eeprom, eeprom_size); | ||
875 | |||
876 | return data; | ||
877 | err_free: | ||
878 | kfree(data); | ||
879 | return NULL; | ||
880 | } | ||
881 | EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); | ||
882 | |||
883 | /* helper functions */ | ||
884 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | ||
885 | struct iwl_trans *trans) | ||
886 | { | ||
887 | if (data->eeprom_version >= trans->cfg->eeprom_ver || | ||
888 | data->calib_version >= trans->cfg->eeprom_calib_ver) { | ||
889 | IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", | ||
890 | data->eeprom_version, data->calib_version); | ||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | IWL_ERR(trans, | ||
895 | "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", | ||
896 | data->eeprom_version, trans->cfg->eeprom_ver, | ||
897 | data->calib_version, trans->cfg->eeprom_calib_ver); | ||
898 | return -EINVAL; | ||
899 | } | ||
900 | EXPORT_SYMBOL_GPL(iwl_eeprom_check_version); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h new file mode 100644 index 000000000000..9c07c670a1ce --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | |||
@@ -0,0 +1,138 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | #ifndef __iwl_eeprom_parse_h__ | ||
63 | #define __iwl_eeprom_parse_h__ | ||
64 | |||
65 | #include <linux/types.h> | ||
66 | #include <linux/if_ether.h> | ||
67 | #include "iwl-trans.h" | ||
68 | |||
69 | /* SKU Capabilities (actual values from EEPROM definition) */ | ||
70 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) | ||
71 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) | ||
72 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | ||
73 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | ||
74 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | ||
75 | |||
76 | /* radio config bits (actual values from EEPROM definition) */ | ||
77 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ | ||
78 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ | ||
79 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ | ||
80 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ | ||
81 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ | ||
82 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ | ||
83 | |||
84 | struct iwl_eeprom_data { | ||
85 | int n_hw_addrs; | ||
86 | u8 hw_addr[ETH_ALEN]; | ||
87 | |||
88 | u16 radio_config; | ||
89 | |||
90 | u8 calib_version; | ||
91 | __le16 calib_voltage; | ||
92 | |||
93 | __le16 raw_temperature; | ||
94 | __le16 kelvin_temperature; | ||
95 | __le16 kelvin_voltage; | ||
96 | __le16 xtal_calib[2]; | ||
97 | |||
98 | u16 sku; | ||
99 | u16 radio_cfg; | ||
100 | u16 eeprom_version; | ||
101 | s8 max_tx_pwr_half_dbm; | ||
102 | |||
103 | u8 valid_tx_ant, valid_rx_ant; | ||
104 | |||
105 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | ||
106 | struct ieee80211_channel channels[]; | ||
107 | }; | ||
108 | |||
109 | /** | ||
110 | * iwl_parse_eeprom_data - parse EEPROM data and return values | ||
111 | * | ||
112 | * @dev: device pointer we're parsing for, for debug only | ||
113 | * @cfg: device configuration for parsing and overrides | ||
114 | * @eeprom: the EEPROM data | ||
115 | * @eeprom_size: length of the EEPROM data | ||
116 | * | ||
117 | * This function parses all EEPROM values we need and then | ||
118 | * returns a (newly allocated) struct containing all the | ||
119 | * relevant values for driver use. The struct must be freed | ||
120 | * later with iwl_free_eeprom_data(). | ||
121 | */ | ||
122 | struct iwl_eeprom_data * | ||
123 | iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, | ||
124 | const u8 *eeprom, size_t eeprom_size); | ||
125 | |||
126 | /** | ||
127 | * iwl_free_eeprom_data - free EEPROM data | ||
128 | * @data: the data to free | ||
129 | */ | ||
130 | static inline void iwl_free_eeprom_data(struct iwl_eeprom_data *data) | ||
131 | { | ||
132 | kfree(data); | ||
133 | } | ||
134 | |||
135 | int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | ||
136 | struct iwl_trans *trans); | ||
137 | |||
138 | #endif /* __iwl_eeprom_parse_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c new file mode 100644 index 000000000000..27c7da3c6ed1 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | |||
@@ -0,0 +1,463 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | #include <linux/types.h> | ||
63 | #include <linux/slab.h> | ||
64 | #include <linux/export.h> | ||
65 | |||
66 | #include "iwl-debug.h" | ||
67 | #include "iwl-eeprom-read.h" | ||
68 | #include "iwl-io.h" | ||
69 | #include "iwl-prph.h" | ||
70 | #include "iwl-csr.h" | ||
71 | |||
72 | /* | ||
73 | * EEPROM access time values: | ||
74 | * | ||
75 | * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. | ||
76 | * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). | ||
77 | * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. | ||
78 | * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. | ||
79 | */ | ||
80 | #define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ | ||
81 | |||
82 | #define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ | ||
83 | #define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
84 | |||
85 | |||
86 | /* | ||
87 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
88 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
89 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
90 | * weren't arbitrated by the semaphore. | ||
91 | */ | ||
92 | |||
93 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ | ||
94 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
95 | |||
96 | static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) | ||
97 | { | ||
98 | u16 count; | ||
99 | int ret; | ||
100 | |||
101 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
102 | /* Request semaphore */ | ||
103 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
104 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
105 | |||
106 | /* See if we got it */ | ||
107 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
108 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
109 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
110 | EEPROM_SEM_TIMEOUT); | ||
111 | if (ret >= 0) { | ||
112 | IWL_DEBUG_EEPROM(trans->dev, | ||
113 | "Acquired semaphore after %d tries.\n", | ||
114 | count+1); | ||
115 | return ret; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) | ||
123 | { | ||
124 | iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
125 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
126 | } | ||
127 | |||
128 | static int iwl_eeprom_verify_signature(struct iwl_trans *trans, bool nvm_is_otp) | ||
129 | { | ||
130 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | ||
131 | |||
132 | IWL_DEBUG_EEPROM(trans->dev, "EEPROM signature=0x%08x\n", gp); | ||
133 | |||
134 | switch (gp) { | ||
135 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | ||
136 | if (!nvm_is_otp) { | ||
137 | IWL_ERR(trans, "EEPROM with bad signature: 0x%08x\n", | ||
138 | gp); | ||
139 | return -ENOENT; | ||
140 | } | ||
141 | return 0; | ||
142 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | ||
143 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | ||
144 | if (nvm_is_otp) { | ||
145 | IWL_ERR(trans, "OTP with bad signature: 0x%08x\n", gp); | ||
146 | return -ENOENT; | ||
147 | } | ||
148 | return 0; | ||
149 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | ||
150 | default: | ||
151 | IWL_ERR(trans, | ||
152 | "bad EEPROM/OTP signature, type=%s, EEPROM_GP=0x%08x\n", | ||
153 | nvm_is_otp ? "OTP" : "EEPROM", gp); | ||
154 | return -ENOENT; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /****************************************************************************** | ||
159 | * | ||
160 | * OTP related functions | ||
161 | * | ||
162 | ******************************************************************************/ | ||
163 | |||
164 | static void iwl_set_otp_access_absolute(struct iwl_trans *trans) | ||
165 | { | ||
166 | iwl_read32(trans, CSR_OTP_GP_REG); | ||
167 | |||
168 | iwl_clear_bit(trans, CSR_OTP_GP_REG, | ||
169 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
170 | } | ||
171 | |||
172 | static int iwl_nvm_is_otp(struct iwl_trans *trans) | ||
173 | { | ||
174 | u32 otpgp; | ||
175 | |||
176 | /* OTP only valid for CP/PP and after */ | ||
177 | switch (trans->hw_rev & CSR_HW_REV_TYPE_MSK) { | ||
178 | case CSR_HW_REV_TYPE_NONE: | ||
179 | IWL_ERR(trans, "Unknown hardware type\n"); | ||
180 | return -EIO; | ||
181 | case CSR_HW_REV_TYPE_5300: | ||
182 | case CSR_HW_REV_TYPE_5350: | ||
183 | case CSR_HW_REV_TYPE_5100: | ||
184 | case CSR_HW_REV_TYPE_5150: | ||
185 | return 0; | ||
186 | default: | ||
187 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
188 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | ||
189 | return 1; | ||
190 | return 0; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static int iwl_init_otp_access(struct iwl_trans *trans) | ||
195 | { | ||
196 | int ret; | ||
197 | |||
198 | /* Enable 40MHz radio clock */ | ||
199 | iwl_write32(trans, CSR_GP_CNTRL, | ||
200 | iwl_read32(trans, CSR_GP_CNTRL) | | ||
201 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
202 | |||
203 | /* wait for clock to be ready */ | ||
204 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
205 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
206 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
207 | 25000); | ||
208 | if (ret < 0) { | ||
209 | IWL_ERR(trans, "Time out access OTP\n"); | ||
210 | } else { | ||
211 | iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, | ||
212 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
213 | udelay(5); | ||
214 | iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, | ||
215 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
216 | |||
217 | /* | ||
218 | * CSR auto clock gate disable bit - | ||
219 | * this is only applicable for HW with OTP shadow RAM | ||
220 | */ | ||
221 | if (trans->cfg->base_params->shadow_ram_support) | ||
222 | iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, | ||
223 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | ||
224 | } | ||
225 | return ret; | ||
226 | } | ||
227 | |||
228 | static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | ||
229 | __le16 *eeprom_data) | ||
230 | { | ||
231 | int ret = 0; | ||
232 | u32 r; | ||
233 | u32 otpgp; | ||
234 | |||
235 | iwl_write32(trans, CSR_EEPROM_REG, | ||
236 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
237 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
238 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
239 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
240 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
241 | if (ret < 0) { | ||
242 | IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); | ||
243 | return ret; | ||
244 | } | ||
245 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
246 | /* check for ECC errors: */ | ||
247 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
248 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | ||
249 | /* stop in this case */ | ||
250 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | ||
251 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
252 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
253 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | ||
257 | /* continue in this case */ | ||
258 | /* set the correctable OTP ECC bit for acknowledgement */ | ||
259 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
260 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | ||
261 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); | ||
262 | } | ||
263 | *eeprom_data = cpu_to_le16(r >> 16); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * iwl_is_otp_empty: check for empty OTP | ||
269 | */ | ||
270 | static bool iwl_is_otp_empty(struct iwl_trans *trans) | ||
271 | { | ||
272 | u16 next_link_addr = 0; | ||
273 | __le16 link_value; | ||
274 | bool is_empty = false; | ||
275 | |||
276 | /* locate the beginning of OTP link list */ | ||
277 | if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { | ||
278 | if (!link_value) { | ||
279 | IWL_ERR(trans, "OTP is empty\n"); | ||
280 | is_empty = true; | ||
281 | } | ||
282 | } else { | ||
283 | IWL_ERR(trans, "Unable to read first block of OTP list.\n"); | ||
284 | is_empty = true; | ||
285 | } | ||
286 | |||
287 | return is_empty; | ||
288 | } | ||
289 | |||
290 | |||
291 | /* | ||
292 | * iwl_find_otp_image: find EEPROM image in OTP | ||
293 | * finding the OTP block that contains the EEPROM image. | ||
294 | * the last valid block on the link list (the block _before_ the last block) | ||
295 | * is the block we should read and used to configure the device. | ||
296 | * If all the available OTP blocks are full, the last block will be the block | ||
297 | * we should read and used to configure the device. | ||
298 | * only perform this operation if shadow RAM is disabled | ||
299 | */ | ||
300 | static int iwl_find_otp_image(struct iwl_trans *trans, | ||
301 | u16 *validblockaddr) | ||
302 | { | ||
303 | u16 next_link_addr = 0, valid_addr; | ||
304 | __le16 link_value = 0; | ||
305 | int usedblocks = 0; | ||
306 | |||
307 | /* set addressing mode to absolute to traverse the link list */ | ||
308 | iwl_set_otp_access_absolute(trans); | ||
309 | |||
310 | /* checking for empty OTP or error */ | ||
311 | if (iwl_is_otp_empty(trans)) | ||
312 | return -EINVAL; | ||
313 | |||
314 | /* | ||
315 | * start traverse link list | ||
316 | * until reach the max number of OTP blocks | ||
317 | * different devices have different number of OTP blocks | ||
318 | */ | ||
319 | do { | ||
320 | /* save current valid block address | ||
321 | * check for more block on the link list | ||
322 | */ | ||
323 | valid_addr = next_link_addr; | ||
324 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | ||
325 | IWL_DEBUG_EEPROM(trans->dev, "OTP blocks %d addr 0x%x\n", | ||
326 | usedblocks, next_link_addr); | ||
327 | if (iwl_read_otp_word(trans, next_link_addr, &link_value)) | ||
328 | return -EINVAL; | ||
329 | if (!link_value) { | ||
330 | /* | ||
331 | * reach the end of link list, return success and | ||
332 | * set address point to the starting address | ||
333 | * of the image | ||
334 | */ | ||
335 | *validblockaddr = valid_addr; | ||
336 | /* skip first 2 bytes (link list pointer) */ | ||
337 | *validblockaddr += 2; | ||
338 | return 0; | ||
339 | } | ||
340 | /* more in the link list, continue */ | ||
341 | usedblocks++; | ||
342 | } while (usedblocks <= trans->cfg->base_params->max_ll_items); | ||
343 | |||
344 | /* OTP has no valid blocks */ | ||
345 | IWL_DEBUG_EEPROM(trans->dev, "OTP has no valid blocks\n"); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * iwl_read_eeprom - read EEPROM contents | ||
351 | * | ||
352 | * Load the EEPROM contents from adapter and return it | ||
353 | * and its size. | ||
354 | * | ||
355 | * NOTE: This routine uses the non-debug IO access functions. | ||
356 | */ | ||
357 | int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) | ||
358 | { | ||
359 | __le16 *e; | ||
360 | u32 gp = iwl_read32(trans, CSR_EEPROM_GP); | ||
361 | int sz; | ||
362 | int ret; | ||
363 | u16 addr; | ||
364 | u16 validblockaddr = 0; | ||
365 | u16 cache_addr = 0; | ||
366 | int nvm_is_otp; | ||
367 | |||
368 | if (!eeprom || !eeprom_size) | ||
369 | return -EINVAL; | ||
370 | |||
371 | nvm_is_otp = iwl_nvm_is_otp(trans); | ||
372 | if (nvm_is_otp < 0) | ||
373 | return nvm_is_otp; | ||
374 | |||
375 | sz = trans->cfg->base_params->eeprom_size; | ||
376 | IWL_DEBUG_EEPROM(trans->dev, "NVM size = %d\n", sz); | ||
377 | |||
378 | e = kmalloc(sz, GFP_KERNEL); | ||
379 | if (!e) | ||
380 | return -ENOMEM; | ||
381 | |||
382 | ret = iwl_eeprom_verify_signature(trans, nvm_is_otp); | ||
383 | if (ret < 0) { | ||
384 | IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | ||
385 | goto err_free; | ||
386 | } | ||
387 | |||
388 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
389 | ret = iwl_eeprom_acquire_semaphore(trans); | ||
390 | if (ret < 0) { | ||
391 | IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); | ||
392 | goto err_free; | ||
393 | } | ||
394 | |||
395 | if (nvm_is_otp) { | ||
396 | ret = iwl_init_otp_access(trans); | ||
397 | if (ret) { | ||
398 | IWL_ERR(trans, "Failed to initialize OTP access.\n"); | ||
399 | goto err_unlock; | ||
400 | } | ||
401 | |||
402 | iwl_write32(trans, CSR_EEPROM_GP, | ||
403 | iwl_read32(trans, CSR_EEPROM_GP) & | ||
404 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | ||
405 | |||
406 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
407 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | ||
408 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
409 | /* traversing the linked list if no shadow ram supported */ | ||
410 | if (!trans->cfg->base_params->shadow_ram_support) { | ||
411 | ret = iwl_find_otp_image(trans, &validblockaddr); | ||
412 | if (ret) | ||
413 | goto err_unlock; | ||
414 | } | ||
415 | for (addr = validblockaddr; addr < validblockaddr + sz; | ||
416 | addr += sizeof(u16)) { | ||
417 | __le16 eeprom_data; | ||
418 | |||
419 | ret = iwl_read_otp_word(trans, addr, &eeprom_data); | ||
420 | if (ret) | ||
421 | goto err_unlock; | ||
422 | e[cache_addr / 2] = eeprom_data; | ||
423 | cache_addr += sizeof(u16); | ||
424 | } | ||
425 | } else { | ||
426 | /* eeprom is an array of 16bit values */ | ||
427 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
428 | u32 r; | ||
429 | |||
430 | iwl_write32(trans, CSR_EEPROM_REG, | ||
431 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
432 | |||
433 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
434 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
435 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
436 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
437 | if (ret < 0) { | ||
438 | IWL_ERR(trans, | ||
439 | "Time out reading EEPROM[%d]\n", addr); | ||
440 | goto err_unlock; | ||
441 | } | ||
442 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
443 | e[addr / 2] = cpu_to_le16(r >> 16); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | IWL_DEBUG_EEPROM(trans->dev, "NVM Type: %s\n", | ||
448 | nvm_is_otp ? "OTP" : "EEPROM"); | ||
449 | |||
450 | iwl_eeprom_release_semaphore(trans); | ||
451 | |||
452 | *eeprom_size = sz; | ||
453 | *eeprom = (u8 *)e; | ||
454 | return 0; | ||
455 | |||
456 | err_unlock: | ||
457 | iwl_eeprom_release_semaphore(trans); | ||
458 | err_free: | ||
459 | kfree(e); | ||
460 | |||
461 | return ret; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(iwl_read_eeprom); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h new file mode 100644 index 000000000000..1337c9d36fee --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | #ifndef __iwl_eeprom_h__ | ||
64 | #define __iwl_eeprom_h__ | ||
65 | |||
66 | #include "iwl-trans.h" | ||
67 | |||
68 | int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size); | ||
69 | |||
70 | #endif /* __iwl_eeprom_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c deleted file mode 100644 index b8e2b223ac36..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ /dev/null | |||
@@ -1,1148 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | |||
64 | #include <linux/kernel.h> | ||
65 | #include <linux/module.h> | ||
66 | #include <linux/slab.h> | ||
67 | #include <linux/init.h> | ||
68 | |||
69 | #include <net/mac80211.h> | ||
70 | |||
71 | #include "iwl-dev.h" | ||
72 | #include "iwl-debug.h" | ||
73 | #include "iwl-agn.h" | ||
74 | #include "iwl-eeprom.h" | ||
75 | #include "iwl-io.h" | ||
76 | #include "iwl-prph.h" | ||
77 | |||
78 | /************************** EEPROM BANDS **************************** | ||
79 | * | ||
80 | * The iwl_eeprom_band definitions below provide the mapping from the | ||
81 | * EEPROM contents to the specific channel number supported for each | ||
82 | * band. | ||
83 | * | ||
84 | * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 | ||
85 | * definition below maps to physical channel 42 in the 5.2GHz spectrum. | ||
86 | * The specific geography and calibration information for that channel | ||
87 | * is contained in the eeprom map itself. | ||
88 | * | ||
89 | * During init, we copy the eeprom information and channel map | ||
90 | * information into priv->channel_info_24/52 and priv->channel_map_24/52 | ||
91 | * | ||
92 | * channel_map_24/52 provides the index in the channel_info array for a | ||
93 | * given channel. We have to have two separate maps as there is channel | ||
94 | * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and | ||
95 | * band_2 | ||
96 | * | ||
97 | * A value of 0xff stored in the channel_map indicates that the channel | ||
98 | * is not supported by the hardware at all. | ||
99 | * | ||
100 | * A value of 0xfe in the channel_map indicates that the channel is not | ||
101 | * valid for Tx with the current hardware. This means that | ||
102 | * while the system can tune and receive on a given channel, it may not | ||
103 | * be able to associate or transmit any frames on that | ||
104 | * channel. There is no corresponding channel information for that | ||
105 | * entry. | ||
106 | * | ||
107 | *********************************************************************/ | ||
108 | |||
109 | /* 2.4 GHz */ | ||
110 | const u8 iwl_eeprom_band_1[14] = { | ||
111 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 | ||
112 | }; | ||
113 | |||
114 | /* 5.2 GHz bands */ | ||
115 | static const u8 iwl_eeprom_band_2[] = { /* 4915-5080MHz */ | ||
116 | 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 | ||
117 | }; | ||
118 | |||
119 | static const u8 iwl_eeprom_band_3[] = { /* 5170-5320MHz */ | ||
120 | 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 | ||
121 | }; | ||
122 | |||
123 | static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ | ||
124 | 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 | ||
125 | }; | ||
126 | |||
127 | static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ | ||
128 | 145, 149, 153, 157, 161, 165 | ||
129 | }; | ||
130 | |||
131 | static const u8 iwl_eeprom_band_6[] = { /* 2.4 ht40 channel */ | ||
132 | 1, 2, 3, 4, 5, 6, 7 | ||
133 | }; | ||
134 | |||
135 | static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ | ||
136 | 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 | ||
137 | }; | ||
138 | |||
139 | /****************************************************************************** | ||
140 | * | ||
141 | * generic NVM functions | ||
142 | * | ||
143 | ******************************************************************************/ | ||
144 | |||
145 | /* | ||
146 | * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||
147 | * when accessing the EEPROM; each access is a series of pulses to/from the | ||
148 | * EEPROM chip, not a single event, so even reads could conflict if they | ||
149 | * weren't arbitrated by the semaphore. | ||
150 | */ | ||
151 | |||
152 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ | ||
153 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
154 | |||
155 | static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) | ||
156 | { | ||
157 | u16 count; | ||
158 | int ret; | ||
159 | |||
160 | for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||
161 | /* Request semaphore */ | ||
162 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
163 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
164 | |||
165 | /* See if we got it */ | ||
166 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
167 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
168 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||
169 | EEPROM_SEM_TIMEOUT); | ||
170 | if (ret >= 0) { | ||
171 | IWL_DEBUG_EEPROM(trans, | ||
172 | "Acquired semaphore after %d tries.\n", | ||
173 | count+1); | ||
174 | return ret; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) | ||
182 | { | ||
183 | iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, | ||
184 | CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||
185 | |||
186 | } | ||
187 | |||
188 | static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | ||
189 | { | ||
190 | u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP) & | ||
191 | CSR_EEPROM_GP_VALID_MSK; | ||
192 | int ret = 0; | ||
193 | |||
194 | IWL_DEBUG_EEPROM(priv, "EEPROM signature=0x%08x\n", gp); | ||
195 | switch (gp) { | ||
196 | case CSR_EEPROM_GP_BAD_SIG_EEP_GOOD_SIG_OTP: | ||
197 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_OTP) { | ||
198 | IWL_ERR(priv, "EEPROM with bad signature: 0x%08x\n", | ||
199 | gp); | ||
200 | ret = -ENOENT; | ||
201 | } | ||
202 | break; | ||
203 | case CSR_EEPROM_GP_GOOD_SIG_EEP_LESS_THAN_4K: | ||
204 | case CSR_EEPROM_GP_GOOD_SIG_EEP_MORE_THAN_4K: | ||
205 | if (priv->nvm_device_type != NVM_DEVICE_TYPE_EEPROM) { | ||
206 | IWL_ERR(priv, "OTP with bad signature: 0x%08x\n", gp); | ||
207 | ret = -ENOENT; | ||
208 | } | ||
209 | break; | ||
210 | case CSR_EEPROM_GP_BAD_SIGNATURE_BOTH_EEP_AND_OTP: | ||
211 | default: | ||
212 | IWL_ERR(priv, "bad EEPROM/OTP signature, type=%s, " | ||
213 | "EEPROM_GP=0x%08x\n", | ||
214 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
215 | ? "OTP" : "EEPROM", gp); | ||
216 | ret = -ENOENT; | ||
217 | break; | ||
218 | } | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset) | ||
223 | { | ||
224 | if (!priv->eeprom) | ||
225 | return 0; | ||
226 | return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); | ||
227 | } | ||
228 | |||
229 | int iwl_eeprom_check_version(struct iwl_priv *priv) | ||
230 | { | ||
231 | u16 eeprom_ver; | ||
232 | u16 calib_ver; | ||
233 | |||
234 | eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | ||
235 | calib_ver = iwl_eeprom_calib_version(priv); | ||
236 | |||
237 | if (eeprom_ver < priv->cfg->eeprom_ver || | ||
238 | calib_ver < priv->cfg->eeprom_calib_ver) | ||
239 | goto err; | ||
240 | |||
241 | IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", | ||
242 | eeprom_ver, calib_ver); | ||
243 | |||
244 | return 0; | ||
245 | err: | ||
246 | IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " | ||
247 | "CALIB=0x%x < 0x%x\n", | ||
248 | eeprom_ver, priv->cfg->eeprom_ver, | ||
249 | calib_ver, priv->cfg->eeprom_calib_ver); | ||
250 | return -EINVAL; | ||
251 | |||
252 | } | ||
253 | |||
254 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | ||
255 | { | ||
256 | u16 radio_cfg; | ||
257 | |||
258 | priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); | ||
259 | if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && | ||
260 | !priv->cfg->ht_params) { | ||
261 | IWL_ERR(priv, "Invalid 11n configuration\n"); | ||
262 | return -EINVAL; | ||
263 | } | ||
264 | |||
265 | if (!priv->hw_params.sku) { | ||
266 | IWL_ERR(priv, "Invalid device sku\n"); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->hw_params.sku); | ||
271 | |||
272 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
273 | |||
274 | priv->hw_params.valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); | ||
275 | priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); | ||
276 | |||
277 | /* check overrides (some devices have wrong EEPROM) */ | ||
278 | if (priv->cfg->valid_tx_ant) | ||
279 | priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; | ||
280 | if (priv->cfg->valid_rx_ant) | ||
281 | priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; | ||
282 | |||
283 | if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) { | ||
284 | IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", | ||
285 | priv->hw_params.valid_tx_ant, | ||
286 | priv->hw_params.valid_rx_ant); | ||
287 | return -EINVAL; | ||
288 | } | ||
289 | |||
290 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | ||
291 | priv->hw_params.valid_tx_ant, priv->hw_params.valid_rx_ant); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv) | ||
297 | { | ||
298 | struct iwl_eeprom_calib_hdr *hdr; | ||
299 | |||
300 | hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv, | ||
301 | EEPROM_CALIB_ALL); | ||
302 | return hdr->version; | ||
303 | } | ||
304 | |||
305 | static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address) | ||
306 | { | ||
307 | u16 offset = 0; | ||
308 | |||
309 | if ((address & INDIRECT_ADDRESS) == 0) | ||
310 | return address; | ||
311 | |||
312 | switch (address & INDIRECT_TYPE_MSK) { | ||
313 | case INDIRECT_HOST: | ||
314 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST); | ||
315 | break; | ||
316 | case INDIRECT_GENERAL: | ||
317 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL); | ||
318 | break; | ||
319 | case INDIRECT_REGULATORY: | ||
320 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); | ||
321 | break; | ||
322 | case INDIRECT_TXP_LIMIT: | ||
323 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); | ||
324 | break; | ||
325 | case INDIRECT_TXP_LIMIT_SIZE: | ||
326 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); | ||
327 | break; | ||
328 | case INDIRECT_CALIBRATION: | ||
329 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); | ||
330 | break; | ||
331 | case INDIRECT_PROCESS_ADJST: | ||
332 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST); | ||
333 | break; | ||
334 | case INDIRECT_OTHERS: | ||
335 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS); | ||
336 | break; | ||
337 | default: | ||
338 | IWL_ERR(priv, "illegal indirect type: 0x%X\n", | ||
339 | address & INDIRECT_TYPE_MSK); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | /* translate the offset from words to byte */ | ||
344 | return (address & ADDRESS_MSK) + (offset << 1); | ||
345 | } | ||
346 | |||
347 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset) | ||
348 | { | ||
349 | u32 address = eeprom_indirect_address(priv, offset); | ||
350 | BUG_ON(address >= priv->cfg->base_params->eeprom_size); | ||
351 | return &priv->eeprom[address]; | ||
352 | } | ||
353 | |||
354 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac) | ||
355 | { | ||
356 | const u8 *addr = iwl_eeprom_query_addr(priv, | ||
357 | EEPROM_MAC_ADDRESS); | ||
358 | memcpy(mac, addr, ETH_ALEN); | ||
359 | } | ||
360 | |||
361 | /****************************************************************************** | ||
362 | * | ||
363 | * OTP related functions | ||
364 | * | ||
365 | ******************************************************************************/ | ||
366 | |||
367 | static void iwl_set_otp_access(struct iwl_trans *trans, | ||
368 | enum iwl_access_mode mode) | ||
369 | { | ||
370 | iwl_read32(trans, CSR_OTP_GP_REG); | ||
371 | |||
372 | if (mode == IWL_OTP_ACCESS_ABSOLUTE) | ||
373 | iwl_clear_bit(trans, CSR_OTP_GP_REG, | ||
374 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
375 | else | ||
376 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
377 | CSR_OTP_GP_REG_OTP_ACCESS_MODE); | ||
378 | } | ||
379 | |||
380 | static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev) | ||
381 | { | ||
382 | u32 otpgp; | ||
383 | int nvm_type; | ||
384 | |||
385 | /* OTP only valid for CP/PP and after */ | ||
386 | switch (hw_rev & CSR_HW_REV_TYPE_MSK) { | ||
387 | case CSR_HW_REV_TYPE_NONE: | ||
388 | IWL_ERR(trans, "Unknown hardware type\n"); | ||
389 | return -ENOENT; | ||
390 | case CSR_HW_REV_TYPE_5300: | ||
391 | case CSR_HW_REV_TYPE_5350: | ||
392 | case CSR_HW_REV_TYPE_5100: | ||
393 | case CSR_HW_REV_TYPE_5150: | ||
394 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | ||
395 | break; | ||
396 | default: | ||
397 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
398 | if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) | ||
399 | nvm_type = NVM_DEVICE_TYPE_OTP; | ||
400 | else | ||
401 | nvm_type = NVM_DEVICE_TYPE_EEPROM; | ||
402 | break; | ||
403 | } | ||
404 | return nvm_type; | ||
405 | } | ||
406 | |||
407 | static int iwl_init_otp_access(struct iwl_trans *trans) | ||
408 | { | ||
409 | int ret; | ||
410 | |||
411 | /* Enable 40MHz radio clock */ | ||
412 | iwl_write32(trans, CSR_GP_CNTRL, | ||
413 | iwl_read32(trans, CSR_GP_CNTRL) | | ||
414 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
415 | |||
416 | /* wait for clock to be ready */ | ||
417 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | ||
418 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
419 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | ||
420 | 25000); | ||
421 | if (ret < 0) | ||
422 | IWL_ERR(trans, "Time out access OTP\n"); | ||
423 | else { | ||
424 | iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, | ||
425 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
426 | udelay(5); | ||
427 | iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, | ||
428 | APMG_PS_CTRL_VAL_RESET_REQ); | ||
429 | |||
430 | /* | ||
431 | * CSR auto clock gate disable bit - | ||
432 | * this is only applicable for HW with OTP shadow RAM | ||
433 | */ | ||
434 | if (trans->cfg->base_params->shadow_ram_support) | ||
435 | iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, | ||
436 | CSR_RESET_LINK_PWR_MGMT_DISABLED); | ||
437 | } | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, | ||
442 | __le16 *eeprom_data) | ||
443 | { | ||
444 | int ret = 0; | ||
445 | u32 r; | ||
446 | u32 otpgp; | ||
447 | |||
448 | iwl_write32(trans, CSR_EEPROM_REG, | ||
449 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
450 | ret = iwl_poll_bit(trans, CSR_EEPROM_REG, | ||
451 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
452 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
453 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
454 | if (ret < 0) { | ||
455 | IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); | ||
456 | return ret; | ||
457 | } | ||
458 | r = iwl_read32(trans, CSR_EEPROM_REG); | ||
459 | /* check for ECC errors: */ | ||
460 | otpgp = iwl_read32(trans, CSR_OTP_GP_REG); | ||
461 | if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { | ||
462 | /* stop in this case */ | ||
463 | /* set the uncorrectable OTP ECC bit for acknowledgement */ | ||
464 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
465 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
466 | IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { | ||
470 | /* continue in this case */ | ||
471 | /* set the correctable OTP ECC bit for acknowledgement */ | ||
472 | iwl_set_bit(trans, CSR_OTP_GP_REG, | ||
473 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); | ||
474 | IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); | ||
475 | } | ||
476 | *eeprom_data = cpu_to_le16(r >> 16); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | /* | ||
481 | * iwl_is_otp_empty: check for empty OTP | ||
482 | */ | ||
483 | static bool iwl_is_otp_empty(struct iwl_trans *trans) | ||
484 | { | ||
485 | u16 next_link_addr = 0; | ||
486 | __le16 link_value; | ||
487 | bool is_empty = false; | ||
488 | |||
489 | /* locate the beginning of OTP link list */ | ||
490 | if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { | ||
491 | if (!link_value) { | ||
492 | IWL_ERR(trans, "OTP is empty\n"); | ||
493 | is_empty = true; | ||
494 | } | ||
495 | } else { | ||
496 | IWL_ERR(trans, "Unable to read first block of OTP list.\n"); | ||
497 | is_empty = true; | ||
498 | } | ||
499 | |||
500 | return is_empty; | ||
501 | } | ||
502 | |||
503 | |||
504 | /* | ||
505 | * iwl_find_otp_image: find EEPROM image in OTP | ||
506 | * finding the OTP block that contains the EEPROM image. | ||
507 | * the last valid block on the link list (the block _before_ the last block) | ||
508 | * is the block we should read and used to configure the device. | ||
509 | * If all the available OTP blocks are full, the last block will be the block | ||
510 | * we should read and used to configure the device. | ||
511 | * only perform this operation if shadow RAM is disabled | ||
512 | */ | ||
513 | static int iwl_find_otp_image(struct iwl_trans *trans, | ||
514 | u16 *validblockaddr) | ||
515 | { | ||
516 | u16 next_link_addr = 0, valid_addr; | ||
517 | __le16 link_value = 0; | ||
518 | int usedblocks = 0; | ||
519 | |||
520 | /* set addressing mode to absolute to traverse the link list */ | ||
521 | iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE); | ||
522 | |||
523 | /* checking for empty OTP or error */ | ||
524 | if (iwl_is_otp_empty(trans)) | ||
525 | return -EINVAL; | ||
526 | |||
527 | /* | ||
528 | * start traverse link list | ||
529 | * until reach the max number of OTP blocks | ||
530 | * different devices have different number of OTP blocks | ||
531 | */ | ||
532 | do { | ||
533 | /* save current valid block address | ||
534 | * check for more block on the link list | ||
535 | */ | ||
536 | valid_addr = next_link_addr; | ||
537 | next_link_addr = le16_to_cpu(link_value) * sizeof(u16); | ||
538 | IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n", | ||
539 | usedblocks, next_link_addr); | ||
540 | if (iwl_read_otp_word(trans, next_link_addr, &link_value)) | ||
541 | return -EINVAL; | ||
542 | if (!link_value) { | ||
543 | /* | ||
544 | * reach the end of link list, return success and | ||
545 | * set address point to the starting address | ||
546 | * of the image | ||
547 | */ | ||
548 | *validblockaddr = valid_addr; | ||
549 | /* skip first 2 bytes (link list pointer) */ | ||
550 | *validblockaddr += 2; | ||
551 | return 0; | ||
552 | } | ||
553 | /* more in the link list, continue */ | ||
554 | usedblocks++; | ||
555 | } while (usedblocks <= trans->cfg->base_params->max_ll_items); | ||
556 | |||
557 | /* OTP has no valid blocks */ | ||
558 | IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n"); | ||
559 | return -EINVAL; | ||
560 | } | ||
561 | |||
562 | /****************************************************************************** | ||
563 | * | ||
564 | * Tx Power related functions | ||
565 | * | ||
566 | ******************************************************************************/ | ||
567 | /** | ||
568 | * iwl_get_max_txpower_avg - get the highest tx power from all chains. | ||
569 | * find the highest tx power from all chains for the channel | ||
570 | */ | ||
571 | static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, | ||
572 | struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, | ||
573 | int element, s8 *max_txpower_in_half_dbm) | ||
574 | { | ||
575 | s8 max_txpower_avg = 0; /* (dBm) */ | ||
576 | |||
577 | /* Take the highest tx power from any valid chains */ | ||
578 | if ((priv->hw_params.valid_tx_ant & ANT_A) && | ||
579 | (enhanced_txpower[element].chain_a_max > max_txpower_avg)) | ||
580 | max_txpower_avg = enhanced_txpower[element].chain_a_max; | ||
581 | if ((priv->hw_params.valid_tx_ant & ANT_B) && | ||
582 | (enhanced_txpower[element].chain_b_max > max_txpower_avg)) | ||
583 | max_txpower_avg = enhanced_txpower[element].chain_b_max; | ||
584 | if ((priv->hw_params.valid_tx_ant & ANT_C) && | ||
585 | (enhanced_txpower[element].chain_c_max > max_txpower_avg)) | ||
586 | max_txpower_avg = enhanced_txpower[element].chain_c_max; | ||
587 | if (((priv->hw_params.valid_tx_ant == ANT_AB) | | ||
588 | (priv->hw_params.valid_tx_ant == ANT_BC) | | ||
589 | (priv->hw_params.valid_tx_ant == ANT_AC)) && | ||
590 | (enhanced_txpower[element].mimo2_max > max_txpower_avg)) | ||
591 | max_txpower_avg = enhanced_txpower[element].mimo2_max; | ||
592 | if ((priv->hw_params.valid_tx_ant == ANT_ABC) && | ||
593 | (enhanced_txpower[element].mimo3_max > max_txpower_avg)) | ||
594 | max_txpower_avg = enhanced_txpower[element].mimo3_max; | ||
595 | |||
596 | /* | ||
597 | * max. tx power in EEPROM is in 1/2 dBm format | ||
598 | * convert from 1/2 dBm to dBm (round-up convert) | ||
599 | * but we also do not want to loss 1/2 dBm resolution which | ||
600 | * will impact performance | ||
601 | */ | ||
602 | *max_txpower_in_half_dbm = max_txpower_avg; | ||
603 | return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); | ||
604 | } | ||
605 | |||
606 | static void | ||
607 | iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, | ||
608 | struct iwl_eeprom_enhanced_txpwr *txp, | ||
609 | s8 max_txpower_avg) | ||
610 | { | ||
611 | int ch_idx; | ||
612 | bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; | ||
613 | enum ieee80211_band band; | ||
614 | |||
615 | band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? | ||
616 | IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; | ||
617 | |||
618 | for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { | ||
619 | struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; | ||
620 | |||
621 | /* update matching channel or from common data only */ | ||
622 | if (txp->channel != 0 && ch_info->channel != txp->channel) | ||
623 | continue; | ||
624 | |||
625 | /* update matching band only */ | ||
626 | if (band != ch_info->band) | ||
627 | continue; | ||
628 | |||
629 | if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { | ||
630 | ch_info->max_power_avg = max_txpower_avg; | ||
631 | ch_info->curr_txpow = max_txpower_avg; | ||
632 | ch_info->scan_power = max_txpower_avg; | ||
633 | } | ||
634 | |||
635 | if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) | ||
636 | ch_info->ht40_max_power_avg = max_txpower_avg; | ||
637 | } | ||
638 | } | ||
639 | |||
640 | #define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) | ||
641 | #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) | ||
642 | #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) | ||
643 | |||
644 | #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ | ||
645 | ? # x " " : "") | ||
646 | |||
647 | static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) | ||
648 | { | ||
649 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | ||
650 | int idx, entries; | ||
651 | __le16 *txp_len; | ||
652 | s8 max_txp_avg, max_txp_avg_halfdbm; | ||
653 | |||
654 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | ||
655 | |||
656 | /* the length is in 16-bit words, but we want entries */ | ||
657 | txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); | ||
658 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | ||
659 | |||
660 | txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS); | ||
661 | |||
662 | for (idx = 0; idx < entries; idx++) { | ||
663 | txp = &txp_array[idx]; | ||
664 | /* skip invalid entries */ | ||
665 | if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) | ||
666 | continue; | ||
667 | |||
668 | IWL_DEBUG_EEPROM(priv, "%s %d:\t %s%s%s%s%s%s%s%s (0x%02x)\n", | ||
669 | (txp->channel && (txp->flags & | ||
670 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE)) ? | ||
671 | "Common " : (txp->channel) ? | ||
672 | "Channel" : "Common", | ||
673 | (txp->channel), | ||
674 | TXP_CHECK_AND_PRINT(VALID), | ||
675 | TXP_CHECK_AND_PRINT(BAND_52G), | ||
676 | TXP_CHECK_AND_PRINT(OFDM), | ||
677 | TXP_CHECK_AND_PRINT(40MHZ), | ||
678 | TXP_CHECK_AND_PRINT(HT_AP), | ||
679 | TXP_CHECK_AND_PRINT(RES1), | ||
680 | TXP_CHECK_AND_PRINT(RES2), | ||
681 | TXP_CHECK_AND_PRINT(COMMON_TYPE), | ||
682 | txp->flags); | ||
683 | IWL_DEBUG_EEPROM(priv, "\t\t chain_A: 0x%02x " | ||
684 | "chain_B: 0X%02x chain_C: 0X%02x\n", | ||
685 | txp->chain_a_max, txp->chain_b_max, | ||
686 | txp->chain_c_max); | ||
687 | IWL_DEBUG_EEPROM(priv, "\t\t MIMO2: 0x%02x " | ||
688 | "MIMO3: 0x%02x High 20_on_40: 0x%02x " | ||
689 | "Low 20_on_40: 0x%02x\n", | ||
690 | txp->mimo2_max, txp->mimo3_max, | ||
691 | ((txp->delta_20_in_40 & 0xf0) >> 4), | ||
692 | (txp->delta_20_in_40 & 0x0f)); | ||
693 | |||
694 | max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, | ||
695 | &max_txp_avg_halfdbm); | ||
696 | |||
697 | /* | ||
698 | * Update the user limit values values to the highest | ||
699 | * power supported by any channel | ||
700 | */ | ||
701 | if (max_txp_avg > priv->tx_power_user_lmt) | ||
702 | priv->tx_power_user_lmt = max_txp_avg; | ||
703 | if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) | ||
704 | priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; | ||
705 | |||
706 | iwl_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * iwl_eeprom_init - read EEPROM contents | ||
712 | * | ||
713 | * Load the EEPROM contents from adapter into priv->eeprom | ||
714 | * | ||
715 | * NOTE: This routine uses the non-debug IO access functions. | ||
716 | */ | ||
717 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | ||
718 | { | ||
719 | __le16 *e; | ||
720 | u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP); | ||
721 | int sz; | ||
722 | int ret; | ||
723 | u16 addr; | ||
724 | u16 validblockaddr = 0; | ||
725 | u16 cache_addr = 0; | ||
726 | |||
727 | priv->nvm_device_type = iwl_get_nvm_type(priv->trans, hw_rev); | ||
728 | if (priv->nvm_device_type == -ENOENT) | ||
729 | return -ENOENT; | ||
730 | /* allocate eeprom */ | ||
731 | sz = priv->cfg->base_params->eeprom_size; | ||
732 | IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); | ||
733 | priv->eeprom = kzalloc(sz, GFP_KERNEL); | ||
734 | if (!priv->eeprom) { | ||
735 | ret = -ENOMEM; | ||
736 | goto alloc_err; | ||
737 | } | ||
738 | e = (__le16 *)priv->eeprom; | ||
739 | |||
740 | ret = iwl_eeprom_verify_signature(priv); | ||
741 | if (ret < 0) { | ||
742 | IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); | ||
743 | ret = -ENOENT; | ||
744 | goto err; | ||
745 | } | ||
746 | |||
747 | /* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||
748 | ret = iwl_eeprom_acquire_semaphore(priv->trans); | ||
749 | if (ret < 0) { | ||
750 | IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | ||
751 | ret = -ENOENT; | ||
752 | goto err; | ||
753 | } | ||
754 | |||
755 | if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { | ||
756 | |||
757 | ret = iwl_init_otp_access(priv->trans); | ||
758 | if (ret) { | ||
759 | IWL_ERR(priv, "Failed to initialize OTP access.\n"); | ||
760 | ret = -ENOENT; | ||
761 | goto done; | ||
762 | } | ||
763 | iwl_write32(priv->trans, CSR_EEPROM_GP, | ||
764 | iwl_read32(priv->trans, CSR_EEPROM_GP) & | ||
765 | ~CSR_EEPROM_GP_IF_OWNER_MSK); | ||
766 | |||
767 | iwl_set_bit(priv->trans, CSR_OTP_GP_REG, | ||
768 | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | | ||
769 | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); | ||
770 | /* traversing the linked list if no shadow ram supported */ | ||
771 | if (!priv->cfg->base_params->shadow_ram_support) { | ||
772 | if (iwl_find_otp_image(priv->trans, &validblockaddr)) { | ||
773 | ret = -ENOENT; | ||
774 | goto done; | ||
775 | } | ||
776 | } | ||
777 | for (addr = validblockaddr; addr < validblockaddr + sz; | ||
778 | addr += sizeof(u16)) { | ||
779 | __le16 eeprom_data; | ||
780 | |||
781 | ret = iwl_read_otp_word(priv->trans, addr, | ||
782 | &eeprom_data); | ||
783 | if (ret) | ||
784 | goto done; | ||
785 | e[cache_addr / 2] = eeprom_data; | ||
786 | cache_addr += sizeof(u16); | ||
787 | } | ||
788 | } else { | ||
789 | /* eeprom is an array of 16bit values */ | ||
790 | for (addr = 0; addr < sz; addr += sizeof(u16)) { | ||
791 | u32 r; | ||
792 | |||
793 | iwl_write32(priv->trans, CSR_EEPROM_REG, | ||
794 | CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); | ||
795 | |||
796 | ret = iwl_poll_bit(priv->trans, CSR_EEPROM_REG, | ||
797 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
798 | CSR_EEPROM_REG_READ_VALID_MSK, | ||
799 | IWL_EEPROM_ACCESS_TIMEOUT); | ||
800 | if (ret < 0) { | ||
801 | IWL_ERR(priv, | ||
802 | "Time out reading EEPROM[%d]\n", addr); | ||
803 | goto done; | ||
804 | } | ||
805 | r = iwl_read32(priv->trans, CSR_EEPROM_REG); | ||
806 | e[addr / 2] = cpu_to_le16(r >> 16); | ||
807 | } | ||
808 | } | ||
809 | |||
810 | IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", | ||
811 | (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) | ||
812 | ? "OTP" : "EEPROM", | ||
813 | iwl_eeprom_query16(priv, EEPROM_VERSION)); | ||
814 | |||
815 | ret = 0; | ||
816 | done: | ||
817 | iwl_eeprom_release_semaphore(priv->trans); | ||
818 | |||
819 | err: | ||
820 | if (ret) | ||
821 | iwl_eeprom_free(priv); | ||
822 | alloc_err: | ||
823 | return ret; | ||
824 | } | ||
825 | |||
826 | void iwl_eeprom_free(struct iwl_priv *priv) | ||
827 | { | ||
828 | kfree(priv->eeprom); | ||
829 | priv->eeprom = NULL; | ||
830 | } | ||
831 | |||
832 | static void iwl_init_band_reference(struct iwl_priv *priv, | ||
833 | int eep_band, int *eeprom_ch_count, | ||
834 | const struct iwl_eeprom_channel **eeprom_ch_info, | ||
835 | const u8 **eeprom_ch_index) | ||
836 | { | ||
837 | u32 offset = priv->lib-> | ||
838 | eeprom_ops.regulatory_bands[eep_band - 1]; | ||
839 | switch (eep_band) { | ||
840 | case 1: /* 2.4GHz band */ | ||
841 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); | ||
842 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
843 | iwl_eeprom_query_addr(priv, offset); | ||
844 | *eeprom_ch_index = iwl_eeprom_band_1; | ||
845 | break; | ||
846 | case 2: /* 4.9GHz band */ | ||
847 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); | ||
848 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
849 | iwl_eeprom_query_addr(priv, offset); | ||
850 | *eeprom_ch_index = iwl_eeprom_band_2; | ||
851 | break; | ||
852 | case 3: /* 5.2GHz band */ | ||
853 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); | ||
854 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
855 | iwl_eeprom_query_addr(priv, offset); | ||
856 | *eeprom_ch_index = iwl_eeprom_band_3; | ||
857 | break; | ||
858 | case 4: /* 5.5GHz band */ | ||
859 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); | ||
860 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
861 | iwl_eeprom_query_addr(priv, offset); | ||
862 | *eeprom_ch_index = iwl_eeprom_band_4; | ||
863 | break; | ||
864 | case 5: /* 5.7GHz band */ | ||
865 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); | ||
866 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
867 | iwl_eeprom_query_addr(priv, offset); | ||
868 | *eeprom_ch_index = iwl_eeprom_band_5; | ||
869 | break; | ||
870 | case 6: /* 2.4GHz ht40 channels */ | ||
871 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); | ||
872 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
873 | iwl_eeprom_query_addr(priv, offset); | ||
874 | *eeprom_ch_index = iwl_eeprom_band_6; | ||
875 | break; | ||
876 | case 7: /* 5 GHz ht40 channels */ | ||
877 | *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); | ||
878 | *eeprom_ch_info = (struct iwl_eeprom_channel *) | ||
879 | iwl_eeprom_query_addr(priv, offset); | ||
880 | *eeprom_ch_index = iwl_eeprom_band_7; | ||
881 | break; | ||
882 | default: | ||
883 | BUG(); | ||
884 | return; | ||
885 | } | ||
886 | } | ||
887 | |||
888 | #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ | ||
889 | ? # x " " : "") | ||
890 | /** | ||
891 | * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. | ||
892 | * | ||
893 | * Does not set up a command, or touch hardware. | ||
894 | */ | ||
895 | static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, | ||
896 | enum ieee80211_band band, u16 channel, | ||
897 | const struct iwl_eeprom_channel *eeprom_ch, | ||
898 | u8 clear_ht40_extension_channel) | ||
899 | { | ||
900 | struct iwl_channel_info *ch_info; | ||
901 | |||
902 | ch_info = (struct iwl_channel_info *) | ||
903 | iwl_get_channel_info(priv, band, channel); | ||
904 | |||
905 | if (!is_channel_valid(ch_info)) | ||
906 | return -1; | ||
907 | |||
908 | IWL_DEBUG_EEPROM(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" | ||
909 | " Ad-Hoc %ssupported\n", | ||
910 | ch_info->channel, | ||
911 | is_channel_a_band(ch_info) ? | ||
912 | "5.2" : "2.4", | ||
913 | CHECK_AND_PRINT(IBSS), | ||
914 | CHECK_AND_PRINT(ACTIVE), | ||
915 | CHECK_AND_PRINT(RADAR), | ||
916 | CHECK_AND_PRINT(WIDE), | ||
917 | CHECK_AND_PRINT(DFS), | ||
918 | eeprom_ch->flags, | ||
919 | eeprom_ch->max_power_avg, | ||
920 | ((eeprom_ch->flags & EEPROM_CHANNEL_IBSS) | ||
921 | && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ? | ||
922 | "" : "not "); | ||
923 | |||
924 | ch_info->ht40_eeprom = *eeprom_ch; | ||
925 | ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg; | ||
926 | ch_info->ht40_flags = eeprom_ch->flags; | ||
927 | if (eeprom_ch->flags & EEPROM_CHANNEL_VALID) | ||
928 | ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel; | ||
929 | |||
930 | return 0; | ||
931 | } | ||
932 | |||
933 | #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ | ||
934 | ? # x " " : "") | ||
935 | |||
936 | /** | ||
937 | * iwl_init_channel_map - Set up driver's info for all possible channels | ||
938 | */ | ||
939 | int iwl_init_channel_map(struct iwl_priv *priv) | ||
940 | { | ||
941 | int eeprom_ch_count = 0; | ||
942 | const u8 *eeprom_ch_index = NULL; | ||
943 | const struct iwl_eeprom_channel *eeprom_ch_info = NULL; | ||
944 | int band, ch; | ||
945 | struct iwl_channel_info *ch_info; | ||
946 | |||
947 | if (priv->channel_count) { | ||
948 | IWL_DEBUG_EEPROM(priv, "Channel map already initialized.\n"); | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | IWL_DEBUG_EEPROM(priv, "Initializing regulatory info from EEPROM\n"); | ||
953 | |||
954 | priv->channel_count = | ||
955 | ARRAY_SIZE(iwl_eeprom_band_1) + | ||
956 | ARRAY_SIZE(iwl_eeprom_band_2) + | ||
957 | ARRAY_SIZE(iwl_eeprom_band_3) + | ||
958 | ARRAY_SIZE(iwl_eeprom_band_4) + | ||
959 | ARRAY_SIZE(iwl_eeprom_band_5); | ||
960 | |||
961 | IWL_DEBUG_EEPROM(priv, "Parsing data for %d channels.\n", | ||
962 | priv->channel_count); | ||
963 | |||
964 | priv->channel_info = kcalloc(priv->channel_count, | ||
965 | sizeof(struct iwl_channel_info), | ||
966 | GFP_KERNEL); | ||
967 | if (!priv->channel_info) { | ||
968 | IWL_ERR(priv, "Could not allocate channel_info\n"); | ||
969 | priv->channel_count = 0; | ||
970 | return -ENOMEM; | ||
971 | } | ||
972 | |||
973 | ch_info = priv->channel_info; | ||
974 | |||
975 | /* Loop through the 5 EEPROM bands adding them in order to the | ||
976 | * channel map we maintain (that contains additional information than | ||
977 | * what just in the EEPROM) */ | ||
978 | for (band = 1; band <= 5; band++) { | ||
979 | |||
980 | iwl_init_band_reference(priv, band, &eeprom_ch_count, | ||
981 | &eeprom_ch_info, &eeprom_ch_index); | ||
982 | |||
983 | /* Loop through each band adding each of the channels */ | ||
984 | for (ch = 0; ch < eeprom_ch_count; ch++) { | ||
985 | ch_info->channel = eeprom_ch_index[ch]; | ||
986 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : | ||
987 | IEEE80211_BAND_5GHZ; | ||
988 | |||
989 | /* permanently store EEPROM's channel regulatory flags | ||
990 | * and max power in channel info database. */ | ||
991 | ch_info->eeprom = eeprom_ch_info[ch]; | ||
992 | |||
993 | /* Copy the run-time flags so they are there even on | ||
994 | * invalid channels */ | ||
995 | ch_info->flags = eeprom_ch_info[ch].flags; | ||
996 | /* First write that ht40 is not enabled, and then enable | ||
997 | * one by one */ | ||
998 | ch_info->ht40_extension_channel = | ||
999 | IEEE80211_CHAN_NO_HT40; | ||
1000 | |||
1001 | if (!(is_channel_valid(ch_info))) { | ||
1002 | IWL_DEBUG_EEPROM(priv, | ||
1003 | "Ch. %d Flags %x [%sGHz] - " | ||
1004 | "No traffic\n", | ||
1005 | ch_info->channel, | ||
1006 | ch_info->flags, | ||
1007 | is_channel_a_band(ch_info) ? | ||
1008 | "5.2" : "2.4"); | ||
1009 | ch_info++; | ||
1010 | continue; | ||
1011 | } | ||
1012 | |||
1013 | /* Initialize regulatory-based run-time data */ | ||
1014 | ch_info->max_power_avg = ch_info->curr_txpow = | ||
1015 | eeprom_ch_info[ch].max_power_avg; | ||
1016 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | ||
1017 | ch_info->min_power = 0; | ||
1018 | |||
1019 | IWL_DEBUG_EEPROM(priv, "Ch. %d [%sGHz] " | ||
1020 | "%s%s%s%s%s%s(0x%02x %ddBm):" | ||
1021 | " Ad-Hoc %ssupported\n", | ||
1022 | ch_info->channel, | ||
1023 | is_channel_a_band(ch_info) ? | ||
1024 | "5.2" : "2.4", | ||
1025 | CHECK_AND_PRINT_I(VALID), | ||
1026 | CHECK_AND_PRINT_I(IBSS), | ||
1027 | CHECK_AND_PRINT_I(ACTIVE), | ||
1028 | CHECK_AND_PRINT_I(RADAR), | ||
1029 | CHECK_AND_PRINT_I(WIDE), | ||
1030 | CHECK_AND_PRINT_I(DFS), | ||
1031 | eeprom_ch_info[ch].flags, | ||
1032 | eeprom_ch_info[ch].max_power_avg, | ||
1033 | ((eeprom_ch_info[ch]. | ||
1034 | flags & EEPROM_CHANNEL_IBSS) | ||
1035 | && !(eeprom_ch_info[ch]. | ||
1036 | flags & EEPROM_CHANNEL_RADAR)) | ||
1037 | ? "" : "not "); | ||
1038 | |||
1039 | ch_info++; | ||
1040 | } | ||
1041 | } | ||
1042 | |||
1043 | /* Check if we do have HT40 channels */ | ||
1044 | if (priv->lib->eeprom_ops.regulatory_bands[5] == | ||
1045 | EEPROM_REGULATORY_BAND_NO_HT40 && | ||
1046 | priv->lib->eeprom_ops.regulatory_bands[6] == | ||
1047 | EEPROM_REGULATORY_BAND_NO_HT40) | ||
1048 | return 0; | ||
1049 | |||
1050 | /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ | ||
1051 | for (band = 6; band <= 7; band++) { | ||
1052 | enum ieee80211_band ieeeband; | ||
1053 | |||
1054 | iwl_init_band_reference(priv, band, &eeprom_ch_count, | ||
1055 | &eeprom_ch_info, &eeprom_ch_index); | ||
1056 | |||
1057 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | ||
1058 | ieeeband = | ||
1059 | (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1060 | |||
1061 | /* Loop through each band adding each of the channels */ | ||
1062 | for (ch = 0; ch < eeprom_ch_count; ch++) { | ||
1063 | /* Set up driver's info for lower half */ | ||
1064 | iwl_mod_ht40_chan_info(priv, ieeeband, | ||
1065 | eeprom_ch_index[ch], | ||
1066 | &eeprom_ch_info[ch], | ||
1067 | IEEE80211_CHAN_NO_HT40PLUS); | ||
1068 | |||
1069 | /* Set up driver's info for upper half */ | ||
1070 | iwl_mod_ht40_chan_info(priv, ieeeband, | ||
1071 | eeprom_ch_index[ch] + 4, | ||
1072 | &eeprom_ch_info[ch], | ||
1073 | IEEE80211_CHAN_NO_HT40MINUS); | ||
1074 | } | ||
1075 | } | ||
1076 | |||
1077 | /* for newer device (6000 series and up) | ||
1078 | * EEPROM contain enhanced tx power information | ||
1079 | * driver need to process addition information | ||
1080 | * to determine the max channel tx power limits | ||
1081 | */ | ||
1082 | if (priv->lib->eeprom_ops.enhanced_txpower) | ||
1083 | iwl_eeprom_enhanced_txpower(priv); | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | /* | ||
1089 | * iwl_free_channel_map - undo allocations in iwl_init_channel_map | ||
1090 | */ | ||
1091 | void iwl_free_channel_map(struct iwl_priv *priv) | ||
1092 | { | ||
1093 | kfree(priv->channel_info); | ||
1094 | priv->channel_count = 0; | ||
1095 | } | ||
1096 | |||
1097 | /** | ||
1098 | * iwl_get_channel_info - Find driver's private channel info | ||
1099 | * | ||
1100 | * Based on band and channel number. | ||
1101 | */ | ||
1102 | const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, | ||
1103 | enum ieee80211_band band, u16 channel) | ||
1104 | { | ||
1105 | int i; | ||
1106 | |||
1107 | switch (band) { | ||
1108 | case IEEE80211_BAND_5GHZ: | ||
1109 | for (i = 14; i < priv->channel_count; i++) { | ||
1110 | if (priv->channel_info[i].channel == channel) | ||
1111 | return &priv->channel_info[i]; | ||
1112 | } | ||
1113 | break; | ||
1114 | case IEEE80211_BAND_2GHZ: | ||
1115 | if (channel >= 1 && channel <= 14) | ||
1116 | return &priv->channel_info[channel - 1]; | ||
1117 | break; | ||
1118 | default: | ||
1119 | BUG(); | ||
1120 | } | ||
1121 | |||
1122 | return NULL; | ||
1123 | } | ||
1124 | |||
1125 | void iwl_rf_config(struct iwl_priv *priv) | ||
1126 | { | ||
1127 | u16 radio_cfg; | ||
1128 | |||
1129 | radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG); | ||
1130 | |||
1131 | /* write radio config values to register */ | ||
1132 | if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { | ||
1133 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
1134 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | | ||
1135 | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | | ||
1136 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
1137 | IWL_INFO(priv, "Radio type=0x%x-0x%x-0x%x\n", | ||
1138 | EEPROM_RF_CFG_TYPE_MSK(radio_cfg), | ||
1139 | EEPROM_RF_CFG_STEP_MSK(radio_cfg), | ||
1140 | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); | ||
1141 | } else | ||
1142 | WARN_ON(1); | ||
1143 | |||
1144 | /* set CSR_HW_CONFIG_REG for uCode use */ | ||
1145 | iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG, | ||
1146 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | ||
1147 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
1148 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h deleted file mode 100644 index 64bfd947caeb..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called LICENSE.GPL. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | *****************************************************************************/ | ||
62 | |||
63 | #ifndef __iwl_eeprom_h__ | ||
64 | #define __iwl_eeprom_h__ | ||
65 | |||
66 | #include <net/mac80211.h> | ||
67 | |||
68 | struct iwl_priv; | ||
69 | |||
70 | /* | ||
71 | * EEPROM access time values: | ||
72 | * | ||
73 | * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG. | ||
74 | * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). | ||
75 | * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. | ||
76 | * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. | ||
77 | */ | ||
78 | #define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ | ||
79 | |||
80 | #define IWL_EEPROM_SEM_TIMEOUT 10 /* microseconds */ | ||
81 | #define IWL_EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | ||
82 | |||
83 | |||
84 | /* | ||
85 | * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. | ||
86 | * | ||
87 | * IBSS and/or AP operation is allowed *only* on those channels with | ||
88 | * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because | ||
89 | * RADAR detection is not supported by the 4965 driver, but is a | ||
90 | * requirement for establishing a new network for legal operation on channels | ||
91 | * requiring RADAR detection or restricting ACTIVE scanning. | ||
92 | * | ||
93 | * NOTE: "WIDE" flag does not indicate anything about "HT40" 40 MHz channels. | ||
94 | * It only indicates that 20 MHz channel use is supported; HT40 channel | ||
95 | * usage is indicated by a separate set of regulatory flags for each | ||
96 | * HT40 channel pair. | ||
97 | * | ||
98 | * NOTE: Using a channel inappropriately will result in a uCode error! | ||
99 | */ | ||
100 | #define IWL_NUM_TX_CALIB_GROUPS 5 | ||
101 | enum { | ||
102 | EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ | ||
103 | EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ | ||
104 | /* Bit 2 Reserved */ | ||
105 | EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ | ||
106 | EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ | ||
107 | EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ | ||
108 | /* Bit 6 Reserved (was Narrow Channel) */ | ||
109 | EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ | ||
110 | }; | ||
111 | |||
112 | /* SKU Capabilities */ | ||
113 | #define EEPROM_SKU_CAP_BAND_24GHZ (1 << 4) | ||
114 | #define EEPROM_SKU_CAP_BAND_52GHZ (1 << 5) | ||
115 | #define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) | ||
116 | #define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) | ||
117 | #define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) | ||
118 | |||
119 | /* *regulatory* channel data format in eeprom, one for each channel. | ||
120 | * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ | ||
121 | struct iwl_eeprom_channel { | ||
122 | u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ | ||
123 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ | ||
124 | } __packed; | ||
125 | |||
126 | enum iwl_eeprom_enhanced_txpwr_flags { | ||
127 | IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), | ||
128 | IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), | ||
129 | IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), | ||
130 | IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), | ||
131 | IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), | ||
132 | IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), | ||
133 | IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), | ||
134 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), | ||
135 | }; | ||
136 | |||
137 | /** | ||
138 | * iwl_eeprom_enhanced_txpwr structure | ||
139 | * This structure presents the enhanced regulatory tx power limit layout | ||
140 | * in eeprom image | ||
141 | * Enhanced regulatory tx power portion of eeprom image can be broken down | ||
142 | * into individual structures; each one is 8 bytes in size and contain the | ||
143 | * following information | ||
144 | * @flags: entry flags | ||
145 | * @channel: channel number | ||
146 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | ||
147 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | ||
148 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | ||
149 | * @delta_20_in_40: 20-in-40 deltas (hi/lo) | ||
150 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | ||
151 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | ||
152 | * | ||
153 | */ | ||
154 | struct iwl_eeprom_enhanced_txpwr { | ||
155 | u8 flags; | ||
156 | u8 channel; | ||
157 | s8 chain_a_max; | ||
158 | s8 chain_b_max; | ||
159 | s8 chain_c_max; | ||
160 | u8 delta_20_in_40; | ||
161 | s8 mimo2_max; | ||
162 | s8 mimo3_max; | ||
163 | } __packed; | ||
164 | |||
165 | /* calibration */ | ||
166 | struct iwl_eeprom_calib_hdr { | ||
167 | u8 version; | ||
168 | u8 pa_type; | ||
169 | __le16 voltage; | ||
170 | } __packed; | ||
171 | |||
172 | #define EEPROM_CALIB_ALL (INDIRECT_ADDRESS | INDIRECT_CALIBRATION) | ||
173 | #define EEPROM_XTAL ((2*0x128) | EEPROM_CALIB_ALL) | ||
174 | |||
175 | /* temperature */ | ||
176 | #define EEPROM_KELVIN_TEMPERATURE ((2*0x12A) | EEPROM_CALIB_ALL) | ||
177 | #define EEPROM_RAW_TEMPERATURE ((2*0x12B) | EEPROM_CALIB_ALL) | ||
178 | |||
179 | |||
180 | /* agn links */ | ||
181 | #define EEPROM_LINK_HOST (2*0x64) | ||
182 | #define EEPROM_LINK_GENERAL (2*0x65) | ||
183 | #define EEPROM_LINK_REGULATORY (2*0x66) | ||
184 | #define EEPROM_LINK_CALIBRATION (2*0x67) | ||
185 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) | ||
186 | #define EEPROM_LINK_OTHERS (2*0x69) | ||
187 | #define EEPROM_LINK_TXP_LIMIT (2*0x6a) | ||
188 | #define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) | ||
189 | |||
190 | /* agn regulatory - indirect access */ | ||
191 | #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ | ||
192 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 28 bytes */ | ||
193 | #define EEPROM_REG_BAND_2_CHANNELS ((0x26)\ | ||
194 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 26 bytes */ | ||
195 | #define EEPROM_REG_BAND_3_CHANNELS ((0x42)\ | ||
196 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ | ||
197 | #define EEPROM_REG_BAND_4_CHANNELS ((0x5C)\ | ||
198 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ | ||
199 | #define EEPROM_REG_BAND_5_CHANNELS ((0x74)\ | ||
200 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 12 bytes */ | ||
201 | #define EEPROM_REG_BAND_24_HT40_CHANNELS ((0x82)\ | ||
202 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | ||
203 | #define EEPROM_REG_BAND_52_HT40_CHANNELS ((0x92)\ | ||
204 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 22 bytes */ | ||
205 | |||
206 | /* 6000 regulatory - indirect access */ | ||
207 | #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ | ||
208 | | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | ||
209 | /* 2.4 GHz */ | ||
210 | extern const u8 iwl_eeprom_band_1[14]; | ||
211 | |||
212 | #define ADDRESS_MSK 0x0000FFFF | ||
213 | #define INDIRECT_TYPE_MSK 0x000F0000 | ||
214 | #define INDIRECT_HOST 0x00010000 | ||
215 | #define INDIRECT_GENERAL 0x00020000 | ||
216 | #define INDIRECT_REGULATORY 0x00030000 | ||
217 | #define INDIRECT_CALIBRATION 0x00040000 | ||
218 | #define INDIRECT_PROCESS_ADJST 0x00050000 | ||
219 | #define INDIRECT_OTHERS 0x00060000 | ||
220 | #define INDIRECT_TXP_LIMIT 0x00070000 | ||
221 | #define INDIRECT_TXP_LIMIT_SIZE 0x00080000 | ||
222 | #define INDIRECT_ADDRESS 0x00100000 | ||
223 | |||
224 | /* General */ | ||
225 | #define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ | ||
226 | #define EEPROM_SUBSYSTEM_ID (2*0x0A) /* 2 bytes */ | ||
227 | #define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ | ||
228 | #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ | ||
229 | #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ | ||
230 | #define EEPROM_VERSION (2*0x44) /* 2 bytes */ | ||
231 | #define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ | ||
232 | #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ | ||
233 | #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ | ||
234 | #define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */ | ||
235 | |||
236 | /* The following masks are to be applied on EEPROM_RADIO_CONFIG */ | ||
237 | #define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */ | ||
238 | #define EEPROM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */ | ||
239 | #define EEPROM_RF_CFG_DASH_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */ | ||
240 | #define EEPROM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */ | ||
241 | #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */ | ||
242 | #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */ | ||
243 | |||
244 | #define EEPROM_RF_CONFIG_TYPE_MAX 0x3 | ||
245 | |||
246 | #define EEPROM_REGULATORY_BAND_NO_HT40 (0) | ||
247 | |||
248 | struct iwl_eeprom_ops { | ||
249 | const u32 regulatory_bands[7]; | ||
250 | bool enhanced_txpower; | ||
251 | }; | ||
252 | |||
253 | |||
254 | int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); | ||
255 | void iwl_eeprom_free(struct iwl_priv *priv); | ||
256 | int iwl_eeprom_check_version(struct iwl_priv *priv); | ||
257 | int iwl_eeprom_init_hw_params(struct iwl_priv *priv); | ||
258 | u16 iwl_eeprom_calib_version(struct iwl_priv *priv); | ||
259 | const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset); | ||
260 | u16 iwl_eeprom_query16(struct iwl_priv *priv, size_t offset); | ||
261 | void iwl_eeprom_get_mac(struct iwl_priv *priv, u8 *mac); | ||
262 | int iwl_init_channel_map(struct iwl_priv *priv); | ||
263 | void iwl_free_channel_map(struct iwl_priv *priv); | ||
264 | const struct iwl_channel_info *iwl_get_channel_info( | ||
265 | const struct iwl_priv *priv, | ||
266 | enum ieee80211_band band, u16 channel); | ||
267 | void iwl_rf_config(struct iwl_priv *priv); | ||
268 | |||
269 | #endif /* __iwl_eeprom_h__ */ | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 081dd34d2387..5f2df70b73c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -27,6 +27,7 @@ | |||
27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/export.h> | ||
30 | 31 | ||
31 | #include "iwl-io.h" | 32 | #include "iwl-io.h" |
32 | #include"iwl-csr.h" | 33 | #include"iwl-csr.h" |
@@ -52,6 +53,7 @@ void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) | |||
52 | __iwl_set_bit(trans, reg, mask); | 53 | __iwl_set_bit(trans, reg, mask); |
53 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 54 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
54 | } | 55 | } |
56 | EXPORT_SYMBOL_GPL(iwl_set_bit); | ||
55 | 57 | ||
56 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) | 58 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) |
57 | { | 59 | { |
@@ -61,6 +63,25 @@ void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) | |||
61 | __iwl_clear_bit(trans, reg, mask); | 63 | __iwl_clear_bit(trans, reg, mask); |
62 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 64 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
63 | } | 65 | } |
66 | EXPORT_SYMBOL_GPL(iwl_clear_bit); | ||
67 | |||
68 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value) | ||
69 | { | ||
70 | unsigned long flags; | ||
71 | u32 v; | ||
72 | |||
73 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
74 | WARN_ON_ONCE(value & ~mask); | ||
75 | #endif | ||
76 | |||
77 | spin_lock_irqsave(&trans->reg_lock, flags); | ||
78 | v = iwl_read32(trans, reg); | ||
79 | v &= ~mask; | ||
80 | v |= value; | ||
81 | iwl_write32(trans, reg, v); | ||
82 | spin_unlock_irqrestore(&trans->reg_lock, flags); | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(iwl_set_bits_mask); | ||
64 | 85 | ||
65 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | 86 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
66 | u32 bits, u32 mask, int timeout) | 87 | u32 bits, u32 mask, int timeout) |
@@ -76,6 +97,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | |||
76 | 97 | ||
77 | return -ETIMEDOUT; | 98 | return -ETIMEDOUT; |
78 | } | 99 | } |
100 | EXPORT_SYMBOL_GPL(iwl_poll_bit); | ||
79 | 101 | ||
80 | int iwl_grab_nic_access_silent(struct iwl_trans *trans) | 102 | int iwl_grab_nic_access_silent(struct iwl_trans *trans) |
81 | { | 103 | { |
@@ -117,6 +139,7 @@ int iwl_grab_nic_access_silent(struct iwl_trans *trans) | |||
117 | 139 | ||
118 | return 0; | 140 | return 0; |
119 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access_silent); | ||
120 | 143 | ||
121 | bool iwl_grab_nic_access(struct iwl_trans *trans) | 144 | bool iwl_grab_nic_access(struct iwl_trans *trans) |
122 | { | 145 | { |
@@ -130,6 +153,7 @@ bool iwl_grab_nic_access(struct iwl_trans *trans) | |||
130 | 153 | ||
131 | return true; | 154 | return true; |
132 | } | 155 | } |
156 | EXPORT_SYMBOL_GPL(iwl_grab_nic_access); | ||
133 | 157 | ||
134 | void iwl_release_nic_access(struct iwl_trans *trans) | 158 | void iwl_release_nic_access(struct iwl_trans *trans) |
135 | { | 159 | { |
@@ -144,6 +168,7 @@ void iwl_release_nic_access(struct iwl_trans *trans) | |||
144 | */ | 168 | */ |
145 | mmiowb(); | 169 | mmiowb(); |
146 | } | 170 | } |
171 | EXPORT_SYMBOL_GPL(iwl_release_nic_access); | ||
147 | 172 | ||
148 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | 173 | u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) |
149 | { | 174 | { |
@@ -158,6 +183,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) | |||
158 | 183 | ||
159 | return value; | 184 | return value; |
160 | } | 185 | } |
186 | EXPORT_SYMBOL_GPL(iwl_read_direct32); | ||
161 | 187 | ||
162 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | 188 | void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) |
163 | { | 189 | { |
@@ -170,6 +196,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) | |||
170 | } | 196 | } |
171 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 197 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
172 | } | 198 | } |
199 | EXPORT_SYMBOL_GPL(iwl_write_direct32); | ||
173 | 200 | ||
174 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 201 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
175 | int timeout) | 202 | int timeout) |
@@ -185,6 +212,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | |||
185 | 212 | ||
186 | return -ETIMEDOUT; | 213 | return -ETIMEDOUT; |
187 | } | 214 | } |
215 | EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); | ||
188 | 216 | ||
189 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) | 217 | static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) |
190 | { | 218 | { |
@@ -211,6 +239,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) | |||
211 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 239 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
212 | return val; | 240 | return val; |
213 | } | 241 | } |
242 | EXPORT_SYMBOL_GPL(iwl_read_prph); | ||
214 | 243 | ||
215 | void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | 244 | void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) |
216 | { | 245 | { |
@@ -223,6 +252,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) | |||
223 | } | 252 | } |
224 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 253 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
225 | } | 254 | } |
255 | EXPORT_SYMBOL_GPL(iwl_write_prph); | ||
226 | 256 | ||
227 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | 257 | void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) |
228 | { | 258 | { |
@@ -236,6 +266,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
236 | } | 266 | } |
237 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 267 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
238 | } | 268 | } |
269 | EXPORT_SYMBOL_GPL(iwl_set_bits_prph); | ||
239 | 270 | ||
240 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, | 271 | void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, |
241 | u32 bits, u32 mask) | 272 | u32 bits, u32 mask) |
@@ -250,6 +281,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, | |||
250 | } | 281 | } |
251 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 282 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
252 | } | 283 | } |
284 | EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); | ||
253 | 285 | ||
254 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | 286 | void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) |
255 | { | 287 | { |
@@ -264,6 +296,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) | |||
264 | } | 296 | } |
265 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 297 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
266 | } | 298 | } |
299 | EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); | ||
267 | 300 | ||
268 | void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, | 301 | void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, |
269 | void *buf, int words) | 302 | void *buf, int words) |
@@ -281,6 +314,7 @@ void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
281 | } | 314 | } |
282 | spin_unlock_irqrestore(&trans->reg_lock, flags); | 315 | spin_unlock_irqrestore(&trans->reg_lock, flags); |
283 | } | 316 | } |
317 | EXPORT_SYMBOL_GPL(_iwl_read_targ_mem_words); | ||
284 | 318 | ||
285 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) | 319 | u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) |
286 | { | 320 | { |
@@ -290,6 +324,7 @@ u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) | |||
290 | 324 | ||
291 | return value; | 325 | return value; |
292 | } | 326 | } |
327 | EXPORT_SYMBOL_GPL(iwl_read_targ_mem); | ||
293 | 328 | ||
294 | int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, | 329 | int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, |
295 | void *buf, int words) | 330 | void *buf, int words) |
@@ -310,8 +345,10 @@ int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, | |||
310 | 345 | ||
311 | return result; | 346 | return result; |
312 | } | 347 | } |
348 | EXPORT_SYMBOL_GPL(_iwl_write_targ_mem_words); | ||
313 | 349 | ||
314 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) | 350 | int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) |
315 | { | 351 | { |
316 | return _iwl_write_targ_mem_words(trans, addr, &val, 1); | 352 | return _iwl_write_targ_mem_words(trans, addr, &val, 1); |
317 | } | 353 | } |
354 | EXPORT_SYMBOL_GPL(iwl_write_targ_mem); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index abb3250164ba..4a9a45f771ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h | |||
@@ -54,6 +54,8 @@ static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) | |||
54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 54 | void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); | 55 | void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); |
56 | 56 | ||
57 | void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value); | ||
58 | |||
57 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, | 59 | int iwl_poll_bit(struct iwl_trans *trans, u32 addr, |
58 | u32 bits, u32 mask, int timeout); | 60 | u32 bits, u32 mask, int timeout); |
59 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, | 61 | int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 0066b899fe5c..5cfed29b1b18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c | |||
@@ -61,6 +61,7 @@ | |||
61 | * | 61 | * |
62 | *****************************************************************************/ | 62 | *****************************************************************************/ |
63 | #include <linux/sched.h> | 63 | #include <linux/sched.h> |
64 | #include <linux/export.h> | ||
64 | 65 | ||
65 | #include "iwl-notif-wait.h" | 66 | #include "iwl-notif-wait.h" |
66 | 67 | ||
@@ -71,6 +72,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) | |||
71 | INIT_LIST_HEAD(¬if_wait->notif_waits); | 72 | INIT_LIST_HEAD(¬if_wait->notif_waits); |
72 | init_waitqueue_head(¬if_wait->notif_waitq); | 73 | init_waitqueue_head(¬if_wait->notif_waitq); |
73 | } | 74 | } |
75 | EXPORT_SYMBOL_GPL(iwl_notification_wait_init); | ||
74 | 76 | ||
75 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | 77 | void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, |
76 | struct iwl_rx_packet *pkt) | 78 | struct iwl_rx_packet *pkt) |
@@ -115,6 +117,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, | |||
115 | if (triggered) | 117 | if (triggered) |
116 | wake_up_all(¬if_wait->notif_waitq); | 118 | wake_up_all(¬if_wait->notif_waitq); |
117 | } | 119 | } |
120 | EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); | ||
118 | 121 | ||
119 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | 122 | void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) |
120 | { | 123 | { |
@@ -128,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) | |||
128 | 131 | ||
129 | wake_up_all(¬if_wait->notif_waitq); | 132 | wake_up_all(¬if_wait->notif_waitq); |
130 | } | 133 | } |
131 | 134 | EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); | |
132 | 135 | ||
133 | void | 136 | void |
134 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | 137 | iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, |
@@ -152,6 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, | |||
152 | list_add(&wait_entry->list, ¬if_wait->notif_waits); | 155 | list_add(&wait_entry->list, ¬if_wait->notif_waits); |
153 | spin_unlock_bh(¬if_wait->notif_wait_lock); | 156 | spin_unlock_bh(¬if_wait->notif_wait_lock); |
154 | } | 157 | } |
158 | EXPORT_SYMBOL_GPL(iwl_init_notification_wait); | ||
155 | 159 | ||
156 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | 160 | int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, |
157 | struct iwl_notification_wait *wait_entry, | 161 | struct iwl_notification_wait *wait_entry, |
@@ -175,6 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, | |||
175 | return -ETIMEDOUT; | 179 | return -ETIMEDOUT; |
176 | return 0; | 180 | return 0; |
177 | } | 181 | } |
182 | EXPORT_SYMBOL_GPL(iwl_wait_notification); | ||
178 | 183 | ||
179 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | 184 | void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, |
180 | struct iwl_notification_wait *wait_entry) | 185 | struct iwl_notification_wait *wait_entry) |
@@ -183,3 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, | |||
183 | list_del(&wait_entry->list); | 188 | list_del(&wait_entry->list); |
184 | spin_unlock_bh(¬if_wait->notif_wait_lock); | 189 | spin_unlock_bh(¬if_wait->notif_wait_lock); |
185 | } | 190 | } |
191 | EXPORT_SYMBOL_GPL(iwl_remove_notification); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 4ef742b28e08..cd9ef114d3a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h | |||
@@ -145,6 +145,9 @@ struct iwl_op_mode_ops { | |||
145 | void (*wimax_active)(struct iwl_op_mode *op_mode); | 145 | void (*wimax_active)(struct iwl_op_mode *op_mode); |
146 | }; | 146 | }; |
147 | 147 | ||
148 | int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops); | ||
149 | void iwl_opmode_deregister(const char *name); | ||
150 | |||
148 | /** | 151 | /** |
149 | * struct iwl_op_mode - operational mode | 152 | * struct iwl_op_mode - operational mode |
150 | * | 153 | * |
@@ -218,9 +221,4 @@ static inline void iwl_op_mode_wimax_active(struct iwl_op_mode *op_mode) | |||
218 | op_mode->ops->wimax_active(op_mode); | 221 | op_mode->ops->wimax_active(op_mode); |
219 | } | 222 | } |
220 | 223 | ||
221 | /***************************************************** | ||
222 | * Op mode layers implementations | ||
223 | ******************************************************/ | ||
224 | extern const struct iwl_op_mode_ops iwl_dvm_ops; | ||
225 | |||
226 | #endif /* __iwl_op_mode_h__ */ | 224 | #endif /* __iwl_op_mode_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index dfd54662e3e6..9253ef1dba72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h | |||
@@ -187,7 +187,7 @@ | |||
187 | #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) | 187 | #define SCD_QUEUE_STTS_REG_POS_ACTIVE (3) |
188 | #define SCD_QUEUE_STTS_REG_POS_WSL (4) | 188 | #define SCD_QUEUE_STTS_REG_POS_WSL (4) |
189 | #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) | 189 | #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) |
190 | #define SCD_QUEUE_STTS_REG_MSK (0x00FF0000) | 190 | #define SCD_QUEUE_STTS_REG_MSK (0x017F0000) |
191 | 191 | ||
192 | #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) | 192 | #define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) |
193 | #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) | 193 | #define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 79a1e7ae4995..00efde8e5536 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -154,6 +154,9 @@ struct iwl_cmd_header { | |||
154 | __le16 sequence; | 154 | __le16 sequence; |
155 | } __packed; | 155 | } __packed; |
156 | 156 | ||
157 | /* iwl_cmd_header flags value */ | ||
158 | #define IWL_CMD_FAILED_MSK 0x40 | ||
159 | |||
157 | 160 | ||
158 | #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ | 161 | #define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ |
159 | #define FH_RSCSR_FRAME_INVALID 0x55550000 | 162 | #define FH_RSCSR_FRAME_INVALID 0x55550000 |
@@ -280,6 +283,8 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) | |||
280 | 283 | ||
281 | #define MAX_NO_RECLAIM_CMDS 6 | 284 | #define MAX_NO_RECLAIM_CMDS 6 |
282 | 285 | ||
286 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | ||
287 | |||
283 | /* | 288 | /* |
284 | * Maximum number of HW queues the transport layer | 289 | * Maximum number of HW queues the transport layer |
285 | * currently supports | 290 | * currently supports |
@@ -350,10 +355,10 @@ struct iwl_trans; | |||
350 | * Must be atomic | 355 | * Must be atomic |
351 | * @reclaim: free packet until ssn. Returns a list of freed packets. | 356 | * @reclaim: free packet until ssn. Returns a list of freed packets. |
352 | * Must be atomic | 357 | * Must be atomic |
353 | * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is | 358 | * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is |
354 | * ready and a successful ADDBA response has been received. | 359 | * ready and a successful ADDBA response has been received. |
355 | * May sleep | 360 | * May sleep |
356 | * @tx_agg_disable: de-configure a Tx queue to send AMPDUs | 361 | * @txq_disable: de-configure a Tx queue to send AMPDUs |
357 | * Must be atomic | 362 | * Must be atomic |
358 | * @wait_tx_queue_empty: wait until all tx queues are empty | 363 | * @wait_tx_queue_empty: wait until all tx queues are empty |
359 | * May sleep | 364 | * May sleep |
@@ -386,9 +391,9 @@ struct iwl_trans_ops { | |||
386 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, | 391 | void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, |
387 | struct sk_buff_head *skbs); | 392 | struct sk_buff_head *skbs); |
388 | 393 | ||
389 | void (*tx_agg_setup)(struct iwl_trans *trans, int queue, int fifo, | 394 | void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo, |
390 | int sta_id, int tid, int frame_limit, u16 ssn); | 395 | int sta_id, int tid, int frame_limit, u16 ssn); |
391 | void (*tx_agg_disable)(struct iwl_trans *trans, int queue); | 396 | void (*txq_disable)(struct iwl_trans *trans, int queue); |
392 | 397 | ||
393 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); | 398 | int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); |
394 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); | 399 | int (*wait_tx_queue_empty)(struct iwl_trans *trans); |
@@ -428,6 +433,11 @@ enum iwl_trans_state { | |||
428 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 433 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
429 | * @pm_support: set to true in start_hw if link pm is supported | 434 | * @pm_support: set to true in start_hw if link pm is supported |
430 | * @wait_command_queue: the wait_queue for SYNC host commands | 435 | * @wait_command_queue: the wait_queue for SYNC host commands |
436 | * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. | ||
437 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | ||
438 | * @dev_cmd_headroom: room needed for the transport's private use before the | ||
439 | * device_cmd for Tx - for internal use only | ||
440 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | ||
431 | */ | 441 | */ |
432 | struct iwl_trans { | 442 | struct iwl_trans { |
433 | const struct iwl_trans_ops *ops; | 443 | const struct iwl_trans_ops *ops; |
@@ -445,6 +455,10 @@ struct iwl_trans { | |||
445 | 455 | ||
446 | wait_queue_head_t wait_command_queue; | 456 | wait_queue_head_t wait_command_queue; |
447 | 457 | ||
458 | /* The following fields are internal only */ | ||
459 | struct kmem_cache *dev_cmd_pool; | ||
460 | size_t dev_cmd_headroom; | ||
461 | |||
448 | /* pointer to trans specific struct */ | 462 | /* pointer to trans specific struct */ |
449 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 463 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
450 | char trans_specific[0] __aligned(sizeof(void *)); | 464 | char trans_specific[0] __aligned(sizeof(void *)); |
@@ -520,6 +534,26 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, | |||
520 | return trans->ops->send_cmd(trans, cmd); | 534 | return trans->ops->send_cmd(trans, cmd); |
521 | } | 535 | } |
522 | 536 | ||
537 | static inline struct iwl_device_cmd * | ||
538 | iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) | ||
539 | { | ||
540 | u8 *dev_cmd_ptr = kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC); | ||
541 | |||
542 | if (unlikely(dev_cmd_ptr == NULL)) | ||
543 | return NULL; | ||
544 | |||
545 | return (struct iwl_device_cmd *) | ||
546 | (dev_cmd_ptr + trans->dev_cmd_headroom); | ||
547 | } | ||
548 | |||
549 | static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, | ||
550 | struct iwl_device_cmd *dev_cmd) | ||
551 | { | ||
552 | u8 *dev_cmd_ptr = (u8 *)dev_cmd - trans->dev_cmd_headroom; | ||
553 | |||
554 | kmem_cache_free(trans->dev_cmd_pool, dev_cmd_ptr); | ||
555 | } | ||
556 | |||
523 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, | 557 | static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, |
524 | struct iwl_device_cmd *dev_cmd, int queue) | 558 | struct iwl_device_cmd *dev_cmd, int queue) |
525 | { | 559 | { |
@@ -538,24 +572,24 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, | |||
538 | trans->ops->reclaim(trans, queue, ssn, skbs); | 572 | trans->ops->reclaim(trans, queue, ssn, skbs); |
539 | } | 573 | } |
540 | 574 | ||
541 | static inline void iwl_trans_tx_agg_disable(struct iwl_trans *trans, int queue) | 575 | static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) |
542 | { | 576 | { |
543 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 577 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
544 | "%s bad state = %d", __func__, trans->state); | 578 | "%s bad state = %d", __func__, trans->state); |
545 | 579 | ||
546 | trans->ops->tx_agg_disable(trans, queue); | 580 | trans->ops->txq_disable(trans, queue); |
547 | } | 581 | } |
548 | 582 | ||
549 | static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int queue, | 583 | static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, |
550 | int fifo, int sta_id, int tid, | 584 | int fifo, int sta_id, int tid, |
551 | int frame_limit, u16 ssn) | 585 | int frame_limit, u16 ssn) |
552 | { | 586 | { |
553 | might_sleep(); | 587 | might_sleep(); |
554 | 588 | ||
555 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, | 589 | WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, |
556 | "%s bad state = %d", __func__, trans->state); | 590 | "%s bad state = %d", __func__, trans->state); |
557 | 591 | ||
558 | trans->ops->tx_agg_setup(trans, queue, fifo, sta_id, tid, | 592 | trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, |
559 | frame_limit, ssn); | 593 | frame_limit, ssn); |
560 | } | 594 | } |
561 | 595 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c index 2629a6602dfa..81b83f484f08 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/pcie/1000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-csr.h" | 30 | #include "iwl-csr.h" |
32 | #include "iwl-agn-hw.h" | 31 | #include "iwl-agn-hw.h" |
32 | #include "cfg.h" | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL1000_UCODE_API_MAX 5 | 35 | #define IWL1000_UCODE_API_MAX 5 |
@@ -64,13 +64,26 @@ static const struct iwl_base_params iwl1000_base_params = { | |||
64 | .support_ct_kill_exit = true, | 64 | .support_ct_kill_exit = true, |
65 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 65 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
66 | .chain_noise_scale = 1000, | 66 | .chain_noise_scale = 1000, |
67 | .wd_timeout = IWL_WATCHHDOG_DISABLED, | 67 | .wd_timeout = IWL_WATCHDOG_DISABLED, |
68 | .max_event_log_size = 128, | 68 | .max_event_log_size = 128, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const struct iwl_ht_params iwl1000_ht_params = { | 71 | static const struct iwl_ht_params iwl1000_ht_params = { |
72 | .ht_greenfield_support = true, | 72 | .ht_greenfield_support = true, |
73 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 73 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
74 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ), | ||
75 | }; | ||
76 | |||
77 | static const struct iwl_eeprom_params iwl1000_eeprom_params = { | ||
78 | .regulatory_bands = { | ||
79 | EEPROM_REG_BAND_1_CHANNELS, | ||
80 | EEPROM_REG_BAND_2_CHANNELS, | ||
81 | EEPROM_REG_BAND_3_CHANNELS, | ||
82 | EEPROM_REG_BAND_4_CHANNELS, | ||
83 | EEPROM_REG_BAND_5_CHANNELS, | ||
84 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
85 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
86 | } | ||
74 | }; | 87 | }; |
75 | 88 | ||
76 | #define IWL_DEVICE_1000 \ | 89 | #define IWL_DEVICE_1000 \ |
@@ -84,6 +97,7 @@ static const struct iwl_ht_params iwl1000_ht_params = { | |||
84 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 97 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
85 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 98 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
86 | .base_params = &iwl1000_base_params, \ | 99 | .base_params = &iwl1000_base_params, \ |
100 | .eeprom_params = &iwl1000_eeprom_params, \ | ||
87 | .led_mode = IWL_LED_BLINK | 101 | .led_mode = IWL_LED_BLINK |
88 | 102 | ||
89 | const struct iwl_cfg iwl1000_bgn_cfg = { | 103 | const struct iwl_cfg iwl1000_bgn_cfg = { |
@@ -108,6 +122,7 @@ const struct iwl_cfg iwl1000_bg_cfg = { | |||
108 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ | 122 | .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ |
109 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ | 123 | .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ |
110 | .base_params = &iwl1000_base_params, \ | 124 | .base_params = &iwl1000_base_params, \ |
125 | .eeprom_params = &iwl1000_eeprom_params, \ | ||
111 | .led_mode = IWL_LED_RF_STATE, \ | 126 | .led_mode = IWL_LED_RF_STATE, \ |
112 | .rx_with_siso_diversity = true | 127 | .rx_with_siso_diversity = true |
113 | 128 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index 8133105ac645..fd4e78f56fa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-commands.h" /* needed for BT for now */ | 31 | #include "cfg.h" |
32 | #include "dvm/commands.h" /* needed for BT for now */ | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL2030_UCODE_API_MAX 6 | 35 | #define IWL2030_UCODE_API_MAX 6 |
@@ -104,6 +104,7 @@ static const struct iwl_base_params iwl2030_base_params = { | |||
104 | static const struct iwl_ht_params iwl2000_ht_params = { | 104 | static const struct iwl_ht_params iwl2000_ht_params = { |
105 | .ht_greenfield_support = true, | 105 | .ht_greenfield_support = true, |
106 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 106 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
107 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ), | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static const struct iwl_bt_params iwl2030_bt_params = { | 110 | static const struct iwl_bt_params iwl2030_bt_params = { |
@@ -116,6 +117,19 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
116 | .bt_session_2 = true, | 117 | .bt_session_2 = true, |
117 | }; | 118 | }; |
118 | 119 | ||
120 | static const struct iwl_eeprom_params iwl20x0_eeprom_params = { | ||
121 | .regulatory_bands = { | ||
122 | EEPROM_REG_BAND_1_CHANNELS, | ||
123 | EEPROM_REG_BAND_2_CHANNELS, | ||
124 | EEPROM_REG_BAND_3_CHANNELS, | ||
125 | EEPROM_REG_BAND_4_CHANNELS, | ||
126 | EEPROM_REG_BAND_5_CHANNELS, | ||
127 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
128 | EEPROM_REGULATORY_BAND_NO_HT40, | ||
129 | }, | ||
130 | .enhanced_txpower = true, | ||
131 | }; | ||
132 | |||
119 | #define IWL_DEVICE_2000 \ | 133 | #define IWL_DEVICE_2000 \ |
120 | .fw_name_pre = IWL2000_FW_PRE, \ | 134 | .fw_name_pre = IWL2000_FW_PRE, \ |
121 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ | 135 | .ucode_api_max = IWL2000_UCODE_API_MAX, \ |
@@ -127,6 +141,7 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
127 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 141 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
128 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 142 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
129 | .base_params = &iwl2000_base_params, \ | 143 | .base_params = &iwl2000_base_params, \ |
144 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
130 | .need_temp_offset_calib = true, \ | 145 | .need_temp_offset_calib = true, \ |
131 | .temp_offset_v2 = true, \ | 146 | .temp_offset_v2 = true, \ |
132 | .led_mode = IWL_LED_RF_STATE | 147 | .led_mode = IWL_LED_RF_STATE |
@@ -155,6 +170,7 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = { | |||
155 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 170 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
156 | .base_params = &iwl2030_base_params, \ | 171 | .base_params = &iwl2030_base_params, \ |
157 | .bt_params = &iwl2030_bt_params, \ | 172 | .bt_params = &iwl2030_bt_params, \ |
173 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
158 | .need_temp_offset_calib = true, \ | 174 | .need_temp_offset_calib = true, \ |
159 | .temp_offset_v2 = true, \ | 175 | .temp_offset_v2 = true, \ |
160 | .led_mode = IWL_LED_RF_STATE, \ | 176 | .led_mode = IWL_LED_RF_STATE, \ |
@@ -177,6 +193,7 @@ const struct iwl_cfg iwl2030_2bgn_cfg = { | |||
177 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ | 193 | .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ |
178 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 194 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
179 | .base_params = &iwl2000_base_params, \ | 195 | .base_params = &iwl2000_base_params, \ |
196 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
180 | .need_temp_offset_calib = true, \ | 197 | .need_temp_offset_calib = true, \ |
181 | .temp_offset_v2 = true, \ | 198 | .temp_offset_v2 = true, \ |
182 | .led_mode = IWL_LED_RF_STATE, \ | 199 | .led_mode = IWL_LED_RF_STATE, \ |
@@ -207,6 +224,7 @@ const struct iwl_cfg iwl105_bgn_d_cfg = { | |||
207 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ | 224 | .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ |
208 | .base_params = &iwl2030_base_params, \ | 225 | .base_params = &iwl2030_base_params, \ |
209 | .bt_params = &iwl2030_bt_params, \ | 226 | .bt_params = &iwl2030_bt_params, \ |
227 | .eeprom_params = &iwl20x0_eeprom_params, \ | ||
210 | .need_temp_offset_calib = true, \ | 228 | .need_temp_offset_calib = true, \ |
211 | .temp_offset_v2 = true, \ | 229 | .temp_offset_v2 = true, \ |
212 | .led_mode = IWL_LED_RF_STATE, \ | 230 | .led_mode = IWL_LED_RF_STATE, \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c index 8e26bc825f23..d1665fa6d15a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/pcie/5000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-csr.h" | 31 | #include "iwl-csr.h" |
32 | #include "cfg.h" | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL5000_UCODE_API_MAX 5 | 35 | #define IWL5000_UCODE_API_MAX 5 |
@@ -62,13 +62,26 @@ static const struct iwl_base_params iwl5000_base_params = { | |||
62 | .led_compensation = 51, | 62 | .led_compensation = 51, |
63 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 63 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
64 | .chain_noise_scale = 1000, | 64 | .chain_noise_scale = 1000, |
65 | .wd_timeout = IWL_WATCHHDOG_DISABLED, | 65 | .wd_timeout = IWL_WATCHDOG_DISABLED, |
66 | .max_event_log_size = 512, | 66 | .max_event_log_size = 512, |
67 | .no_idle_support = true, | 67 | .no_idle_support = true, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static const struct iwl_ht_params iwl5000_ht_params = { | 70 | static const struct iwl_ht_params iwl5000_ht_params = { |
71 | .ht_greenfield_support = true, | 71 | .ht_greenfield_support = true, |
72 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
73 | }; | ||
74 | |||
75 | static const struct iwl_eeprom_params iwl5000_eeprom_params = { | ||
76 | .regulatory_bands = { | ||
77 | EEPROM_REG_BAND_1_CHANNELS, | ||
78 | EEPROM_REG_BAND_2_CHANNELS, | ||
79 | EEPROM_REG_BAND_3_CHANNELS, | ||
80 | EEPROM_REG_BAND_4_CHANNELS, | ||
81 | EEPROM_REG_BAND_5_CHANNELS, | ||
82 | EEPROM_REG_BAND_24_HT40_CHANNELS, | ||
83 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
84 | }, | ||
72 | }; | 85 | }; |
73 | 86 | ||
74 | #define IWL_DEVICE_5000 \ | 87 | #define IWL_DEVICE_5000 \ |
@@ -82,6 +95,7 @@ static const struct iwl_ht_params iwl5000_ht_params = { | |||
82 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ | 95 | .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ |
83 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ | 96 | .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ |
84 | .base_params = &iwl5000_base_params, \ | 97 | .base_params = &iwl5000_base_params, \ |
98 | .eeprom_params = &iwl5000_eeprom_params, \ | ||
85 | .led_mode = IWL_LED_BLINK | 99 | .led_mode = IWL_LED_BLINK |
86 | 100 | ||
87 | const struct iwl_cfg iwl5300_agn_cfg = { | 101 | const struct iwl_cfg iwl5300_agn_cfg = { |
@@ -128,6 +142,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
128 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, | 142 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, |
129 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | 143 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, |
130 | .base_params = &iwl5000_base_params, | 144 | .base_params = &iwl5000_base_params, |
145 | .eeprom_params = &iwl5000_eeprom_params, | ||
131 | .ht_params = &iwl5000_ht_params, | 146 | .ht_params = &iwl5000_ht_params, |
132 | .led_mode = IWL_LED_BLINK, | 147 | .led_mode = IWL_LED_BLINK, |
133 | .internal_wimax_coex = true, | 148 | .internal_wimax_coex = true, |
@@ -144,6 +159,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
144 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ | 159 | .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ |
145 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ | 160 | .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ |
146 | .base_params = &iwl5000_base_params, \ | 161 | .base_params = &iwl5000_base_params, \ |
162 | .eeprom_params = &iwl5000_eeprom_params, \ | ||
147 | .no_xtal_calib = true, \ | 163 | .no_xtal_calib = true, \ |
148 | .led_mode = IWL_LED_BLINK, \ | 164 | .led_mode = IWL_LED_BLINK, \ |
149 | .internal_wimax_coex = true | 165 | .internal_wimax_coex = true |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c index e5e8ada4aaf6..cb08ba03aae7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/pcie/6000.c | |||
@@ -27,9 +27,9 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/stringify.h> | 28 | #include <linux/stringify.h> |
29 | #include "iwl-config.h" | 29 | #include "iwl-config.h" |
30 | #include "iwl-cfg.h" | ||
31 | #include "iwl-agn-hw.h" | 30 | #include "iwl-agn-hw.h" |
32 | #include "iwl-commands.h" /* needed for BT for now */ | 31 | #include "cfg.h" |
32 | #include "dvm/commands.h" /* needed for BT for now */ | ||
33 | 33 | ||
34 | /* Highest firmware API version supported */ | 34 | /* Highest firmware API version supported */ |
35 | #define IWL6000_UCODE_API_MAX 6 | 35 | #define IWL6000_UCODE_API_MAX 6 |
@@ -127,6 +127,7 @@ static const struct iwl_base_params iwl6000_g2_base_params = { | |||
127 | static const struct iwl_ht_params iwl6000_ht_params = { | 127 | static const struct iwl_ht_params iwl6000_ht_params = { |
128 | .ht_greenfield_support = true, | 128 | .ht_greenfield_support = true, |
129 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 129 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
130 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
130 | }; | 131 | }; |
131 | 132 | ||
132 | static const struct iwl_bt_params iwl6000_bt_params = { | 133 | static const struct iwl_bt_params iwl6000_bt_params = { |
@@ -138,6 +139,19 @@ static const struct iwl_bt_params iwl6000_bt_params = { | |||
138 | .bt_sco_disable = true, | 139 | .bt_sco_disable = true, |
139 | }; | 140 | }; |
140 | 141 | ||
142 | static const struct iwl_eeprom_params iwl6000_eeprom_params = { | ||
143 | .regulatory_bands = { | ||
144 | EEPROM_REG_BAND_1_CHANNELS, | ||
145 | EEPROM_REG_BAND_2_CHANNELS, | ||
146 | EEPROM_REG_BAND_3_CHANNELS, | ||
147 | EEPROM_REG_BAND_4_CHANNELS, | ||
148 | EEPROM_REG_BAND_5_CHANNELS, | ||
149 | EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||
150 | EEPROM_REG_BAND_52_HT40_CHANNELS | ||
151 | }, | ||
152 | .enhanced_txpower = true, | ||
153 | }; | ||
154 | |||
141 | #define IWL_DEVICE_6005 \ | 155 | #define IWL_DEVICE_6005 \ |
142 | .fw_name_pre = IWL6005_FW_PRE, \ | 156 | .fw_name_pre = IWL6005_FW_PRE, \ |
143 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ | 157 | .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ |
@@ -149,6 +163,7 @@ static const struct iwl_bt_params iwl6000_bt_params = { | |||
149 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ | 163 | .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ |
150 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ | 164 | .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ |
151 | .base_params = &iwl6000_g2_base_params, \ | 165 | .base_params = &iwl6000_g2_base_params, \ |
166 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
152 | .need_temp_offset_calib = true, \ | 167 | .need_temp_offset_calib = true, \ |
153 | .led_mode = IWL_LED_RF_STATE | 168 | .led_mode = IWL_LED_RF_STATE |
154 | 169 | ||
@@ -204,6 +219,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { | |||
204 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ | 219 | .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ |
205 | .base_params = &iwl6000_g2_base_params, \ | 220 | .base_params = &iwl6000_g2_base_params, \ |
206 | .bt_params = &iwl6000_bt_params, \ | 221 | .bt_params = &iwl6000_bt_params, \ |
222 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
207 | .need_temp_offset_calib = true, \ | 223 | .need_temp_offset_calib = true, \ |
208 | .led_mode = IWL_LED_RF_STATE, \ | 224 | .led_mode = IWL_LED_RF_STATE, \ |
209 | .adv_pm = true \ | 225 | .adv_pm = true \ |
@@ -292,6 +308,7 @@ const struct iwl_cfg iwl130_bg_cfg = { | |||
292 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ | 308 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ |
293 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ | 309 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ |
294 | .base_params = &iwl6000_base_params, \ | 310 | .base_params = &iwl6000_base_params, \ |
311 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
295 | .led_mode = IWL_LED_BLINK | 312 | .led_mode = IWL_LED_BLINK |
296 | 313 | ||
297 | const struct iwl_cfg iwl6000i_2agn_cfg = { | 314 | const struct iwl_cfg iwl6000i_2agn_cfg = { |
@@ -322,6 +339,7 @@ const struct iwl_cfg iwl6000i_2bg_cfg = { | |||
322 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ | 339 | .eeprom_ver = EEPROM_6050_EEPROM_VERSION, \ |
323 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ | 340 | .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ |
324 | .base_params = &iwl6050_base_params, \ | 341 | .base_params = &iwl6050_base_params, \ |
342 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
325 | .led_mode = IWL_LED_BLINK, \ | 343 | .led_mode = IWL_LED_BLINK, \ |
326 | .internal_wimax_coex = true | 344 | .internal_wimax_coex = true |
327 | 345 | ||
@@ -346,6 +364,7 @@ const struct iwl_cfg iwl6050_2abg_cfg = { | |||
346 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ | 364 | .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ |
347 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ | 365 | .eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ |
348 | .base_params = &iwl6050_base_params, \ | 366 | .base_params = &iwl6050_base_params, \ |
367 | .eeprom_params = &iwl6000_eeprom_params, \ | ||
349 | .led_mode = IWL_LED_BLINK, \ | 368 | .led_mode = IWL_LED_BLINK, \ |
350 | .internal_wimax_coex = true | 369 | .internal_wimax_coex = true |
351 | 370 | ||
@@ -372,6 +391,7 @@ const struct iwl_cfg iwl6000_3agn_cfg = { | |||
372 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, | 391 | .eeprom_ver = EEPROM_6000_EEPROM_VERSION, |
373 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, | 392 | .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, |
374 | .base_params = &iwl6000_base_params, | 393 | .base_params = &iwl6000_base_params, |
394 | .eeprom_params = &iwl6000_eeprom_params, | ||
375 | .ht_params = &iwl6000_ht_params, | 395 | .ht_params = &iwl6000_ht_params, |
376 | .led_mode = IWL_LED_BLINK, | 396 | .led_mode = IWL_LED_BLINK, |
377 | }; | 397 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h index 82152311d73b..82152311d73b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/pcie/cfg.h | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 0c8a1c2d8847..f4c3500b68c6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -68,10 +68,11 @@ | |||
68 | #include <linux/pci-aspm.h> | 68 | #include <linux/pci-aspm.h> |
69 | 69 | ||
70 | #include "iwl-trans.h" | 70 | #include "iwl-trans.h" |
71 | #include "iwl-cfg.h" | ||
72 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
73 | #include "iwl-trans.h" | 72 | #include "iwl-trans.h" |
74 | #include "iwl-trans-pcie-int.h" | 73 | |
74 | #include "cfg.h" | ||
75 | #include "internal.h" | ||
75 | 76 | ||
76 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ | 77 | #define IWL_PCI_DEVICE(dev, subdev, cfg) \ |
77 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ | 78 | .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index e959207c630a..94201c4d6227 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -313,7 +313,7 @@ void iwl_bg_rx_replenish(struct work_struct *data); | |||
313 | void iwl_irq_tasklet(struct iwl_trans *trans); | 313 | void iwl_irq_tasklet(struct iwl_trans *trans); |
314 | void iwlagn_rx_replenish(struct iwl_trans *trans); | 314 | void iwlagn_rx_replenish(struct iwl_trans *trans); |
315 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | 315 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, |
316 | struct iwl_rx_queue *q); | 316 | struct iwl_rx_queue *q); |
317 | 317 | ||
318 | /***************************************************** | 318 | /***************************************************** |
319 | * ICT | 319 | * ICT |
@@ -328,7 +328,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data); | |||
328 | * TX / HCMD | 328 | * TX / HCMD |
329 | ******************************************************/ | 329 | ******************************************************/ |
330 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, | 330 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, |
331 | struct iwl_tx_queue *txq); | 331 | struct iwl_tx_queue *txq); |
332 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | 332 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, |
333 | struct iwl_tx_queue *txq, | 333 | struct iwl_tx_queue *txq, |
334 | dma_addr_t addr, u16 len, u8 reset); | 334 | dma_addr_t addr, u16 len, u8 reset); |
@@ -337,17 +337,20 @@ int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | |||
337 | void iwl_tx_cmd_complete(struct iwl_trans *trans, | 337 | void iwl_tx_cmd_complete(struct iwl_trans *trans, |
338 | struct iwl_rx_cmd_buffer *rxb, int handler_status); | 338 | struct iwl_rx_cmd_buffer *rxb, int handler_status); |
339 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 339 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
340 | struct iwl_tx_queue *txq, | 340 | struct iwl_tx_queue *txq, |
341 | u16 byte_cnt); | 341 | u16 byte_cnt); |
342 | void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int queue); | 342 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); |
343 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); | 343 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); |
344 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | 344 | void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, |
345 | struct iwl_tx_queue *txq, | 345 | struct iwl_tx_queue *txq, |
346 | int tx_fifo_id, bool active); | 346 | int tx_fifo_id, bool active); |
347 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int queue, int fifo, | 347 | void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, |
348 | int sta_id, int tid, int frame_limit, u16 ssn); | 348 | int fifo, int sta_id, int tid, |
349 | void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 349 | int frame_limit, u16 ssn); |
350 | enum dma_data_direction dma_dir); | 350 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, |
351 | int sta_id, int tid, int frame_limit, u16 ssn); | ||
352 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | ||
353 | enum dma_data_direction dma_dir); | ||
351 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 354 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, |
352 | struct sk_buff_head *skbs); | 355 | struct sk_buff_head *skbs); |
353 | int iwl_queue_space(const struct iwl_queue *q); | 356 | int iwl_queue_space(const struct iwl_queue *q); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 08517d3c80bb..d6860c070c16 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include "iwl-prph.h" | 33 | #include "iwl-prph.h" |
34 | #include "iwl-io.h" | 34 | #include "iwl-io.h" |
35 | #include "iwl-trans-pcie-int.h" | 35 | #include "internal.h" |
36 | #include "iwl-op-mode.h" | 36 | #include "iwl-op-mode.h" |
37 | 37 | ||
38 | #ifdef CONFIG_IWLWIFI_IDI | 38 | #ifdef CONFIG_IWLWIFI_IDI |
@@ -130,7 +130,7 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q) | |||
130 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | 130 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue |
131 | */ | 131 | */ |
132 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | 132 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, |
133 | struct iwl_rx_queue *q) | 133 | struct iwl_rx_queue *q) |
134 | { | 134 | { |
135 | unsigned long flags; | 135 | unsigned long flags; |
136 | u32 reg; | 136 | u32 reg; |
@@ -201,9 +201,7 @@ static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr) | |||
201 | */ | 201 | */ |
202 | static void iwlagn_rx_queue_restock(struct iwl_trans *trans) | 202 | static void iwlagn_rx_queue_restock(struct iwl_trans *trans) |
203 | { | 203 | { |
204 | struct iwl_trans_pcie *trans_pcie = | 204 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
205 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
206 | |||
207 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 205 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
208 | struct list_head *element; | 206 | struct list_head *element; |
209 | struct iwl_rx_mem_buffer *rxb; | 207 | struct iwl_rx_mem_buffer *rxb; |
@@ -253,9 +251,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans) | |||
253 | */ | 251 | */ |
254 | static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | 252 | static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) |
255 | { | 253 | { |
256 | struct iwl_trans_pcie *trans_pcie = | 254 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
257 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
258 | |||
259 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 255 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
260 | struct list_head *element; | 256 | struct list_head *element; |
261 | struct iwl_rx_mem_buffer *rxb; | 257 | struct iwl_rx_mem_buffer *rxb; |
@@ -278,8 +274,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
278 | gfp_mask |= __GFP_COMP; | 274 | gfp_mask |= __GFP_COMP; |
279 | 275 | ||
280 | /* Alloc a new receive buffer */ | 276 | /* Alloc a new receive buffer */ |
281 | page = alloc_pages(gfp_mask, | 277 | page = alloc_pages(gfp_mask, trans_pcie->rx_page_order); |
282 | trans_pcie->rx_page_order); | ||
283 | if (!page) { | 278 | if (!page) { |
284 | if (net_ratelimit()) | 279 | if (net_ratelimit()) |
285 | IWL_DEBUG_INFO(trans, "alloc_pages failed, " | 280 | IWL_DEBUG_INFO(trans, "alloc_pages failed, " |
@@ -315,9 +310,10 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
315 | BUG_ON(rxb->page); | 310 | BUG_ON(rxb->page); |
316 | rxb->page = page; | 311 | rxb->page = page; |
317 | /* Get physical address of the RB */ | 312 | /* Get physical address of the RB */ |
318 | rxb->page_dma = dma_map_page(trans->dev, page, 0, | 313 | rxb->page_dma = |
319 | PAGE_SIZE << trans_pcie->rx_page_order, | 314 | dma_map_page(trans->dev, page, 0, |
320 | DMA_FROM_DEVICE); | 315 | PAGE_SIZE << trans_pcie->rx_page_order, |
316 | DMA_FROM_DEVICE); | ||
321 | /* dma address must be no more than 36 bits */ | 317 | /* dma address must be no more than 36 bits */ |
322 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); | 318 | BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); |
323 | /* and also 256 byte aligned! */ | 319 | /* and also 256 byte aligned! */ |
@@ -465,8 +461,8 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
465 | if (rxb->page != NULL) { | 461 | if (rxb->page != NULL) { |
466 | rxb->page_dma = | 462 | rxb->page_dma = |
467 | dma_map_page(trans->dev, rxb->page, 0, | 463 | dma_map_page(trans->dev, rxb->page, 0, |
468 | PAGE_SIZE << trans_pcie->rx_page_order, | 464 | PAGE_SIZE << trans_pcie->rx_page_order, |
469 | DMA_FROM_DEVICE); | 465 | DMA_FROM_DEVICE); |
470 | list_add_tail(&rxb->list, &rxq->rx_free); | 466 | list_add_tail(&rxb->list, &rxq->rx_free); |
471 | rxq->free_count++; | 467 | rxq->free_count++; |
472 | } else | 468 | } else |
@@ -497,7 +493,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
497 | 493 | ||
498 | /* Rx interrupt, but nothing sent from uCode */ | 494 | /* Rx interrupt, but nothing sent from uCode */ |
499 | if (i == r) | 495 | if (i == r) |
500 | IWL_DEBUG_RX(trans, "r = %d, i = %d\n", r, i); | 496 | IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); |
501 | 497 | ||
502 | /* calculate total frames need to be restock after handling RX */ | 498 | /* calculate total frames need to be restock after handling RX */ |
503 | total_empty = r - rxq->write_actual; | 499 | total_empty = r - rxq->write_actual; |
@@ -513,8 +509,8 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
513 | rxb = rxq->queue[i]; | 509 | rxb = rxq->queue[i]; |
514 | rxq->queue[i] = NULL; | 510 | rxq->queue[i] = NULL; |
515 | 511 | ||
516 | IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); | 512 | IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", |
517 | 513 | r, i, rxb); | |
518 | iwl_rx_handle_rxbuf(trans, rxb); | 514 | iwl_rx_handle_rxbuf(trans, rxb); |
519 | 515 | ||
520 | i = (i + 1) & RX_QUEUE_MASK; | 516 | i = (i + 1) & RX_QUEUE_MASK; |
@@ -546,12 +542,12 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
546 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ | 542 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ |
547 | if (trans->cfg->internal_wimax_coex && | 543 | if (trans->cfg->internal_wimax_coex && |
548 | (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & | 544 | (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & |
549 | APMS_CLK_VAL_MRB_FUNC_MODE) || | 545 | APMS_CLK_VAL_MRB_FUNC_MODE) || |
550 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & | 546 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & |
551 | APMG_PS_CTRL_VAL_RESET_REQ))) { | 547 | APMG_PS_CTRL_VAL_RESET_REQ))) { |
552 | struct iwl_trans_pcie *trans_pcie; | 548 | struct iwl_trans_pcie *trans_pcie = |
549 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
553 | 550 | ||
554 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
555 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 551 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
556 | iwl_op_mode_wimax_active(trans->op_mode); | 552 | iwl_op_mode_wimax_active(trans->op_mode); |
557 | wake_up(&trans->wait_command_queue); | 553 | wake_up(&trans->wait_command_queue); |
@@ -567,6 +563,8 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
567 | /* tasklet for iwlagn interrupt */ | 563 | /* tasklet for iwlagn interrupt */ |
568 | void iwl_irq_tasklet(struct iwl_trans *trans) | 564 | void iwl_irq_tasklet(struct iwl_trans *trans) |
569 | { | 565 | { |
566 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
567 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | ||
570 | u32 inta = 0; | 568 | u32 inta = 0; |
571 | u32 handled = 0; | 569 | u32 handled = 0; |
572 | unsigned long flags; | 570 | unsigned long flags; |
@@ -575,10 +573,6 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
575 | u32 inta_mask; | 573 | u32 inta_mask; |
576 | #endif | 574 | #endif |
577 | 575 | ||
578 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
579 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | ||
580 | |||
581 | |||
582 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 576 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
583 | 577 | ||
584 | /* Ack/clear/reset pending uCode interrupts. | 578 | /* Ack/clear/reset pending uCode interrupts. |
@@ -593,7 +587,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
593 | * interrupt coalescing can still be achieved. | 587 | * interrupt coalescing can still be achieved. |
594 | */ | 588 | */ |
595 | iwl_write32(trans, CSR_INT, | 589 | iwl_write32(trans, CSR_INT, |
596 | trans_pcie->inta | ~trans_pcie->inta_mask); | 590 | trans_pcie->inta | ~trans_pcie->inta_mask); |
597 | 591 | ||
598 | inta = trans_pcie->inta; | 592 | inta = trans_pcie->inta; |
599 | 593 | ||
@@ -602,7 +596,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
602 | /* just for debug */ | 596 | /* just for debug */ |
603 | inta_mask = iwl_read32(trans, CSR_INT_MASK); | 597 | inta_mask = iwl_read32(trans, CSR_INT_MASK); |
604 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", | 598 | IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n", |
605 | inta, inta_mask); | 599 | inta, inta_mask); |
606 | } | 600 | } |
607 | #endif | 601 | #endif |
608 | 602 | ||
@@ -651,7 +645,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
651 | 645 | ||
652 | hw_rfkill = iwl_is_rfkill_set(trans); | 646 | hw_rfkill = iwl_is_rfkill_set(trans); |
653 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", | 647 | IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", |
654 | hw_rfkill ? "disable radio" : "enable radio"); | 648 | hw_rfkill ? "disable radio" : "enable radio"); |
655 | 649 | ||
656 | isr_stats->rfkill++; | 650 | isr_stats->rfkill++; |
657 | 651 | ||
@@ -693,7 +687,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
693 | * Rx "responses" (frame-received notification), and other | 687 | * Rx "responses" (frame-received notification), and other |
694 | * notifications from uCode come through here*/ | 688 | * notifications from uCode come through here*/ |
695 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | | 689 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX | |
696 | CSR_INT_BIT_RX_PERIODIC)) { | 690 | CSR_INT_BIT_RX_PERIODIC)) { |
697 | IWL_DEBUG_ISR(trans, "Rx interrupt\n"); | 691 | IWL_DEBUG_ISR(trans, "Rx interrupt\n"); |
698 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { | 692 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { |
699 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); | 693 | handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); |
@@ -733,7 +727,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
733 | */ | 727 | */ |
734 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) | 728 | if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) |
735 | iwl_write8(trans, CSR_INT_PERIODIC_REG, | 729 | iwl_write8(trans, CSR_INT_PERIODIC_REG, |
736 | CSR_INT_PERIODIC_ENA); | 730 | CSR_INT_PERIODIC_ENA); |
737 | 731 | ||
738 | isr_stats->rx++; | 732 | isr_stats->rx++; |
739 | } | 733 | } |
@@ -782,8 +776,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
782 | /* Free dram table */ | 776 | /* Free dram table */ |
783 | void iwl_free_isr_ict(struct iwl_trans *trans) | 777 | void iwl_free_isr_ict(struct iwl_trans *trans) |
784 | { | 778 | { |
785 | struct iwl_trans_pcie *trans_pcie = | 779 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
786 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
787 | 780 | ||
788 | if (trans_pcie->ict_tbl) { | 781 | if (trans_pcie->ict_tbl) { |
789 | dma_free_coherent(trans->dev, ICT_SIZE, | 782 | dma_free_coherent(trans->dev, ICT_SIZE, |
@@ -802,8 +795,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) | |||
802 | */ | 795 | */ |
803 | int iwl_alloc_isr_ict(struct iwl_trans *trans) | 796 | int iwl_alloc_isr_ict(struct iwl_trans *trans) |
804 | { | 797 | { |
805 | struct iwl_trans_pcie *trans_pcie = | 798 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
806 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
807 | 799 | ||
808 | trans_pcie->ict_tbl = | 800 | trans_pcie->ict_tbl = |
809 | dma_alloc_coherent(trans->dev, ICT_SIZE, | 801 | dma_alloc_coherent(trans->dev, ICT_SIZE, |
@@ -837,10 +829,9 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
837 | */ | 829 | */ |
838 | void iwl_reset_ict(struct iwl_trans *trans) | 830 | void iwl_reset_ict(struct iwl_trans *trans) |
839 | { | 831 | { |
832 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
840 | u32 val; | 833 | u32 val; |
841 | unsigned long flags; | 834 | unsigned long flags; |
842 | struct iwl_trans_pcie *trans_pcie = | ||
843 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
844 | 835 | ||
845 | if (!trans_pcie->ict_tbl) | 836 | if (!trans_pcie->ict_tbl) |
846 | return; | 837 | return; |
@@ -868,9 +859,7 @@ void iwl_reset_ict(struct iwl_trans *trans) | |||
868 | /* Device is going down disable ict interrupt usage */ | 859 | /* Device is going down disable ict interrupt usage */ |
869 | void iwl_disable_ict(struct iwl_trans *trans) | 860 | void iwl_disable_ict(struct iwl_trans *trans) |
870 | { | 861 | { |
871 | struct iwl_trans_pcie *trans_pcie = | 862 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
872 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
873 | |||
874 | unsigned long flags; | 863 | unsigned long flags; |
875 | 864 | ||
876 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 865 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
@@ -934,7 +923,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
934 | if (likely(inta)) | 923 | if (likely(inta)) |
935 | tasklet_schedule(&trans_pcie->irq_tasklet); | 924 | tasklet_schedule(&trans_pcie->irq_tasklet); |
936 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && | 925 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
937 | !trans_pcie->inta) | 926 | !trans_pcie->inta) |
938 | iwl_enable_interrupts(trans); | 927 | iwl_enable_interrupts(trans); |
939 | 928 | ||
940 | unplugged: | 929 | unplugged: |
@@ -945,7 +934,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
945 | /* re-enable interrupts here since we don't have anything to service. */ | 934 | /* re-enable interrupts here since we don't have anything to service. */ |
946 | /* only Re-enable if disabled by irq and no schedules tasklet. */ | 935 | /* only Re-enable if disabled by irq and no schedules tasklet. */ |
947 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && | 936 | if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
948 | !trans_pcie->inta) | 937 | !trans_pcie->inta) |
949 | iwl_enable_interrupts(trans); | 938 | iwl_enable_interrupts(trans); |
950 | 939 | ||
951 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 940 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
@@ -1036,7 +1025,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1036 | 1025 | ||
1037 | inta = (0xff & val) | ((0xff00 & val) << 16); | 1026 | inta = (0xff & val) | ((0xff00 & val) << 16); |
1038 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", | 1027 | IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", |
1039 | inta, inta_mask, val); | 1028 | inta, inta_mask, val); |
1040 | 1029 | ||
1041 | inta &= trans_pcie->inta_mask; | 1030 | inta &= trans_pcie->inta_mask; |
1042 | trans_pcie->inta |= inta; | 1031 | trans_pcie->inta |= inta; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 79c6b91417f9..7461a6a14338 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -70,15 +70,12 @@ | |||
70 | 70 | ||
71 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
72 | #include "iwl-trans.h" | 72 | #include "iwl-trans.h" |
73 | #include "iwl-trans-pcie-int.h" | ||
74 | #include "iwl-csr.h" | 73 | #include "iwl-csr.h" |
75 | #include "iwl-prph.h" | 74 | #include "iwl-prph.h" |
76 | #include "iwl-eeprom.h" | ||
77 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | ||
78 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 77 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
79 | #include "iwl-commands.h" | 78 | #include "dvm/commands.h" |
80 | |||
81 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | ||
82 | 79 | ||
83 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | 80 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ |
84 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ | 81 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ |
@@ -86,8 +83,7 @@ | |||
86 | 83 | ||
87 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | 84 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) |
88 | { | 85 | { |
89 | struct iwl_trans_pcie *trans_pcie = | 86 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
90 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
91 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 87 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
92 | struct device *dev = trans->dev; | 88 | struct device *dev = trans->dev; |
93 | 89 | ||
@@ -114,7 +110,7 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) | |||
114 | 110 | ||
115 | err_rb_stts: | 111 | err_rb_stts: |
116 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | 112 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, |
117 | rxq->bd, rxq->bd_dma); | 113 | rxq->bd, rxq->bd_dma); |
118 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | 114 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); |
119 | rxq->bd = NULL; | 115 | rxq->bd = NULL; |
120 | err_bd: | 116 | err_bd: |
@@ -123,8 +119,7 @@ err_bd: | |||
123 | 119 | ||
124 | static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | 120 | static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) |
125 | { | 121 | { |
126 | struct iwl_trans_pcie *trans_pcie = | 122 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
127 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
128 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 123 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
129 | int i; | 124 | int i; |
130 | 125 | ||
@@ -134,8 +129,8 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | |||
134 | * to an SKB, so we need to unmap and free potential storage */ | 129 | * to an SKB, so we need to unmap and free potential storage */ |
135 | if (rxq->pool[i].page != NULL) { | 130 | if (rxq->pool[i].page != NULL) { |
136 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | 131 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, |
137 | PAGE_SIZE << trans_pcie->rx_page_order, | 132 | PAGE_SIZE << trans_pcie->rx_page_order, |
138 | DMA_FROM_DEVICE); | 133 | DMA_FROM_DEVICE); |
139 | __free_pages(rxq->pool[i].page, | 134 | __free_pages(rxq->pool[i].page, |
140 | trans_pcie->rx_page_order); | 135 | trans_pcie->rx_page_order); |
141 | rxq->pool[i].page = NULL; | 136 | rxq->pool[i].page = NULL; |
@@ -193,8 +188,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | |||
193 | 188 | ||
194 | static int iwl_rx_init(struct iwl_trans *trans) | 189 | static int iwl_rx_init(struct iwl_trans *trans) |
195 | { | 190 | { |
196 | struct iwl_trans_pcie *trans_pcie = | 191 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
197 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
198 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 192 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
199 | 193 | ||
200 | int i, err; | 194 | int i, err; |
@@ -236,10 +230,8 @@ static int iwl_rx_init(struct iwl_trans *trans) | |||
236 | 230 | ||
237 | static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) | 231 | static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) |
238 | { | 232 | { |
239 | struct iwl_trans_pcie *trans_pcie = | 233 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
240 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
241 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 234 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
242 | |||
243 | unsigned long flags; | 235 | unsigned long flags; |
244 | 236 | ||
245 | /*if rxq->bd is NULL, it means that nothing has been allocated, | 237 | /*if rxq->bd is NULL, it means that nothing has been allocated, |
@@ -274,11 +266,11 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) | |||
274 | /* stop Rx DMA */ | 266 | /* stop Rx DMA */ |
275 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | 267 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); |
276 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, | 268 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, |
277 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | 269 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); |
278 | } | 270 | } |
279 | 271 | ||
280 | static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, | 272 | static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, |
281 | struct iwl_dma_ptr *ptr, size_t size) | 273 | struct iwl_dma_ptr *ptr, size_t size) |
282 | { | 274 | { |
283 | if (WARN_ON(ptr->addr)) | 275 | if (WARN_ON(ptr->addr)) |
284 | return -EINVAL; | 276 | return -EINVAL; |
@@ -291,8 +283,8 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, | |||
291 | return 0; | 283 | return 0; |
292 | } | 284 | } |
293 | 285 | ||
294 | static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, | 286 | static void iwlagn_free_dma_ptr(struct iwl_trans *trans, |
295 | struct iwl_dma_ptr *ptr) | 287 | struct iwl_dma_ptr *ptr) |
296 | { | 288 | { |
297 | if (unlikely(!ptr->addr)) | 289 | if (unlikely(!ptr->addr)) |
298 | return; | 290 | return; |
@@ -329,12 +321,12 @@ static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) | |||
329 | } | 321 | } |
330 | 322 | ||
331 | static int iwl_trans_txq_alloc(struct iwl_trans *trans, | 323 | static int iwl_trans_txq_alloc(struct iwl_trans *trans, |
332 | struct iwl_tx_queue *txq, int slots_num, | 324 | struct iwl_tx_queue *txq, int slots_num, |
333 | u32 txq_id) | 325 | u32 txq_id) |
334 | { | 326 | { |
327 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
335 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | 328 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
336 | int i; | 329 | int i; |
337 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
338 | 330 | ||
339 | if (WARN_ON(txq->entries || txq->tfds)) | 331 | if (WARN_ON(txq->entries || txq->tfds)) |
340 | return -EINVAL; | 332 | return -EINVAL; |
@@ -435,7 +427,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | |||
435 | 427 | ||
436 | spin_lock_bh(&txq->lock); | 428 | spin_lock_bh(&txq->lock); |
437 | while (q->write_ptr != q->read_ptr) { | 429 | while (q->write_ptr != q->read_ptr) { |
438 | iwlagn_txq_free_tfd(trans, txq, dma_dir); | 430 | iwl_txq_free_tfd(trans, txq, dma_dir); |
439 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | 431 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); |
440 | } | 432 | } |
441 | spin_unlock_bh(&txq->lock); | 433 | spin_unlock_bh(&txq->lock); |
@@ -455,6 +447,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | |||
455 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 447 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; |
456 | struct device *dev = trans->dev; | 448 | struct device *dev = trans->dev; |
457 | int i; | 449 | int i; |
450 | |||
458 | if (WARN_ON(!txq)) | 451 | if (WARN_ON(!txq)) |
459 | return; | 452 | return; |
460 | 453 | ||
@@ -574,11 +567,11 @@ error: | |||
574 | } | 567 | } |
575 | static int iwl_tx_init(struct iwl_trans *trans) | 568 | static int iwl_tx_init(struct iwl_trans *trans) |
576 | { | 569 | { |
570 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
577 | int ret; | 571 | int ret; |
578 | int txq_id, slots_num; | 572 | int txq_id, slots_num; |
579 | unsigned long flags; | 573 | unsigned long flags; |
580 | bool alloc = false; | 574 | bool alloc = false; |
581 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
582 | 575 | ||
583 | if (!trans_pcie->txq) { | 576 | if (!trans_pcie->txq) { |
584 | ret = iwl_trans_tx_alloc(trans); | 577 | ret = iwl_trans_tx_alloc(trans); |
@@ -643,10 +636,9 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) | |||
643 | 636 | ||
644 | static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) | 637 | static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) |
645 | { | 638 | { |
639 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
646 | int pos; | 640 | int pos; |
647 | u16 pci_lnk_ctl; | 641 | u16 pci_lnk_ctl; |
648 | struct iwl_trans_pcie *trans_pcie = | ||
649 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
650 | 642 | ||
651 | struct pci_dev *pci_dev = trans_pcie->pci_dev; | 643 | struct pci_dev *pci_dev = trans_pcie->pci_dev; |
652 | 644 | ||
@@ -700,14 +692,14 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
700 | 692 | ||
701 | /* Disable L0S exit timer (platform NMI Work/Around) */ | 693 | /* Disable L0S exit timer (platform NMI Work/Around) */ |
702 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, | 694 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, |
703 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | 695 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
704 | 696 | ||
705 | /* | 697 | /* |
706 | * Disable L0s without affecting L1; | 698 | * Disable L0s without affecting L1; |
707 | * don't wait for ICH L0s (ICH bug W/A) | 699 | * don't wait for ICH L0s (ICH bug W/A) |
708 | */ | 700 | */ |
709 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, | 701 | iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, |
710 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | 702 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); |
711 | 703 | ||
712 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ | 704 | /* Set FH wait threshold to maximum (HW error during stress W/A) */ |
713 | iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); | 705 | iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); |
@@ -717,7 +709,7 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
717 | * wake device's PCI Express link L1a -> L0s | 709 | * wake device's PCI Express link L1a -> L0s |
718 | */ | 710 | */ |
719 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | 711 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
720 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | 712 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); |
721 | 713 | ||
722 | iwl_apm_config(trans); | 714 | iwl_apm_config(trans); |
723 | 715 | ||
@@ -738,8 +730,8 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
738 | * and accesses to uCode SRAM. | 730 | * and accesses to uCode SRAM. |
739 | */ | 731 | */ |
740 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, | 732 | ret = iwl_poll_bit(trans, CSR_GP_CNTRL, |
741 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 733 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
742 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | 734 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
743 | if (ret < 0) { | 735 | if (ret < 0) { |
744 | IWL_DEBUG_INFO(trans, "Failed to init the card\n"); | 736 | IWL_DEBUG_INFO(trans, "Failed to init the card\n"); |
745 | goto out; | 737 | goto out; |
@@ -773,8 +765,8 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) | |||
773 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); | 765 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); |
774 | 766 | ||
775 | ret = iwl_poll_bit(trans, CSR_RESET, | 767 | ret = iwl_poll_bit(trans, CSR_RESET, |
776 | CSR_RESET_REG_FLAG_MASTER_DISABLED, | 768 | CSR_RESET_REG_FLAG_MASTER_DISABLED, |
777 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); | 769 | CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); |
778 | if (ret) | 770 | if (ret) |
779 | IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); | 771 | IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); |
780 | 772 | ||
@@ -816,8 +808,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
816 | iwl_apm_init(trans); | 808 | iwl_apm_init(trans); |
817 | 809 | ||
818 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ | 810 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ |
819 | iwl_write8(trans, CSR_INT_COALESCING, | 811 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); |
820 | IWL_HOST_INT_CALIB_TIMEOUT_DEF); | ||
821 | 812 | ||
822 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 813 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
823 | 814 | ||
@@ -836,8 +827,8 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
836 | 827 | ||
837 | if (trans->cfg->base_params->shadow_reg_enable) { | 828 | if (trans->cfg->base_params->shadow_reg_enable) { |
838 | /* enable shadow regs in HW */ | 829 | /* enable shadow regs in HW */ |
839 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, | 830 | iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); |
840 | 0x800FFFFF); | 831 | IWL_DEBUG_INFO(trans, "Enabling shadow registers in device\n"); |
841 | } | 832 | } |
842 | 833 | ||
843 | return 0; | 834 | return 0; |
@@ -851,13 +842,13 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) | |||
851 | int ret; | 842 | int ret; |
852 | 843 | ||
853 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | 844 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
854 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); | 845 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); |
855 | 846 | ||
856 | /* See if we got it */ | 847 | /* See if we got it */ |
857 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | 848 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, |
858 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 849 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
859 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | 850 | CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, |
860 | HW_READY_TIMEOUT); | 851 | HW_READY_TIMEOUT); |
861 | 852 | ||
862 | IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret < 0 ? " not" : ""); | 853 | IWL_DEBUG_INFO(trans, "hardware%s ready\n", ret < 0 ? " not" : ""); |
863 | return ret; | 854 | return ret; |
@@ -877,11 +868,11 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans) | |||
877 | 868 | ||
878 | /* If HW is not ready, prepare the conditions to check again */ | 869 | /* If HW is not ready, prepare the conditions to check again */ |
879 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | 870 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
880 | CSR_HW_IF_CONFIG_REG_PREPARE); | 871 | CSR_HW_IF_CONFIG_REG_PREPARE); |
881 | 872 | ||
882 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, | 873 | ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, |
883 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, | 874 | ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, |
884 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); | 875 | CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); |
885 | 876 | ||
886 | if (ret < 0) | 877 | if (ret < 0) |
887 | return ret; | 878 | return ret; |
@@ -908,32 +899,33 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num, | |||
908 | trans_pcie->ucode_write_complete = false; | 899 | trans_pcie->ucode_write_complete = false; |
909 | 900 | ||
910 | iwl_write_direct32(trans, | 901 | iwl_write_direct32(trans, |
911 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 902 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
912 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); | 903 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); |
913 | 904 | ||
914 | iwl_write_direct32(trans, | 905 | iwl_write_direct32(trans, |
915 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); | 906 | FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), |
907 | dst_addr); | ||
916 | 908 | ||
917 | iwl_write_direct32(trans, | 909 | iwl_write_direct32(trans, |
918 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | 910 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), |
919 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | 911 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); |
920 | 912 | ||
921 | iwl_write_direct32(trans, | 913 | iwl_write_direct32(trans, |
922 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), | 914 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), |
923 | (iwl_get_dma_hi_addr(phy_addr) | 915 | (iwl_get_dma_hi_addr(phy_addr) |
924 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | 916 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); |
925 | 917 | ||
926 | iwl_write_direct32(trans, | 918 | iwl_write_direct32(trans, |
927 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | 919 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), |
928 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | 920 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | |
929 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | | 921 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | |
930 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); | 922 | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); |
931 | 923 | ||
932 | iwl_write_direct32(trans, | 924 | iwl_write_direct32(trans, |
933 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), | 925 | FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), |
934 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 926 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
935 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | | 927 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | |
936 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); | 928 | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); |
937 | 929 | ||
938 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", | 930 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", |
939 | section_num); | 931 | section_num); |
@@ -1038,6 +1030,10 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1038 | 1030 | ||
1039 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1031 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1040 | 1032 | ||
1033 | /* make sure all queue are not stopped/used */ | ||
1034 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
1035 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
1036 | |||
1041 | trans_pcie->scd_base_addr = | 1037 | trans_pcie->scd_base_addr = |
1042 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); | 1038 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); |
1043 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | 1039 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; |
@@ -1058,69 +1054,39 @@ static void iwl_tx_start(struct iwl_trans *trans) | |||
1058 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | 1054 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, |
1059 | trans_pcie->scd_bc_tbls.dma >> 10); | 1055 | trans_pcie->scd_bc_tbls.dma >> 10); |
1060 | 1056 | ||
1057 | for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { | ||
1058 | int fifo = trans_pcie->setup_q_to_fifo[i]; | ||
1059 | |||
1060 | __iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, | ||
1061 | IWL_TID_NON_QOS, | ||
1062 | SCD_FRAME_LIMIT, 0); | ||
1063 | } | ||
1064 | |||
1065 | /* Activate all Tx DMA/FIFO channels */ | ||
1066 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
1067 | |||
1061 | /* The chain extension of the SCD doesn't work well. This feature is | 1068 | /* The chain extension of the SCD doesn't work well. This feature is |
1062 | * enabled by default by the HW, so we need to disable it manually. | 1069 | * enabled by default by the HW, so we need to disable it manually. |
1063 | */ | 1070 | */ |
1064 | iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); | 1071 | iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); |
1065 | 1072 | ||
1073 | |||
1066 | /* Enable DMA channel */ | 1074 | /* Enable DMA channel */ |
1067 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | 1075 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) |
1068 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | 1076 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), |
1069 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | 1077 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | |
1070 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | 1078 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); |
1071 | 1079 | ||
1072 | /* Update FH chicken bits */ | 1080 | /* Update FH chicken bits */ |
1073 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); | 1081 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); |
1074 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, | 1082 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, |
1075 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | 1083 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); |
1076 | 1084 | ||
1077 | iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, | ||
1078 | SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); | ||
1079 | iwl_write_prph(trans, SCD_AGGR_SEL, 0); | ||
1080 | |||
1081 | /* initiate the queues */ | ||
1082 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { | ||
1083 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); | ||
1084 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); | ||
1085 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
1086 | SCD_CONTEXT_QUEUE_OFFSET(i), 0); | ||
1087 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
1088 | SCD_CONTEXT_QUEUE_OFFSET(i) + | ||
1089 | sizeof(u32), | ||
1090 | ((SCD_WIN_SIZE << | ||
1091 | SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
1092 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
1093 | ((SCD_FRAME_LIMIT << | ||
1094 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
1095 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
1096 | } | ||
1097 | |||
1098 | iwl_write_prph(trans, SCD_INTERRUPT_MASK, | ||
1099 | IWL_MASK(0, trans->cfg->base_params->num_of_queues)); | ||
1100 | |||
1101 | /* Activate all Tx DMA/FIFO channels */ | ||
1102 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
1103 | |||
1104 | iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); | ||
1105 | |||
1106 | /* make sure all queue are not stopped/used */ | ||
1107 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
1108 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
1109 | |||
1110 | for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { | ||
1111 | int fifo = trans_pcie->setup_q_to_fifo[i]; | ||
1112 | |||
1113 | set_bit(i, trans_pcie->queue_used); | ||
1114 | |||
1115 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[i], | ||
1116 | fifo, true); | ||
1117 | } | ||
1118 | |||
1119 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1085 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1120 | 1086 | ||
1121 | /* Enable L1-Active */ | 1087 | /* Enable L1-Active */ |
1122 | iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, | 1088 | iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, |
1123 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | 1089 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); |
1124 | } | 1090 | } |
1125 | 1091 | ||
1126 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | 1092 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) |
@@ -1134,9 +1100,9 @@ static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | |||
1134 | */ | 1100 | */ |
1135 | static int iwl_trans_tx_stop(struct iwl_trans *trans) | 1101 | static int iwl_trans_tx_stop(struct iwl_trans *trans) |
1136 | { | 1102 | { |
1103 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1137 | int ch, txq_id, ret; | 1104 | int ch, txq_id, ret; |
1138 | unsigned long flags; | 1105 | unsigned long flags; |
1139 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1140 | 1106 | ||
1141 | /* Turn off all Tx DMA fifos */ | 1107 | /* Turn off all Tx DMA fifos */ |
1142 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1108 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
@@ -1148,13 +1114,13 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1148 | iwl_write_direct32(trans, | 1114 | iwl_write_direct32(trans, |
1149 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | 1115 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); |
1150 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | 1116 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, |
1151 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), | 1117 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); |
1152 | 1000); | ||
1153 | if (ret < 0) | 1118 | if (ret < 0) |
1154 | IWL_ERR(trans, "Failing on timeout while stopping" | 1119 | IWL_ERR(trans, |
1155 | " DMA channel %d [0x%08x]", ch, | 1120 | "Failing on timeout while stopping DMA channel %d [0x%08x]", |
1156 | iwl_read_direct32(trans, | 1121 | ch, |
1157 | FH_TSSR_TX_STATUS_REG)); | 1122 | iwl_read_direct32(trans, |
1123 | FH_TSSR_TX_STATUS_REG)); | ||
1158 | } | 1124 | } |
1159 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1125 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1160 | 1126 | ||
@@ -1173,8 +1139,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) | |||
1173 | 1139 | ||
1174 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | 1140 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) |
1175 | { | 1141 | { |
1176 | unsigned long flags; | ||
1177 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1142 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1143 | unsigned long flags; | ||
1178 | 1144 | ||
1179 | /* tell the device to stop sending interrupts */ | 1145 | /* tell the device to stop sending interrupts */ |
1180 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 1146 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
@@ -1204,7 +1170,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1204 | 1170 | ||
1205 | /* Make sure (redundant) we've released our request to stay awake */ | 1171 | /* Make sure (redundant) we've released our request to stay awake */ |
1206 | iwl_clear_bit(trans, CSR_GP_CNTRL, | 1172 | iwl_clear_bit(trans, CSR_GP_CNTRL, |
1207 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 1173 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1208 | 1174 | ||
1209 | /* Stop the device, and put it in low power state */ | 1175 | /* Stop the device, and put it in low power state */ |
1210 | iwl_apm_stop(trans); | 1176 | iwl_apm_stop(trans); |
@@ -1278,8 +1244,9 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1278 | txq->entries[q->write_ptr].cmd = dev_cmd; | 1244 | txq->entries[q->write_ptr].cmd = dev_cmd; |
1279 | 1245 | ||
1280 | dev_cmd->hdr.cmd = REPLY_TX; | 1246 | dev_cmd->hdr.cmd = REPLY_TX; |
1281 | dev_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | 1247 | dev_cmd->hdr.sequence = |
1282 | INDEX_TO_SEQ(q->write_ptr))); | 1248 | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | |
1249 | INDEX_TO_SEQ(q->write_ptr))); | ||
1283 | 1250 | ||
1284 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | 1251 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ |
1285 | out_meta = &txq->entries[q->write_ptr].meta; | 1252 | out_meta = &txq->entries[q->write_ptr].meta; |
@@ -1344,7 +1311,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1344 | 1311 | ||
1345 | /* take back ownership of DMA buffer to enable update */ | 1312 | /* take back ownership of DMA buffer to enable update */ |
1346 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, | 1313 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, |
1347 | DMA_BIDIRECTIONAL); | 1314 | DMA_BIDIRECTIONAL); |
1348 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1315 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1349 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 1316 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
1350 | 1317 | ||
@@ -1356,10 +1323,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1356 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1323 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1357 | 1324 | ||
1358 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | 1325 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
1359 | DMA_BIDIRECTIONAL); | 1326 | DMA_BIDIRECTIONAL); |
1360 | 1327 | ||
1361 | trace_iwlwifi_dev_tx(trans->dev, | 1328 | trace_iwlwifi_dev_tx(trans->dev, |
1362 | &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], | 1329 | &txq->tfds[txq->q.write_ptr], |
1363 | sizeof(struct iwl_tfd), | 1330 | sizeof(struct iwl_tfd), |
1364 | &dev_cmd->hdr, firstlen, | 1331 | &dev_cmd->hdr, firstlen, |
1365 | skb->data + hdr_len, secondlen); | 1332 | skb->data + hdr_len, secondlen); |
@@ -1395,8 +1362,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1395 | 1362 | ||
1396 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 1363 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) |
1397 | { | 1364 | { |
1398 | struct iwl_trans_pcie *trans_pcie = | 1365 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1399 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1400 | int err; | 1366 | int err; |
1401 | bool hw_rfkill; | 1367 | bool hw_rfkill; |
1402 | 1368 | ||
@@ -1409,7 +1375,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1409 | iwl_alloc_isr_ict(trans); | 1375 | iwl_alloc_isr_ict(trans); |
1410 | 1376 | ||
1411 | err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, | 1377 | err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, |
1412 | DRV_NAME, trans); | 1378 | DRV_NAME, trans); |
1413 | if (err) { | 1379 | if (err) { |
1414 | IWL_ERR(trans, "Error allocating IRQ %d\n", | 1380 | IWL_ERR(trans, "Error allocating IRQ %d\n", |
1415 | trans_pcie->irq); | 1381 | trans_pcie->irq); |
@@ -1447,9 +1413,9 @@ error: | |||
1447 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, | 1413 | static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, |
1448 | bool op_mode_leaving) | 1414 | bool op_mode_leaving) |
1449 | { | 1415 | { |
1416 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1450 | bool hw_rfkill; | 1417 | bool hw_rfkill; |
1451 | unsigned long flags; | 1418 | unsigned long flags; |
1452 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1453 | 1419 | ||
1454 | iwl_apm_stop(trans); | 1420 | iwl_apm_stop(trans); |
1455 | 1421 | ||
@@ -1553,8 +1519,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
1553 | 1519 | ||
1554 | void iwl_trans_pcie_free(struct iwl_trans *trans) | 1520 | void iwl_trans_pcie_free(struct iwl_trans *trans) |
1555 | { | 1521 | { |
1556 | struct iwl_trans_pcie *trans_pcie = | 1522 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1557 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1558 | 1523 | ||
1559 | iwl_trans_pcie_tx_free(trans); | 1524 | iwl_trans_pcie_tx_free(trans); |
1560 | #ifndef CONFIG_IWLWIFI_IDI | 1525 | #ifndef CONFIG_IWLWIFI_IDI |
@@ -1569,6 +1534,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1569 | iounmap(trans_pcie->hw_base); | 1534 | iounmap(trans_pcie->hw_base); |
1570 | pci_release_regions(trans_pcie->pci_dev); | 1535 | pci_release_regions(trans_pcie->pci_dev); |
1571 | pci_disable_device(trans_pcie->pci_dev); | 1536 | pci_disable_device(trans_pcie->pci_dev); |
1537 | kmem_cache_destroy(trans->dev_cmd_pool); | ||
1572 | 1538 | ||
1573 | kfree(trans); | 1539 | kfree(trans); |
1574 | } | 1540 | } |
@@ -1816,8 +1782,8 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ | |||
1816 | }; | 1782 | }; |
1817 | 1783 | ||
1818 | static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | 1784 | static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, |
1819 | char __user *user_buf, | 1785 | char __user *user_buf, |
1820 | size_t count, loff_t *ppos) | 1786 | size_t count, loff_t *ppos) |
1821 | { | 1787 | { |
1822 | struct iwl_trans *trans = file->private_data; | 1788 | struct iwl_trans *trans = file->private_data; |
1823 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1789 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -1853,11 +1819,11 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1853 | } | 1819 | } |
1854 | 1820 | ||
1855 | static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, | 1821 | static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, |
1856 | char __user *user_buf, | 1822 | char __user *user_buf, |
1857 | size_t count, loff_t *ppos) { | 1823 | size_t count, loff_t *ppos) |
1824 | { | ||
1858 | struct iwl_trans *trans = file->private_data; | 1825 | struct iwl_trans *trans = file->private_data; |
1859 | struct iwl_trans_pcie *trans_pcie = | 1826 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1860 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1861 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 1827 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; |
1862 | char buf[256]; | 1828 | char buf[256]; |
1863 | int pos = 0; | 1829 | int pos = 0; |
@@ -1881,11 +1847,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, | |||
1881 | 1847 | ||
1882 | static ssize_t iwl_dbgfs_interrupt_read(struct file *file, | 1848 | static ssize_t iwl_dbgfs_interrupt_read(struct file *file, |
1883 | char __user *user_buf, | 1849 | char __user *user_buf, |
1884 | size_t count, loff_t *ppos) { | 1850 | size_t count, loff_t *ppos) |
1885 | 1851 | { | |
1886 | struct iwl_trans *trans = file->private_data; | 1852 | struct iwl_trans *trans = file->private_data; |
1887 | struct iwl_trans_pcie *trans_pcie = | 1853 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1888 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1889 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | 1854 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; |
1890 | 1855 | ||
1891 | int pos = 0; | 1856 | int pos = 0; |
@@ -1943,8 +1908,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | |||
1943 | size_t count, loff_t *ppos) | 1908 | size_t count, loff_t *ppos) |
1944 | { | 1909 | { |
1945 | struct iwl_trans *trans = file->private_data; | 1910 | struct iwl_trans *trans = file->private_data; |
1946 | struct iwl_trans_pcie *trans_pcie = | 1911 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1947 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1948 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | 1912 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; |
1949 | 1913 | ||
1950 | char buf[8]; | 1914 | char buf[8]; |
@@ -1964,8 +1928,8 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file, | |||
1964 | } | 1928 | } |
1965 | 1929 | ||
1966 | static ssize_t iwl_dbgfs_csr_write(struct file *file, | 1930 | static ssize_t iwl_dbgfs_csr_write(struct file *file, |
1967 | const char __user *user_buf, | 1931 | const char __user *user_buf, |
1968 | size_t count, loff_t *ppos) | 1932 | size_t count, loff_t *ppos) |
1969 | { | 1933 | { |
1970 | struct iwl_trans *trans = file->private_data; | 1934 | struct iwl_trans *trans = file->private_data; |
1971 | char buf[8]; | 1935 | char buf[8]; |
@@ -1985,8 +1949,8 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, | |||
1985 | } | 1949 | } |
1986 | 1950 | ||
1987 | static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | 1951 | static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, |
1988 | char __user *user_buf, | 1952 | char __user *user_buf, |
1989 | size_t count, loff_t *ppos) | 1953 | size_t count, loff_t *ppos) |
1990 | { | 1954 | { |
1991 | struct iwl_trans *trans = file->private_data; | 1955 | struct iwl_trans *trans = file->private_data; |
1992 | char *buf; | 1956 | char *buf; |
@@ -2029,7 +1993,7 @@ DEBUGFS_WRITE_FILE_OPS(fw_restart); | |||
2029 | * | 1993 | * |
2030 | */ | 1994 | */ |
2031 | static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | 1995 | static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, |
2032 | struct dentry *dir) | 1996 | struct dentry *dir) |
2033 | { | 1997 | { |
2034 | DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); | 1998 | DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR); |
2035 | DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); | 1999 | DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR); |
@@ -2041,9 +2005,10 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | |||
2041 | } | 2005 | } |
2042 | #else | 2006 | #else |
2043 | static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, | 2007 | static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, |
2044 | struct dentry *dir) | 2008 | struct dentry *dir) |
2045 | { return 0; } | 2009 | { |
2046 | 2010 | return 0; | |
2011 | } | ||
2047 | #endif /*CONFIG_IWLWIFI_DEBUGFS */ | 2012 | #endif /*CONFIG_IWLWIFI_DEBUGFS */ |
2048 | 2013 | ||
2049 | static const struct iwl_trans_ops trans_ops_pcie = { | 2014 | static const struct iwl_trans_ops trans_ops_pcie = { |
@@ -2060,8 +2025,8 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
2060 | .tx = iwl_trans_pcie_tx, | 2025 | .tx = iwl_trans_pcie_tx, |
2061 | .reclaim = iwl_trans_pcie_reclaim, | 2026 | .reclaim = iwl_trans_pcie_reclaim, |
2062 | 2027 | ||
2063 | .tx_agg_disable = iwl_trans_pcie_tx_agg_disable, | 2028 | .txq_disable = iwl_trans_pcie_txq_disable, |
2064 | .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, | 2029 | .txq_enable = iwl_trans_pcie_txq_enable, |
2065 | 2030 | ||
2066 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 2031 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2067 | 2032 | ||
@@ -2084,11 +2049,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2084 | { | 2049 | { |
2085 | struct iwl_trans_pcie *trans_pcie; | 2050 | struct iwl_trans_pcie *trans_pcie; |
2086 | struct iwl_trans *trans; | 2051 | struct iwl_trans *trans; |
2052 | char cmd_pool_name[100]; | ||
2087 | u16 pci_cmd; | 2053 | u16 pci_cmd; |
2088 | int err; | 2054 | int err; |
2089 | 2055 | ||
2090 | trans = kzalloc(sizeof(struct iwl_trans) + | 2056 | trans = kzalloc(sizeof(struct iwl_trans) + |
2091 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); | 2057 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); |
2092 | 2058 | ||
2093 | if (WARN_ON(!trans)) | 2059 | if (WARN_ON(!trans)) |
2094 | return NULL; | 2060 | return NULL; |
@@ -2104,7 +2070,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2104 | /* W/A - seems to solve weird behavior. We need to remove this if we | 2070 | /* W/A - seems to solve weird behavior. We need to remove this if we |
2105 | * don't want to stay in L1 all the time. This wastes a lot of power */ | 2071 | * don't want to stay in L1 all the time. This wastes a lot of power */ |
2106 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | | 2072 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | |
2107 | PCIE_LINK_STATE_CLKPM); | 2073 | PCIE_LINK_STATE_CLKPM); |
2108 | 2074 | ||
2109 | if (pci_enable_device(pdev)) { | 2075 | if (pci_enable_device(pdev)) { |
2110 | err = -ENODEV; | 2076 | err = -ENODEV; |
@@ -2120,7 +2086,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2120 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2086 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
2121 | if (!err) | 2087 | if (!err) |
2122 | err = pci_set_consistent_dma_mask(pdev, | 2088 | err = pci_set_consistent_dma_mask(pdev, |
2123 | DMA_BIT_MASK(32)); | 2089 | DMA_BIT_MASK(32)); |
2124 | /* both attempts failed: */ | 2090 | /* both attempts failed: */ |
2125 | if (err) { | 2091 | if (err) { |
2126 | dev_printk(KERN_ERR, &pdev->dev, | 2092 | dev_printk(KERN_ERR, &pdev->dev, |
@@ -2143,13 +2109,13 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2143 | } | 2109 | } |
2144 | 2110 | ||
2145 | dev_printk(KERN_INFO, &pdev->dev, | 2111 | dev_printk(KERN_INFO, &pdev->dev, |
2146 | "pci_resource_len = 0x%08llx\n", | 2112 | "pci_resource_len = 0x%08llx\n", |
2147 | (unsigned long long) pci_resource_len(pdev, 0)); | 2113 | (unsigned long long) pci_resource_len(pdev, 0)); |
2148 | dev_printk(KERN_INFO, &pdev->dev, | 2114 | dev_printk(KERN_INFO, &pdev->dev, |
2149 | "pci_resource_base = %p\n", trans_pcie->hw_base); | 2115 | "pci_resource_base = %p\n", trans_pcie->hw_base); |
2150 | 2116 | ||
2151 | dev_printk(KERN_INFO, &pdev->dev, | 2117 | dev_printk(KERN_INFO, &pdev->dev, |
2152 | "HW Revision ID = 0x%X\n", pdev->revision); | 2118 | "HW Revision ID = 0x%X\n", pdev->revision); |
2153 | 2119 | ||
2154 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | 2120 | /* We disable the RETRY_TIMEOUT register (0x41) to keep |
2155 | * PCI Tx retries from interfering with C3 CPU state */ | 2121 | * PCI Tx retries from interfering with C3 CPU state */ |
@@ -2158,7 +2124,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2158 | err = pci_enable_msi(pdev); | 2124 | err = pci_enable_msi(pdev); |
2159 | if (err) | 2125 | if (err) |
2160 | dev_printk(KERN_ERR, &pdev->dev, | 2126 | dev_printk(KERN_ERR, &pdev->dev, |
2161 | "pci_enable_msi failed(0X%x)", err); | 2127 | "pci_enable_msi failed(0X%x)", err); |
2162 | 2128 | ||
2163 | trans->dev = &pdev->dev; | 2129 | trans->dev = &pdev->dev; |
2164 | trans_pcie->irq = pdev->irq; | 2130 | trans_pcie->irq = pdev->irq; |
@@ -2180,8 +2146,25 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2180 | init_waitqueue_head(&trans->wait_command_queue); | 2146 | init_waitqueue_head(&trans->wait_command_queue); |
2181 | spin_lock_init(&trans->reg_lock); | 2147 | spin_lock_init(&trans->reg_lock); |
2182 | 2148 | ||
2149 | snprintf(cmd_pool_name, sizeof(cmd_pool_name), "iwl_cmd_pool:%s", | ||
2150 | dev_name(trans->dev)); | ||
2151 | |||
2152 | trans->dev_cmd_headroom = 0; | ||
2153 | trans->dev_cmd_pool = | ||
2154 | kmem_cache_create(cmd_pool_name, | ||
2155 | sizeof(struct iwl_device_cmd) | ||
2156 | + trans->dev_cmd_headroom, | ||
2157 | sizeof(void *), | ||
2158 | SLAB_HWCACHE_ALIGN, | ||
2159 | NULL); | ||
2160 | |||
2161 | if (!trans->dev_cmd_pool) | ||
2162 | goto out_pci_disable_msi; | ||
2163 | |||
2183 | return trans; | 2164 | return trans; |
2184 | 2165 | ||
2166 | out_pci_disable_msi: | ||
2167 | pci_disable_msi(pdev); | ||
2185 | out_pci_release_regions: | 2168 | out_pci_release_regions: |
2186 | pci_release_regions(pdev); | 2169 | pci_release_regions(pdev); |
2187 | out_pci_disable_device: | 2170 | out_pci_disable_device: |
@@ -2190,4 +2173,3 @@ out_no_pci: | |||
2190 | kfree(trans); | 2173 | kfree(trans); |
2191 | return NULL; | 2174 | return NULL; |
2192 | } | 2175 | } |
2193 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index a8750238ee09..35e82161ca43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -34,11 +34,10 @@ | |||
34 | #include "iwl-csr.h" | 34 | #include "iwl-csr.h" |
35 | #include "iwl-prph.h" | 35 | #include "iwl-prph.h" |
36 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
37 | #include "iwl-agn-hw.h" | ||
38 | #include "iwl-op-mode.h" | 37 | #include "iwl-op-mode.h" |
39 | #include "iwl-trans-pcie-int.h" | 38 | #include "internal.h" |
40 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | 39 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ |
41 | #include "iwl-commands.h" | 40 | #include "dvm/commands.h" |
42 | 41 | ||
43 | #define IWL_TX_CRC_SIZE 4 | 42 | #define IWL_TX_CRC_SIZE 4 |
44 | #define IWL_TX_DELIMITER_SIZE 4 | 43 | #define IWL_TX_DELIMITER_SIZE 4 |
@@ -47,12 +46,11 @@ | |||
47 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 46 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array |
48 | */ | 47 | */ |
49 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 48 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
50 | struct iwl_tx_queue *txq, | 49 | struct iwl_tx_queue *txq, |
51 | u16 byte_cnt) | 50 | u16 byte_cnt) |
52 | { | 51 | { |
53 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; | 52 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; |
54 | struct iwl_trans_pcie *trans_pcie = | 53 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
55 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
56 | int write_ptr = txq->q.write_ptr; | 54 | int write_ptr = txq->q.write_ptr; |
57 | int txq_id = txq->q.id; | 55 | int txq_id = txq->q.id; |
58 | u8 sec_ctl = 0; | 56 | u8 sec_ctl = 0; |
@@ -178,8 +176,8 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | |||
178 | return tfd->num_tbs & 0x1f; | 176 | return tfd->num_tbs & 0x1f; |
179 | } | 177 | } |
180 | 178 | ||
181 | static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | 179 | static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, |
182 | struct iwl_tfd *tfd, enum dma_data_direction dma_dir) | 180 | struct iwl_tfd *tfd, enum dma_data_direction dma_dir) |
183 | { | 181 | { |
184 | int i; | 182 | int i; |
185 | int num_tbs; | 183 | int num_tbs; |
@@ -209,7 +207,7 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | |||
209 | } | 207 | } |
210 | 208 | ||
211 | /** | 209 | /** |
212 | * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | 210 | * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] |
213 | * @trans - transport private data | 211 | * @trans - transport private data |
214 | * @txq - tx queue | 212 | * @txq - tx queue |
215 | * @dma_dir - the direction of the DMA mapping | 213 | * @dma_dir - the direction of the DMA mapping |
@@ -217,8 +215,8 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | |||
217 | * Does NOT advance any TFD circular buffer read/write indexes | 215 | * Does NOT advance any TFD circular buffer read/write indexes |
218 | * Does NOT free the TFD itself (which is within circular buffer) | 216 | * Does NOT free the TFD itself (which is within circular buffer) |
219 | */ | 217 | */ |
220 | void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 218 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, |
221 | enum dma_data_direction dma_dir) | 219 | enum dma_data_direction dma_dir) |
222 | { | 220 | { |
223 | struct iwl_tfd *tfd_tmp = txq->tfds; | 221 | struct iwl_tfd *tfd_tmp = txq->tfds; |
224 | 222 | ||
@@ -229,8 +227,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
229 | lockdep_assert_held(&txq->lock); | 227 | lockdep_assert_held(&txq->lock); |
230 | 228 | ||
231 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ | 229 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ |
232 | iwlagn_unmap_tfd(trans, &txq->entries[idx].meta, | 230 | iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], |
233 | &tfd_tmp[rd_ptr], dma_dir); | 231 | dma_dir); |
234 | 232 | ||
235 | /* free SKB */ | 233 | /* free SKB */ |
236 | if (txq->entries) { | 234 | if (txq->entries) { |
@@ -270,7 +268,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
270 | /* Each TFD can point to a maximum 20 Tx buffers */ | 268 | /* Each TFD can point to a maximum 20 Tx buffers */ |
271 | if (num_tbs >= IWL_NUM_OF_TBS) { | 269 | if (num_tbs >= IWL_NUM_OF_TBS) { |
272 | IWL_ERR(trans, "Error can not send more than %d chunks\n", | 270 | IWL_ERR(trans, "Error can not send more than %d chunks\n", |
273 | IWL_NUM_OF_TBS); | 271 | IWL_NUM_OF_TBS); |
274 | return -EINVAL; | 272 | return -EINVAL; |
275 | } | 273 | } |
276 | 274 | ||
@@ -279,7 +277,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
279 | 277 | ||
280 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) | 278 | if (unlikely(addr & ~IWL_TX_DMA_MASK)) |
281 | IWL_ERR(trans, "Unaligned address = %llx\n", | 279 | IWL_ERR(trans, "Unaligned address = %llx\n", |
282 | (unsigned long long)addr); | 280 | (unsigned long long)addr); |
283 | 281 | ||
284 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | 282 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); |
285 | 283 | ||
@@ -383,15 +381,13 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, | |||
383 | } | 381 | } |
384 | 382 | ||
385 | static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, | 383 | static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, |
386 | u16 txq_id) | 384 | u16 txq_id) |
387 | { | 385 | { |
386 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
388 | u32 tbl_dw_addr; | 387 | u32 tbl_dw_addr; |
389 | u32 tbl_dw; | 388 | u32 tbl_dw; |
390 | u16 scd_q2ratid; | 389 | u16 scd_q2ratid; |
391 | 390 | ||
392 | struct iwl_trans_pcie *trans_pcie = | ||
393 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
394 | |||
395 | scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; | 391 | scd_q2ratid = ra_tid & SCD_QUEUE_RA_TID_MAP_RATID_MSK; |
396 | 392 | ||
397 | tbl_dw_addr = trans_pcie->scd_base_addr + | 393 | tbl_dw_addr = trans_pcie->scd_base_addr + |
@@ -419,12 +415,11 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) | |||
419 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | 415 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); |
420 | } | 416 | } |
421 | 417 | ||
422 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, | 418 | void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) |
423 | int txq_id, u32 index) | ||
424 | { | 419 | { |
425 | IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d\n", txq_id, index & 0xff); | 420 | IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d\n", txq_id, index & 0xff); |
426 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 421 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
427 | (index & 0xff) | (txq_id << 8)); | 422 | (index & 0xff) | (txq_id << 8)); |
428 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); | 423 | iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); |
429 | } | 424 | } |
430 | 425 | ||
@@ -447,29 +442,34 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, | |||
447 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 442 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
448 | } | 443 | } |
449 | 444 | ||
450 | void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, | 445 | void __iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, |
451 | int sta_id, int tid, int frame_limit, u16 ssn) | 446 | int fifo, int sta_id, int tid, |
447 | int frame_limit, u16 ssn) | ||
452 | { | 448 | { |
453 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 449 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
454 | unsigned long flags; | 450 | |
455 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 451 | lockdep_assert_held(&trans_pcie->irq_lock); |
456 | 452 | ||
457 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) | 453 | if (test_and_set_bit(txq_id, trans_pcie->queue_used)) |
458 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 454 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
459 | 455 | ||
460 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
461 | |||
462 | /* Stop this Tx queue before configuring it */ | 456 | /* Stop this Tx queue before configuring it */ |
463 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); | 457 | iwlagn_tx_queue_stop_scheduler(trans, txq_id); |
464 | 458 | ||
465 | /* Map receiver-address / traffic-ID to this queue */ | 459 | /* Set this queue as a chain-building queue unless it is CMD queue */ |
466 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); | 460 | if (txq_id != trans_pcie->cmd_queue) |
461 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | ||
462 | |||
463 | /* If this queue is mapped to a certain station: it is an AGG queue */ | ||
464 | if (sta_id != IWL_INVALID_STATION) { | ||
465 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | ||
467 | 466 | ||
468 | /* Set this queue as a chain-building queue */ | 467 | /* Map receiver-address / traffic-ID to this queue */ |
469 | iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); | 468 | iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); |
470 | 469 | ||
471 | /* enable aggregations for the queue */ | 470 | /* enable aggregations for the queue */ |
472 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 471 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); |
472 | } | ||
473 | 473 | ||
474 | /* Place first TFD at index corresponding to start sequence number. | 474 | /* Place first TFD at index corresponding to start sequence number. |
475 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | 475 | * Assumes that ssn_idx is valid (!= 0xFFF) */ |
@@ -479,22 +479,34 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, int txq_id, int fifo, | |||
479 | 479 | ||
480 | /* Set up Tx window size and frame limit for this queue */ | 480 | /* Set up Tx window size and frame limit for this queue */ |
481 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | 481 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + |
482 | SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); | ||
483 | iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + | ||
482 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), | 484 | SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), |
483 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | 485 | ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & |
484 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | 486 | SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | |
485 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | 487 | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & |
486 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | 488 | SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); |
487 | 489 | ||
488 | iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
489 | |||
490 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | 490 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ |
491 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], | 491 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], |
492 | fifo, true); | 492 | fifo, true); |
493 | } | ||
494 | |||
495 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | ||
496 | int sta_id, int tid, int frame_limit, u16 ssn) | ||
497 | { | ||
498 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
499 | unsigned long flags; | ||
500 | |||
501 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
502 | |||
503 | __iwl_trans_pcie_txq_enable(trans, txq_id, fifo, sta_id, | ||
504 | tid, frame_limit, ssn); | ||
493 | 505 | ||
494 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 506 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
495 | } | 507 | } |
496 | 508 | ||
497 | void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) | 509 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) |
498 | { | 510 | { |
499 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 511 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
500 | 512 | ||
@@ -511,8 +523,6 @@ void iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int txq_id) | |||
511 | trans_pcie->txq[txq_id].q.write_ptr = 0; | 523 | trans_pcie->txq[txq_id].q.write_ptr = 0; |
512 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); | 524 | iwl_trans_set_wr_ptrs(trans, txq_id, 0); |
513 | 525 | ||
514 | iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, BIT(txq_id)); | ||
515 | |||
516 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], | 526 | iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], |
517 | 0, false); | 527 | 0, false); |
518 | } | 528 | } |
@@ -615,13 +625,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
615 | } | 625 | } |
616 | 626 | ||
617 | IWL_DEBUG_HC(trans, | 627 | IWL_DEBUG_HC(trans, |
618 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", | 628 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", |
619 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), | 629 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), |
620 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, | 630 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), |
621 | q->write_ptr, idx, trans_pcie->cmd_queue); | 631 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); |
622 | 632 | ||
623 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, | 633 | phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, |
624 | DMA_BIDIRECTIONAL); | 634 | DMA_BIDIRECTIONAL); |
625 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | 635 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { |
626 | idx = -ENOMEM; | 636 | idx = -ENOMEM; |
627 | goto out; | 637 | goto out; |
@@ -630,8 +640,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
630 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 640 | dma_unmap_addr_set(out_meta, mapping, phys_addr); |
631 | dma_unmap_len_set(out_meta, len, copy_size); | 641 | dma_unmap_len_set(out_meta, len, copy_size); |
632 | 642 | ||
633 | iwlagn_txq_attach_buf_to_tfd(trans, txq, | 643 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); |
634 | phys_addr, copy_size, 1); | ||
635 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | 644 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
636 | trace_bufs[0] = &out_cmd->hdr; | 645 | trace_bufs[0] = &out_cmd->hdr; |
637 | trace_lens[0] = copy_size; | 646 | trace_lens[0] = copy_size; |
@@ -643,13 +652,12 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
643 | continue; | 652 | continue; |
644 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 653 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) |
645 | continue; | 654 | continue; |
646 | phys_addr = dma_map_single(trans->dev, | 655 | phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], |
647 | (void *)cmd->data[i], | ||
648 | cmd->len[i], DMA_BIDIRECTIONAL); | 656 | cmd->len[i], DMA_BIDIRECTIONAL); |
649 | if (dma_mapping_error(trans->dev, phys_addr)) { | 657 | if (dma_mapping_error(trans->dev, phys_addr)) { |
650 | iwlagn_unmap_tfd(trans, out_meta, | 658 | iwl_unmap_tfd(trans, out_meta, |
651 | &txq->tfds[q->write_ptr], | 659 | &txq->tfds[q->write_ptr], |
652 | DMA_BIDIRECTIONAL); | 660 | DMA_BIDIRECTIONAL); |
653 | idx = -ENOMEM; | 661 | idx = -ENOMEM; |
654 | goto out; | 662 | goto out; |
655 | } | 663 | } |
@@ -723,9 +731,10 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
723 | lockdep_assert_held(&txq->lock); | 731 | lockdep_assert_held(&txq->lock); |
724 | 732 | ||
725 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 733 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
726 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " | 734 | IWL_ERR(trans, |
727 | "index %d is out of range [0-%d] %d %d.\n", __func__, | 735 | "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", |
728 | txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr); | 736 | __func__, txq_id, idx, q->n_bd, |
737 | q->write_ptr, q->read_ptr); | ||
729 | return; | 738 | return; |
730 | } | 739 | } |
731 | 740 | ||
@@ -733,8 +742,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
733 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 742 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
734 | 743 | ||
735 | if (nfreed++ > 0) { | 744 | if (nfreed++ > 0) { |
736 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx, | 745 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", |
737 | q->write_ptr, q->read_ptr); | 746 | idx, q->write_ptr, q->read_ptr); |
738 | iwl_op_mode_nic_error(trans->op_mode); | 747 | iwl_op_mode_nic_error(trans->op_mode); |
739 | } | 748 | } |
740 | 749 | ||
@@ -771,9 +780,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
771 | * in the queue management code. */ | 780 | * in the queue management code. */ |
772 | if (WARN(txq_id != trans_pcie->cmd_queue, | 781 | if (WARN(txq_id != trans_pcie->cmd_queue, |
773 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", | 782 | "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", |
774 | txq_id, trans_pcie->cmd_queue, sequence, | 783 | txq_id, trans_pcie->cmd_queue, sequence, |
775 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, | 784 | trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, |
776 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { | 785 | trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { |
777 | iwl_print_hex_error(trans, pkt, 32); | 786 | iwl_print_hex_error(trans, pkt, 32); |
778 | return; | 787 | return; |
779 | } | 788 | } |
@@ -784,8 +793,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
784 | cmd = txq->entries[cmd_index].cmd; | 793 | cmd = txq->entries[cmd_index].cmd; |
785 | meta = &txq->entries[cmd_index].meta; | 794 | meta = &txq->entries[cmd_index].meta; |
786 | 795 | ||
787 | iwlagn_unmap_tfd(trans, meta, &txq->tfds[index], | 796 | iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); |
788 | DMA_BIDIRECTIONAL); | ||
789 | 797 | ||
790 | /* Input error checking is done when commands are added to queue. */ | 798 | /* Input error checking is done when commands are added to queue. */ |
791 | if (meta->flags & CMD_WANT_SKB) { | 799 | if (meta->flags & CMD_WANT_SKB) { |
@@ -870,8 +878,9 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
870 | } | 878 | } |
871 | 879 | ||
872 | ret = wait_event_timeout(trans->wait_command_queue, | 880 | ret = wait_event_timeout(trans->wait_command_queue, |
873 | !test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status), | 881 | !test_bit(STATUS_HCMD_ACTIVE, |
874 | HOST_COMPLETE_TIMEOUT); | 882 | &trans_pcie->status), |
883 | HOST_COMPLETE_TIMEOUT); | ||
875 | if (!ret) { | 884 | if (!ret) { |
876 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 885 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
877 | struct iwl_tx_queue *txq = | 886 | struct iwl_tx_queue *txq = |
@@ -956,10 +965,10 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | |||
956 | 965 | ||
957 | if ((index >= q->n_bd) || | 966 | if ((index >= q->n_bd) || |
958 | (iwl_queue_used(q, last_to_free) == 0)) { | 967 | (iwl_queue_used(q, last_to_free) == 0)) { |
959 | IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " | 968 | IWL_ERR(trans, |
960 | "last_to_free %d is out of range [0-%d] %d %d.\n", | 969 | "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", |
961 | __func__, txq_id, last_to_free, q->n_bd, | 970 | __func__, txq_id, last_to_free, q->n_bd, |
962 | q->write_ptr, q->read_ptr); | 971 | q->write_ptr, q->read_ptr); |
963 | return 0; | 972 | return 0; |
964 | } | 973 | } |
965 | 974 | ||
@@ -979,7 +988,7 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | |||
979 | 988 | ||
980 | iwlagn_txq_inval_byte_cnt_tbl(trans, txq); | 989 | iwlagn_txq_inval_byte_cnt_tbl(trans, txq); |
981 | 990 | ||
982 | iwlagn_txq_free_tfd(trans, txq, DMA_TO_DEVICE); | 991 | iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); |
983 | freed++; | 992 | freed++; |
984 | } | 993 | } |
985 | 994 | ||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 2fa879b015b6..f4a203049fb4 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -435,24 +435,40 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) | |||
435 | * Set Channel | 435 | * Set Channel |
436 | */ | 436 | */ |
437 | 437 | ||
438 | static int lbs_cfg_set_channel(struct wiphy *wiphy, | 438 | static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, |
439 | struct net_device *netdev, | 439 | struct ieee80211_channel *channel, |
440 | struct ieee80211_channel *channel, | 440 | enum nl80211_channel_type channel_type) |
441 | enum nl80211_channel_type channel_type) | ||
442 | { | 441 | { |
443 | struct lbs_private *priv = wiphy_priv(wiphy); | 442 | struct lbs_private *priv = wiphy_priv(wiphy); |
444 | int ret = -ENOTSUPP; | 443 | int ret = -ENOTSUPP; |
445 | 444 | ||
446 | lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d, type %d", | 445 | lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", |
447 | netdev_name(netdev), channel->center_freq, channel_type); | 446 | channel->center_freq, channel_type); |
448 | 447 | ||
449 | if (channel_type != NL80211_CHAN_NO_HT) | 448 | if (channel_type != NL80211_CHAN_NO_HT) |
450 | goto out; | 449 | goto out; |
451 | 450 | ||
452 | if (netdev == priv->mesh_dev) | 451 | ret = lbs_set_channel(priv, channel->hw_value); |
453 | ret = lbs_mesh_set_channel(priv, channel->hw_value); | 452 | |
454 | else | 453 | out: |
455 | ret = lbs_set_channel(priv, channel->hw_value); | 454 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
455 | return ret; | ||
456 | } | ||
457 | |||
458 | static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy, | ||
459 | struct net_device *netdev, | ||
460 | struct ieee80211_channel *channel) | ||
461 | { | ||
462 | struct lbs_private *priv = wiphy_priv(wiphy); | ||
463 | int ret = -ENOTSUPP; | ||
464 | |||
465 | lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d", | ||
466 | netdev_name(netdev), channel->center_freq); | ||
467 | |||
468 | if (netdev != priv->mesh_dev) | ||
469 | goto out; | ||
470 | |||
471 | ret = lbs_mesh_set_channel(priv, channel->hw_value); | ||
456 | 472 | ||
457 | out: | 473 | out: |
458 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | 474 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
@@ -2029,7 +2045,8 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
2029 | */ | 2045 | */ |
2030 | 2046 | ||
2031 | static struct cfg80211_ops lbs_cfg80211_ops = { | 2047 | static struct cfg80211_ops lbs_cfg80211_ops = { |
2032 | .set_channel = lbs_cfg_set_channel, | 2048 | .set_monitor_channel = lbs_cfg_set_monitor_channel, |
2049 | .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel, | ||
2033 | .scan = lbs_cfg_scan, | 2050 | .scan = lbs_cfg_scan, |
2034 | .connect = lbs_cfg_connect, | 2051 | .connect = lbs_cfg_connect, |
2035 | .disconnect = lbs_cfg_disconnect, | 2052 | .disconnect = lbs_cfg_disconnect, |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index a06cc283e23d..668dd27616a0 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -483,7 +483,7 @@ static ssize_t lbs_rdmac_write(struct file *file, | |||
483 | res = -EFAULT; | 483 | res = -EFAULT; |
484 | goto out_unlock; | 484 | goto out_unlock; |
485 | } | 485 | } |
486 | priv->mac_offset = simple_strtoul((char *)buf, NULL, 16); | 486 | priv->mac_offset = simple_strtoul(buf, NULL, 16); |
487 | res = count; | 487 | res = count; |
488 | out_unlock: | 488 | out_unlock: |
489 | free_page(addr); | 489 | free_page(addr); |
@@ -565,7 +565,7 @@ static ssize_t lbs_rdbbp_write(struct file *file, | |||
565 | res = -EFAULT; | 565 | res = -EFAULT; |
566 | goto out_unlock; | 566 | goto out_unlock; |
567 | } | 567 | } |
568 | priv->bbp_offset = simple_strtoul((char *)buf, NULL, 16); | 568 | priv->bbp_offset = simple_strtoul(buf, NULL, 16); |
569 | res = count; | 569 | res = count; |
570 | out_unlock: | 570 | out_unlock: |
571 | free_page(addr); | 571 | free_page(addr); |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 672005430aca..60996ce89f77 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -58,6 +58,7 @@ struct lbs_private { | |||
58 | uint16_t mesh_tlv; | 58 | uint16_t mesh_tlv; |
59 | u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; | 59 | u8 mesh_ssid[IEEE80211_MAX_SSID_LEN + 1]; |
60 | u8 mesh_ssid_len; | 60 | u8 mesh_ssid_len; |
61 | u8 mesh_channel; | ||
61 | #endif | 62 | #endif |
62 | 63 | ||
63 | /* Debugfs */ | 64 | /* Debugfs */ |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index cd3b0d400618..64b7dc5de126 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -302,7 +302,7 @@ error: | |||
302 | static void if_usb_disconnect(struct usb_interface *intf) | 302 | static void if_usb_disconnect(struct usb_interface *intf) |
303 | { | 303 | { |
304 | struct if_usb_card *cardp = usb_get_intfdata(intf); | 304 | struct if_usb_card *cardp = usb_get_intfdata(intf); |
305 | struct lbs_private *priv = (struct lbs_private *) cardp->priv; | 305 | struct lbs_private *priv = cardp->priv; |
306 | 306 | ||
307 | lbs_deb_enter(LBS_DEB_MAIN); | 307 | lbs_deb_enter(LBS_DEB_MAIN); |
308 | 308 | ||
diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index e87c031b298f..97807751ebcf 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c | |||
@@ -131,16 +131,13 @@ static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, | |||
131 | 131 | ||
132 | int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel) | 132 | int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel) |
133 | { | 133 | { |
134 | priv->mesh_channel = channel; | ||
134 | return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel); | 135 | return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel); |
135 | } | 136 | } |
136 | 137 | ||
137 | static uint16_t lbs_mesh_get_channel(struct lbs_private *priv) | 138 | static uint16_t lbs_mesh_get_channel(struct lbs_private *priv) |
138 | { | 139 | { |
139 | struct wireless_dev *mesh_wdev = priv->mesh_dev->ieee80211_ptr; | 140 | return priv->mesh_channel ?: 1; |
140 | if (mesh_wdev->channel) | ||
141 | return mesh_wdev->channel->hw_value; | ||
142 | else | ||
143 | return 1; | ||
144 | } | 141 | } |
145 | 142 | ||
146 | /*************************************************************************** | 143 | /*************************************************************************** |
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 19a5a92dd779..d576dd6665d3 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c | |||
@@ -253,7 +253,7 @@ lbtf_deb_leave(LBTF_DEB_MAIN); | |||
253 | static void if_usb_disconnect(struct usb_interface *intf) | 253 | static void if_usb_disconnect(struct usb_interface *intf) |
254 | { | 254 | { |
255 | struct if_usb_card *cardp = usb_get_intfdata(intf); | 255 | struct if_usb_card *cardp = usb_get_intfdata(intf); |
256 | struct lbtf_private *priv = (struct lbtf_private *) cardp->priv; | 256 | struct lbtf_private *priv = cardp->priv; |
257 | 257 | ||
258 | lbtf_deb_enter(LBTF_DEB_MAIN); | 258 | lbtf_deb_enter(LBTF_DEB_MAIN); |
259 | 259 | ||
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index fe8ebfebcc0e..e535c937628b 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -101,8 +101,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, | |||
101 | { | 101 | { |
102 | int tid; | 102 | int tid; |
103 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; | 103 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; |
104 | struct host_cmd_ds_11n_delba *del_ba = | 104 | struct host_cmd_ds_11n_delba *del_ba = &resp->params.del_ba; |
105 | (struct host_cmd_ds_11n_delba *) &resp->params.del_ba; | ||
106 | uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set); | 105 | uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set); |
107 | 106 | ||
108 | tid = del_ba_param_set >> DELBA_TID_POS; | 107 | tid = del_ba_param_set >> DELBA_TID_POS; |
@@ -147,8 +146,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, | |||
147 | struct host_cmd_ds_command *resp) | 146 | struct host_cmd_ds_command *resp) |
148 | { | 147 | { |
149 | int tid; | 148 | int tid; |
150 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = | 149 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; |
151 | (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; | ||
152 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; | 150 | struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; |
153 | 151 | ||
154 | add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) | 152 | add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) |
@@ -412,7 +410,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
412 | 410 | ||
413 | memcpy((u8 *) bss_co_2040 + | 411 | memcpy((u8 *) bss_co_2040 + |
414 | sizeof(struct mwifiex_ie_types_header), | 412 | sizeof(struct mwifiex_ie_types_header), |
415 | (u8 *) bss_desc->bcn_bss_co_2040 + | 413 | bss_desc->bcn_bss_co_2040 + |
416 | sizeof(struct ieee_types_header), | 414 | sizeof(struct ieee_types_header), |
417 | le16_to_cpu(bss_co_2040->header.len)); | 415 | le16_to_cpu(bss_co_2040->header.len)); |
418 | 416 | ||
@@ -426,10 +424,8 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
426 | ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY); | 424 | ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY); |
427 | ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap)); | 425 | ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap)); |
428 | 426 | ||
429 | memcpy((u8 *) ext_cap + | 427 | memcpy((u8 *)ext_cap + sizeof(struct mwifiex_ie_types_header), |
430 | sizeof(struct mwifiex_ie_types_header), | 428 | bss_desc->bcn_ext_cap + sizeof(struct ieee_types_header), |
431 | (u8 *) bss_desc->bcn_ext_cap + | ||
432 | sizeof(struct ieee_types_header), | ||
433 | le16_to_cpu(ext_cap->header.len)); | 429 | le16_to_cpu(ext_cap->header.len)); |
434 | 430 | ||
435 | *buffer += sizeof(struct mwifiex_ie_types_extcap); | 431 | *buffer += sizeof(struct mwifiex_ie_types_extcap); |
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 77646d777dce..28366e9211fb 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h | |||
@@ -105,8 +105,7 @@ static inline u8 mwifiex_space_avail_for_new_ba_stream( | |||
105 | priv = adapter->priv[i]; | 105 | priv = adapter->priv[i]; |
106 | if (priv) | 106 | if (priv) |
107 | ba_stream_num += mwifiex_wmm_list_len( | 107 | ba_stream_num += mwifiex_wmm_list_len( |
108 | (struct list_head *) | 108 | &priv->tx_ba_stream_tbl_ptr); |
109 | &priv->tx_ba_stream_tbl_ptr); | ||
110 | } | 109 | } |
111 | 110 | ||
112 | return ((ba_stream_num < | 111 | return ((ba_stream_num < |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 9c44088054dd..89f7c570cd2e 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -296,9 +296,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, | |||
296 | */ | 296 | */ |
297 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) | 297 | int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf) |
298 | { | 298 | { |
299 | struct host_cmd_ds_11n_addba_req *add_ba_req = | 299 | struct host_cmd_ds_11n_addba_req *add_ba_req = &cmd->params.add_ba_req; |
300 | (struct host_cmd_ds_11n_addba_req *) | ||
301 | &cmd->params.add_ba_req; | ||
302 | 300 | ||
303 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ); | 301 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ); |
304 | cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN); | 302 | cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN); |
@@ -320,9 +318,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | |||
320 | struct host_cmd_ds_11n_addba_req | 318 | struct host_cmd_ds_11n_addba_req |
321 | *cmd_addba_req) | 319 | *cmd_addba_req) |
322 | { | 320 | { |
323 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = | 321 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &cmd->params.add_ba_rsp; |
324 | (struct host_cmd_ds_11n_addba_rsp *) | ||
325 | &cmd->params.add_ba_rsp; | ||
326 | u8 tid; | 322 | u8 tid; |
327 | int win_size; | 323 | int win_size; |
328 | uint16_t block_ack_param_set; | 324 | uint16_t block_ack_param_set; |
@@ -367,8 +363,7 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, | |||
367 | */ | 363 | */ |
368 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) | 364 | int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf) |
369 | { | 365 | { |
370 | struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *) | 366 | struct host_cmd_ds_11n_delba *del_ba = &cmd->params.del_ba; |
371 | &cmd->params.del_ba; | ||
372 | 367 | ||
373 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA); | 368 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA); |
374 | cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN); | 369 | cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN); |
@@ -398,8 +393,7 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, | |||
398 | int start_win, end_win, win_size; | 393 | int start_win, end_win, win_size; |
399 | u16 pkt_index; | 394 | u16 pkt_index; |
400 | 395 | ||
401 | tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, | 396 | tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); |
402 | tid, ta); | ||
403 | if (!tbl) { | 397 | if (!tbl) { |
404 | if (pkt_type != PKT_TYPE_BAR) | 398 | if (pkt_type != PKT_TYPE_BAR) |
405 | mwifiex_process_rx_packet(priv->adapter, payload); | 399 | mwifiex_process_rx_packet(priv->adapter, payload); |
@@ -520,9 +514,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, | |||
520 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, | 514 | int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, |
521 | struct host_cmd_ds_command *resp) | 515 | struct host_cmd_ds_command *resp) |
522 | { | 516 | { |
523 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = | 517 | struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; |
524 | (struct host_cmd_ds_11n_addba_rsp *) | ||
525 | &resp->params.add_ba_rsp; | ||
526 | int tid, win_size; | 518 | int tid, win_size; |
527 | struct mwifiex_rx_reorder_tbl *tbl; | 519 | struct mwifiex_rx_reorder_tbl *tbl; |
528 | uint16_t block_ack_param_set; | 520 | uint16_t block_ack_param_set; |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 015fec3371a0..510397b3d4a8 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1716,7 +1716,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) | |||
1716 | wdev_priv = wiphy_priv(wiphy); | 1716 | wdev_priv = wiphy_priv(wiphy); |
1717 | *(unsigned long *)wdev_priv = (unsigned long)adapter; | 1717 | *(unsigned long *)wdev_priv = (unsigned long)adapter; |
1718 | 1718 | ||
1719 | set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); | 1719 | set_wiphy_dev(wiphy, priv->adapter->dev); |
1720 | 1720 | ||
1721 | ret = wiphy_register(wiphy); | 1721 | ret = wiphy_register(wiphy); |
1722 | if (ret < 0) { | 1722 | if (ret < 0) { |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index c1cb004db913..0f18ef6a30c8 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -57,6 +57,68 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | static void scan_delay_timer_fn(unsigned long data) | ||
61 | { | ||
62 | struct mwifiex_private *priv = (struct mwifiex_private *)data; | ||
63 | struct mwifiex_adapter *adapter = priv->adapter; | ||
64 | struct cmd_ctrl_node *cmd_node, *tmp_node; | ||
65 | unsigned long flags; | ||
66 | |||
67 | if (!mwifiex_wmm_lists_empty(adapter)) { | ||
68 | if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) { | ||
69 | /* | ||
70 | * Abort scan operation by cancelling all pending scan | ||
71 | * command | ||
72 | */ | ||
73 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | ||
74 | list_for_each_entry_safe(cmd_node, tmp_node, | ||
75 | &adapter->scan_pending_q, | ||
76 | list) { | ||
77 | list_del(&cmd_node->list); | ||
78 | cmd_node->wait_q_enabled = false; | ||
79 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | ||
80 | } | ||
81 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | ||
82 | flags); | ||
83 | |||
84 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | ||
85 | adapter->scan_processing = false; | ||
86 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, | ||
87 | flags); | ||
88 | |||
89 | if (priv->user_scan_cfg) { | ||
90 | dev_dbg(priv->adapter->dev, | ||
91 | "info: %s: scan aborted\n", __func__); | ||
92 | cfg80211_scan_done(priv->scan_request, 1); | ||
93 | priv->scan_request = NULL; | ||
94 | kfree(priv->user_scan_cfg); | ||
95 | priv->user_scan_cfg = NULL; | ||
96 | } | ||
97 | } else { | ||
98 | /* | ||
99 | * Tx data queue is still not empty, delay scan | ||
100 | * operation further by 20msec. | ||
101 | */ | ||
102 | mod_timer(&priv->scan_delay_timer, jiffies + | ||
103 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); | ||
104 | adapter->scan_delay_cnt++; | ||
105 | } | ||
106 | } else { | ||
107 | /* | ||
108 | * Tx data queue is empty. Get scan command from scan_pending_q | ||
109 | * and put to cmd_pending_q to resume scan operation | ||
110 | */ | ||
111 | adapter->scan_delay_cnt = 0; | ||
112 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | ||
113 | cmd_node = list_first_entry(&adapter->scan_pending_q, | ||
114 | struct cmd_ctrl_node, list); | ||
115 | list_del(&cmd_node->list); | ||
116 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | ||
117 | |||
118 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); | ||
119 | } | ||
120 | } | ||
121 | |||
60 | /* | 122 | /* |
61 | * This function initializes the private structure and sets default | 123 | * This function initializes the private structure and sets default |
62 | * values to the members. | 124 | * values to the members. |
@@ -136,6 +198,9 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) | |||
136 | 198 | ||
137 | priv->scan_block = false; | 199 | priv->scan_block = false; |
138 | 200 | ||
201 | setup_timer(&priv->scan_delay_timer, scan_delay_timer_fn, | ||
202 | (unsigned long)priv); | ||
203 | |||
139 | return mwifiex_add_bss_prio_tbl(priv); | 204 | return mwifiex_add_bss_prio_tbl(priv); |
140 | } | 205 | } |
141 | 206 | ||
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index d6b4fb04011f..82e63cee1e97 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -1349,22 +1349,16 @@ static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac) | |||
1349 | { | 1349 | { |
1350 | u8 mac_address[ETH_ALEN]; | 1350 | u8 mac_address[ETH_ALEN]; |
1351 | int ret; | 1351 | int ret; |
1352 | u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; | ||
1353 | 1352 | ||
1354 | if (mac) { | 1353 | if (!mac || is_zero_ether_addr(mac)) |
1355 | if (!memcmp(mac, zero_mac, sizeof(zero_mac))) | 1354 | memcpy(mac_address, |
1356 | memcpy((u8 *) &mac_address, | 1355 | priv->curr_bss_params.bss_descriptor.mac_address, |
1357 | (u8 *) &priv->curr_bss_params.bss_descriptor. | 1356 | ETH_ALEN); |
1358 | mac_address, ETH_ALEN); | 1357 | else |
1359 | else | 1358 | memcpy(mac_address, mac, ETH_ALEN); |
1360 | memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN); | ||
1361 | } else { | ||
1362 | memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params. | ||
1363 | bss_descriptor.mac_address, ETH_ALEN); | ||
1364 | } | ||
1365 | 1359 | ||
1366 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, | 1360 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE, |
1367 | HostCmd_ACT_GEN_SET, 0, &mac_address); | 1361 | HostCmd_ACT_GEN_SET, 0, mac_address); |
1368 | 1362 | ||
1369 | return ret; | 1363 | return ret; |
1370 | } | 1364 | } |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 3192855c31c0..0f06f07a70e6 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -244,8 +244,8 @@ process_start: | |||
244 | } | 244 | } |
245 | } | 245 | } |
246 | 246 | ||
247 | if (!adapter->scan_processing && !adapter->data_sent && | 247 | if ((!adapter->scan_processing || adapter->scan_delay_cnt) && |
248 | !mwifiex_wmm_lists_empty(adapter)) { | 248 | !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { |
249 | mwifiex_wmm_process_tx(adapter); | 249 | mwifiex_wmm_process_tx(adapter); |
250 | if (adapter->hs_activated) { | 250 | if (adapter->hs_activated) { |
251 | adapter->is_hs_configured = false; | 251 | adapter->is_hs_configured = false; |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index bd3b0bf94b9e..5b32221077c4 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -79,14 +79,17 @@ enum { | |||
79 | 79 | ||
80 | #define SCAN_BEACON_ENTRY_PAD 6 | 80 | #define SCAN_BEACON_ENTRY_PAD 6 |
81 | 81 | ||
82 | #define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 200 | 82 | #define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110 |
83 | #define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 200 | 83 | #define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30 |
84 | #define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 110 | 84 | #define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30 |
85 | 85 | ||
86 | #define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) | 86 | #define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) |
87 | 87 | ||
88 | #define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) | 88 | #define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) |
89 | 89 | ||
90 | #define MWIFIEX_MAX_SCAN_DELAY_CNT 50 | ||
91 | #define MWIFIEX_SCAN_DELAY_MSEC 20 | ||
92 | |||
90 | #define RSN_GTK_OUI_OFFSET 2 | 93 | #define RSN_GTK_OUI_OFFSET 2 |
91 | 94 | ||
92 | #define MWIFIEX_OUI_NOT_PRESENT 0 | 95 | #define MWIFIEX_OUI_NOT_PRESENT 0 |
@@ -482,6 +485,7 @@ struct mwifiex_private { | |||
482 | u16 proberesp_idx; | 485 | u16 proberesp_idx; |
483 | u16 assocresp_idx; | 486 | u16 assocresp_idx; |
484 | u16 rsn_idx; | 487 | u16 rsn_idx; |
488 | struct timer_list scan_delay_timer; | ||
485 | }; | 489 | }; |
486 | 490 | ||
487 | enum mwifiex_ba_status { | 491 | enum mwifiex_ba_status { |
@@ -686,6 +690,7 @@ struct mwifiex_adapter { | |||
686 | struct completion fw_load; | 690 | struct completion fw_load; |
687 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; | 691 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; |
688 | u16 max_mgmt_ie_index; | 692 | u16 max_mgmt_ie_index; |
693 | u8 scan_delay_cnt; | ||
689 | }; | 694 | }; |
690 | 695 | ||
691 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); | 696 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 74f045715723..98c6aabd5a48 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -28,7 +28,10 @@ | |||
28 | /* The maximum number of channels the firmware can scan per command */ | 28 | /* The maximum number of channels the firmware can scan per command */ |
29 | #define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14 | 29 | #define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14 |
30 | 30 | ||
31 | #define MWIFIEX_CHANNELS_PER_SCAN_CMD 4 | 31 | #define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD 4 |
32 | #define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD 15 | ||
33 | #define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD 27 | ||
34 | #define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD 35 | ||
32 | 35 | ||
33 | /* Memory needed to store a max sized Channel List TLV for a firmware scan */ | 36 | /* Memory needed to store a max sized Channel List TLV for a firmware scan */ |
34 | #define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \ | 37 | #define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \ |
@@ -471,7 +474,7 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, | |||
471 | * This routine is used for any scan that is not provided with a | 474 | * This routine is used for any scan that is not provided with a |
472 | * specific channel list to scan. | 475 | * specific channel list to scan. |
473 | */ | 476 | */ |
474 | static void | 477 | static int |
475 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | 478 | mwifiex_scan_create_channel_list(struct mwifiex_private *priv, |
476 | const struct mwifiex_user_scan_cfg | 479 | const struct mwifiex_user_scan_cfg |
477 | *user_scan_in, | 480 | *user_scan_in, |
@@ -528,6 +531,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, | |||
528 | } | 531 | } |
529 | 532 | ||
530 | } | 533 | } |
534 | return chan_idx; | ||
531 | } | 535 | } |
532 | 536 | ||
533 | /* | 537 | /* |
@@ -727,6 +731,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
727 | u32 num_probes; | 731 | u32 num_probes; |
728 | u32 ssid_len; | 732 | u32 ssid_len; |
729 | u32 chan_idx; | 733 | u32 chan_idx; |
734 | u32 chan_num; | ||
730 | u32 scan_type; | 735 | u32 scan_type; |
731 | u16 scan_dur; | 736 | u16 scan_dur; |
732 | u8 channel; | 737 | u8 channel; |
@@ -850,7 +855,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
850 | if (*filtered_scan) | 855 | if (*filtered_scan) |
851 | *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; | 856 | *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; |
852 | else | 857 | else |
853 | *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD; | 858 | *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; |
854 | 859 | ||
855 | /* If the input config or adapter has the number of Probes set, | 860 | /* If the input config or adapter has the number of Probes set, |
856 | add tlv */ | 861 | add tlv */ |
@@ -962,13 +967,28 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
962 | dev_dbg(adapter->dev, | 967 | dev_dbg(adapter->dev, |
963 | "info: Scan: Scanning current channel only\n"); | 968 | "info: Scan: Scanning current channel only\n"); |
964 | } | 969 | } |
965 | 970 | chan_num = chan_idx; | |
966 | } else { | 971 | } else { |
967 | dev_dbg(adapter->dev, | 972 | dev_dbg(adapter->dev, |
968 | "info: Scan: Creating full region channel list\n"); | 973 | "info: Scan: Creating full region channel list\n"); |
969 | mwifiex_scan_create_channel_list(priv, user_scan_in, | 974 | chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in, |
970 | scan_chan_list, | 975 | scan_chan_list, |
971 | *filtered_scan); | 976 | *filtered_scan); |
977 | } | ||
978 | |||
979 | /* | ||
980 | * In associated state we will reduce the number of channels scanned per | ||
981 | * scan command to avoid any traffic delay/loss. This number is decided | ||
982 | * based on total number of channels to be scanned due to constraints | ||
983 | * of command buffers. | ||
984 | */ | ||
985 | if (priv->media_connected) { | ||
986 | if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD) | ||
987 | *max_chan_per_scan = 1; | ||
988 | else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD) | ||
989 | *max_chan_per_scan = 2; | ||
990 | else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD) | ||
991 | *max_chan_per_scan = 3; | ||
972 | } | 992 | } |
973 | } | 993 | } |
974 | 994 | ||
@@ -1014,14 +1034,12 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, | |||
1014 | case TLV_TYPE_TSFTIMESTAMP: | 1034 | case TLV_TYPE_TSFTIMESTAMP: |
1015 | dev_dbg(adapter->dev, "info: SCAN_RESP: TSF " | 1035 | dev_dbg(adapter->dev, "info: SCAN_RESP: TSF " |
1016 | "timestamp TLV, len = %d\n", tlv_len); | 1036 | "timestamp TLV, len = %d\n", tlv_len); |
1017 | *tlv_data = (struct mwifiex_ie_types_data *) | 1037 | *tlv_data = current_tlv; |
1018 | current_tlv; | ||
1019 | break; | 1038 | break; |
1020 | case TLV_TYPE_CHANNELBANDLIST: | 1039 | case TLV_TYPE_CHANNELBANDLIST: |
1021 | dev_dbg(adapter->dev, "info: SCAN_RESP: channel" | 1040 | dev_dbg(adapter->dev, "info: SCAN_RESP: channel" |
1022 | " band list TLV, len = %d\n", tlv_len); | 1041 | " band list TLV, len = %d\n", tlv_len); |
1023 | *tlv_data = (struct mwifiex_ie_types_data *) | 1042 | *tlv_data = current_tlv; |
1024 | current_tlv; | ||
1025 | break; | 1043 | break; |
1026 | default: | 1044 | default: |
1027 | dev_err(adapter->dev, | 1045 | dev_err(adapter->dev, |
@@ -1226,15 +1244,15 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1226 | bss_entry->beacon_buf); | 1244 | bss_entry->beacon_buf); |
1227 | break; | 1245 | break; |
1228 | case WLAN_EID_BSS_COEX_2040: | 1246 | case WLAN_EID_BSS_COEX_2040: |
1229 | bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr + | 1247 | bss_entry->bcn_bss_co_2040 = current_ptr + |
1230 | sizeof(struct ieee_types_header)); | 1248 | sizeof(struct ieee_types_header); |
1231 | bss_entry->bss_co_2040_offset = (u16) (current_ptr + | 1249 | bss_entry->bss_co_2040_offset = (u16) (current_ptr + |
1232 | sizeof(struct ieee_types_header) - | 1250 | sizeof(struct ieee_types_header) - |
1233 | bss_entry->beacon_buf); | 1251 | bss_entry->beacon_buf); |
1234 | break; | 1252 | break; |
1235 | case WLAN_EID_EXT_CAPABILITY: | 1253 | case WLAN_EID_EXT_CAPABILITY: |
1236 | bss_entry->bcn_ext_cap = (u8 *) (current_ptr + | 1254 | bss_entry->bcn_ext_cap = current_ptr + |
1237 | sizeof(struct ieee_types_header)); | 1255 | sizeof(struct ieee_types_header); |
1238 | bss_entry->ext_cap_offset = (u16) (current_ptr + | 1256 | bss_entry->ext_cap_offset = (u16) (current_ptr + |
1239 | sizeof(struct ieee_types_header) - | 1257 | sizeof(struct ieee_types_header) - |
1240 | bss_entry->beacon_buf); | 1258 | bss_entry->beacon_buf); |
@@ -1683,8 +1701,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1683 | goto done; | 1701 | goto done; |
1684 | } | 1702 | } |
1685 | if (element_id == WLAN_EID_DS_PARAMS) { | 1703 | if (element_id == WLAN_EID_DS_PARAMS) { |
1686 | channel = *(u8 *) (current_ptr + | 1704 | channel = *(current_ptr + sizeof(struct ieee_types_header)); |
1687 | sizeof(struct ieee_types_header)); | ||
1688 | break; | 1705 | break; |
1689 | } | 1706 | } |
1690 | 1707 | ||
@@ -1772,14 +1789,23 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1772 | priv->user_scan_cfg = NULL; | 1789 | priv->user_scan_cfg = NULL; |
1773 | } | 1790 | } |
1774 | } else { | 1791 | } else { |
1775 | /* Get scan command from scan_pending_q and put to | 1792 | if (!mwifiex_wmm_lists_empty(adapter)) { |
1776 | cmd_pending_q */ | 1793 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, |
1777 | cmd_node = list_first_entry(&adapter->scan_pending_q, | 1794 | flags); |
1778 | struct cmd_ctrl_node, list); | 1795 | adapter->scan_delay_cnt = 1; |
1779 | list_del(&cmd_node->list); | 1796 | mod_timer(&priv->scan_delay_timer, jiffies + |
1780 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 1797 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); |
1781 | 1798 | } else { | |
1782 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); | 1799 | /* Get scan command from scan_pending_q and put to |
1800 | cmd_pending_q */ | ||
1801 | cmd_node = list_first_entry(&adapter->scan_pending_q, | ||
1802 | struct cmd_ctrl_node, list); | ||
1803 | list_del(&cmd_node->list); | ||
1804 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | ||
1805 | flags); | ||
1806 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, | ||
1807 | true); | ||
1808 | } | ||
1783 | } | 1809 | } |
1784 | 1810 | ||
1785 | done: | 1811 | done: |
@@ -2010,12 +2036,11 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
2010 | 2036 | ||
2011 | if (curr_bss->bcn_bss_co_2040) | 2037 | if (curr_bss->bcn_bss_co_2040) |
2012 | curr_bss->bcn_bss_co_2040 = | 2038 | curr_bss->bcn_bss_co_2040 = |
2013 | (u8 *) (curr_bss->beacon_buf + | 2039 | (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset); |
2014 | curr_bss->bss_co_2040_offset); | ||
2015 | 2040 | ||
2016 | if (curr_bss->bcn_ext_cap) | 2041 | if (curr_bss->bcn_ext_cap) |
2017 | curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf + | 2042 | curr_bss->bcn_ext_cap = curr_bss->beacon_buf + |
2018 | curr_bss->ext_cap_offset); | 2043 | curr_bss->ext_cap_offset; |
2019 | } | 2044 | } |
2020 | 2045 | ||
2021 | /* | 2046 | /* |
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 40e025da6bc2..1ff1362d8cdf 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -793,8 +793,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
793 | struct host_cmd_ds_mac_reg_access *mac_reg; | 793 | struct host_cmd_ds_mac_reg_access *mac_reg; |
794 | 794 | ||
795 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); | 795 | cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); |
796 | mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> | 796 | mac_reg = &cmd->params.mac_reg; |
797 | params.mac_reg; | ||
798 | mac_reg->action = cpu_to_le16(cmd_action); | 797 | mac_reg->action = cpu_to_le16(cmd_action); |
799 | mac_reg->offset = | 798 | mac_reg->offset = |
800 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 799 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -806,8 +805,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
806 | struct host_cmd_ds_bbp_reg_access *bbp_reg; | 805 | struct host_cmd_ds_bbp_reg_access *bbp_reg; |
807 | 806 | ||
808 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); | 807 | cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); |
809 | bbp_reg = (struct host_cmd_ds_bbp_reg_access *) | 808 | bbp_reg = &cmd->params.bbp_reg; |
810 | &cmd->params.bbp_reg; | ||
811 | bbp_reg->action = cpu_to_le16(cmd_action); | 809 | bbp_reg->action = cpu_to_le16(cmd_action); |
812 | bbp_reg->offset = | 810 | bbp_reg->offset = |
813 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 811 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -819,8 +817,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
819 | struct host_cmd_ds_rf_reg_access *rf_reg; | 817 | struct host_cmd_ds_rf_reg_access *rf_reg; |
820 | 818 | ||
821 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); | 819 | cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); |
822 | rf_reg = (struct host_cmd_ds_rf_reg_access *) | 820 | rf_reg = &cmd->params.rf_reg; |
823 | &cmd->params.rf_reg; | ||
824 | rf_reg->action = cpu_to_le16(cmd_action); | 821 | rf_reg->action = cpu_to_le16(cmd_action); |
825 | rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 822 | rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
826 | rf_reg->value = (u8) le32_to_cpu(reg_rw->value); | 823 | rf_reg->value = (u8) le32_to_cpu(reg_rw->value); |
@@ -831,8 +828,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
831 | struct host_cmd_ds_pmic_reg_access *pmic_reg; | 828 | struct host_cmd_ds_pmic_reg_access *pmic_reg; |
832 | 829 | ||
833 | cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); | 830 | cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN); |
834 | pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd-> | 831 | pmic_reg = &cmd->params.pmic_reg; |
835 | params.pmic_reg; | ||
836 | pmic_reg->action = cpu_to_le16(cmd_action); | 832 | pmic_reg->action = cpu_to_le16(cmd_action); |
837 | pmic_reg->offset = | 833 | pmic_reg->offset = |
838 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 834 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -844,8 +840,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
844 | struct host_cmd_ds_rf_reg_access *cau_reg; | 840 | struct host_cmd_ds_rf_reg_access *cau_reg; |
845 | 841 | ||
846 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); | 842 | cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); |
847 | cau_reg = (struct host_cmd_ds_rf_reg_access *) | 843 | cau_reg = &cmd->params.rf_reg; |
848 | &cmd->params.rf_reg; | ||
849 | cau_reg->action = cpu_to_le16(cmd_action); | 844 | cau_reg->action = cpu_to_le16(cmd_action); |
850 | cau_reg->offset = | 845 | cau_reg->offset = |
851 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); | 846 | cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); |
@@ -856,7 +851,6 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, | |||
856 | { | 851 | { |
857 | struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; | 852 | struct mwifiex_ds_read_eeprom *rd_eeprom = data_buf; |
858 | struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = | 853 | struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom = |
859 | (struct host_cmd_ds_802_11_eeprom_access *) | ||
860 | &cmd->params.eeprom; | 854 | &cmd->params.eeprom; |
861 | 855 | ||
862 | cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); | 856 | cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN); |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index a79ed9bd9695..bd40541ebd5a 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -227,7 +227,7 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, | |||
227 | struct mwifiex_ds_get_stats *stats) | 227 | struct mwifiex_ds_get_stats *stats) |
228 | { | 228 | { |
229 | struct host_cmd_ds_802_11_get_log *get_log = | 229 | struct host_cmd_ds_802_11_get_log *get_log = |
230 | (struct host_cmd_ds_802_11_get_log *) &resp->params.get_log; | 230 | &resp->params.get_log; |
231 | 231 | ||
232 | if (stats) { | 232 | if (stats) { |
233 | stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); | 233 | stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame); |
@@ -282,7 +282,7 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
282 | u32 i; | 282 | u32 i; |
283 | int ret = 0; | 283 | int ret = 0; |
284 | 284 | ||
285 | tlv_buf = (u8 *) ((u8 *) rate_cfg) + | 285 | tlv_buf = ((u8 *)rate_cfg) + |
286 | sizeof(struct host_cmd_ds_tx_rate_cfg); | 286 | sizeof(struct host_cmd_ds_tx_rate_cfg); |
287 | tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16)); | 287 | tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16)); |
288 | 288 | ||
@@ -679,39 +679,33 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, | |||
679 | eeprom = data_buf; | 679 | eeprom = data_buf; |
680 | switch (type) { | 680 | switch (type) { |
681 | case HostCmd_CMD_MAC_REG_ACCESS: | 681 | case HostCmd_CMD_MAC_REG_ACCESS: |
682 | r.mac = (struct host_cmd_ds_mac_reg_access *) | 682 | r.mac = &resp->params.mac_reg; |
683 | &resp->params.mac_reg; | ||
684 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); | 683 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); |
685 | reg_rw->value = r.mac->value; | 684 | reg_rw->value = r.mac->value; |
686 | break; | 685 | break; |
687 | case HostCmd_CMD_BBP_REG_ACCESS: | 686 | case HostCmd_CMD_BBP_REG_ACCESS: |
688 | r.bbp = (struct host_cmd_ds_bbp_reg_access *) | 687 | r.bbp = &resp->params.bbp_reg; |
689 | &resp->params.bbp_reg; | ||
690 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); | 688 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); |
691 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); | 689 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); |
692 | break; | 690 | break; |
693 | 691 | ||
694 | case HostCmd_CMD_RF_REG_ACCESS: | 692 | case HostCmd_CMD_RF_REG_ACCESS: |
695 | r.rf = (struct host_cmd_ds_rf_reg_access *) | 693 | r.rf = &resp->params.rf_reg; |
696 | &resp->params.rf_reg; | ||
697 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); | 694 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); |
698 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); | 695 | reg_rw->value = cpu_to_le32((u32) r.bbp->value); |
699 | break; | 696 | break; |
700 | case HostCmd_CMD_PMIC_REG_ACCESS: | 697 | case HostCmd_CMD_PMIC_REG_ACCESS: |
701 | r.pmic = (struct host_cmd_ds_pmic_reg_access *) | 698 | r.pmic = &resp->params.pmic_reg; |
702 | &resp->params.pmic_reg; | ||
703 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); | 699 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); |
704 | reg_rw->value = cpu_to_le32((u32) r.pmic->value); | 700 | reg_rw->value = cpu_to_le32((u32) r.pmic->value); |
705 | break; | 701 | break; |
706 | case HostCmd_CMD_CAU_REG_ACCESS: | 702 | case HostCmd_CMD_CAU_REG_ACCESS: |
707 | r.rf = (struct host_cmd_ds_rf_reg_access *) | 703 | r.rf = &resp->params.rf_reg; |
708 | &resp->params.rf_reg; | ||
709 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); | 704 | reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); |
710 | reg_rw->value = cpu_to_le32((u32) r.rf->value); | 705 | reg_rw->value = cpu_to_le32((u32) r.rf->value); |
711 | break; | 706 | break; |
712 | case HostCmd_CMD_802_11_EEPROM_ACCESS: | 707 | case HostCmd_CMD_802_11_EEPROM_ACCESS: |
713 | r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) | 708 | r.eeprom = &resp->params.eeprom; |
714 | &resp->params.eeprom; | ||
715 | pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); | 709 | pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); |
716 | if (le16_to_cpu(eeprom->byte_count) < | 710 | if (le16_to_cpu(eeprom->byte_count) < |
717 | le16_to_cpu(r.eeprom->byte_count)) { | 711 | le16_to_cpu(r.eeprom->byte_count)) { |
@@ -787,7 +781,7 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv, | |||
787 | struct mwifiex_ds_misc_subsc_evt *sub_event) | 781 | struct mwifiex_ds_misc_subsc_evt *sub_event) |
788 | { | 782 | { |
789 | struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event = | 783 | struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event = |
790 | (struct host_cmd_ds_802_11_subsc_evt *)&resp->params.subsc_evt; | 784 | &resp->params.subsc_evt; |
791 | 785 | ||
792 | /* For every subscribe event command (Get/Set/Clear), FW reports the | 786 | /* For every subscribe event command (Get/Set/Clear), FW reports the |
793 | * current set of subscribed events*/ | 787 | * current set of subscribed events*/ |
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 4ace5a3dcd23..e8b27c305367 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -422,7 +422,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
422 | 422 | ||
423 | if (len != -1) { | 423 | if (len != -1) { |
424 | sinfo.filled = STATION_INFO_ASSOC_REQ_IES; | 424 | sinfo.filled = STATION_INFO_ASSOC_REQ_IES; |
425 | sinfo.assoc_req_ies = (u8 *)&event->data[len]; | 425 | sinfo.assoc_req_ies = &event->data[len]; |
426 | len = (u8 *)sinfo.assoc_req_ies - | 426 | len = (u8 *)sinfo.assoc_req_ies - |
427 | (u8 *)&event->frame_control; | 427 | (u8 *)&event->frame_control; |
428 | sinfo.assoc_req_ies_len = | 428 | sinfo.assoc_req_ies_len = |
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index f7b15b8934fa..e15675585fb1 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c | |||
@@ -160,10 +160,9 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev, | |||
160 | return err; | 160 | return err; |
161 | } | 161 | } |
162 | 162 | ||
163 | static int orinoco_set_channel(struct wiphy *wiphy, | 163 | static int orinoco_set_monitor_channel(struct wiphy *wiphy, |
164 | struct net_device *netdev, | 164 | struct ieee80211_channel *chan, |
165 | struct ieee80211_channel *chan, | 165 | enum nl80211_channel_type channel_type) |
166 | enum nl80211_channel_type channel_type) | ||
167 | { | 166 | { |
168 | struct orinoco_private *priv = wiphy_priv(wiphy); | 167 | struct orinoco_private *priv = wiphy_priv(wiphy); |
169 | int err = 0; | 168 | int err = 0; |
@@ -286,7 +285,7 @@ static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
286 | 285 | ||
287 | const struct cfg80211_ops orinoco_cfg_ops = { | 286 | const struct cfg80211_ops orinoco_cfg_ops = { |
288 | .change_virtual_intf = orinoco_change_vif, | 287 | .change_virtual_intf = orinoco_change_vif, |
289 | .set_channel = orinoco_set_channel, | 288 | .set_monitor_channel = orinoco_set_monitor_channel, |
290 | .scan = orinoco_scan, | 289 | .scan = orinoco_scan, |
291 | .set_wiphy_params = orinoco_set_wiphy_params, | 290 | .set_wiphy_params = orinoco_set_wiphy_params, |
292 | }; | 291 | }; |
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index fa8ce5104781..636daf2860cc 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -905,7 +905,7 @@ int p54_read_eeprom(struct ieee80211_hw *dev) | |||
905 | 905 | ||
906 | while (eeprom_size) { | 906 | while (eeprom_size) { |
907 | blocksize = min(eeprom_size, maxblocksize); | 907 | blocksize = min(eeprom_size, maxblocksize); |
908 | ret = p54_download_eeprom(priv, (void *) (eeprom + offset), | 908 | ret = p54_download_eeprom(priv, eeprom + offset, |
909 | offset, blocksize); | 909 | offset, blocksize); |
910 | if (unlikely(ret)) | 910 | if (unlikely(ret)) |
911 | goto free; | 911 | goto free; |
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 18e82b31afa6..9ba85106eec0 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -478,7 +478,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
478 | 478 | ||
479 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { | 479 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { |
480 | memcpy(&body->longbow.curve_data, | 480 | memcpy(&body->longbow.curve_data, |
481 | (void *) entry + sizeof(__le16), | 481 | entry + sizeof(__le16), |
482 | priv->curve_data->entry_size); | 482 | priv->curve_data->entry_size); |
483 | } else { | 483 | } else { |
484 | struct p54_scan_body *chan = &body->normal; | 484 | struct p54_scan_body *chan = &body->normal; |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 266d45bf86f5..799e148d0370 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -455,7 +455,7 @@ islpci_eth_receive(islpci_private *priv) | |||
455 | "Error mapping DMA address\n"); | 455 | "Error mapping DMA address\n"); |
456 | 456 | ||
457 | /* free the skbuf structure before aborting */ | 457 | /* free the skbuf structure before aborting */ |
458 | dev_kfree_skb_irq((struct sk_buff *) skb); | 458 | dev_kfree_skb_irq(skb); |
459 | skb = NULL; | 459 | skb = NULL; |
460 | break; | 460 | break; |
461 | } | 461 | } |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 86a738bf591c..598ca1cafb95 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -1849,7 +1849,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) | |||
1849 | pr_debug("ray_cs: interrupt for *dev=%p\n", dev); | 1849 | pr_debug("ray_cs: interrupt for *dev=%p\n", dev); |
1850 | 1850 | ||
1851 | local = netdev_priv(dev); | 1851 | local = netdev_priv(dev); |
1852 | link = (struct pcmcia_device *)local->finder; | 1852 | link = local->finder; |
1853 | if (!pcmcia_dev_present(link)) { | 1853 | if (!pcmcia_dev_present(link)) { |
1854 | pr_debug( | 1854 | pr_debug( |
1855 | "ray_cs interrupt from device not present or suspended.\n"); | 1855 | "ray_cs interrupt from device not present or suspended.\n"); |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 9348521e0832..1ca88cdc6ece 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -51,6 +51,7 @@ | |||
51 | * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) | 51 | * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) |
52 | * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) | 52 | * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) |
53 | * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) | 53 | * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) |
54 | * RF5360 2.4G 1T1R | ||
54 | * RF5370 2.4G 1T1R | 55 | * RF5370 2.4G 1T1R |
55 | * RF5390 2.4G 1T1R | 56 | * RF5390 2.4G 1T1R |
56 | */ | 57 | */ |
@@ -67,9 +68,11 @@ | |||
67 | #define RF3320 0x000b | 68 | #define RF3320 0x000b |
68 | #define RF3322 0x000c | 69 | #define RF3322 0x000c |
69 | #define RF3053 0x000d | 70 | #define RF3053 0x000d |
71 | #define RF5360 0x5360 | ||
70 | #define RF5370 0x5370 | 72 | #define RF5370 0x5370 |
71 | #define RF5372 0x5372 | 73 | #define RF5372 0x5372 |
72 | #define RF5390 0x5390 | 74 | #define RF5390 0x5390 |
75 | #define RF5392 0x5392 | ||
73 | 76 | ||
74 | /* | 77 | /* |
75 | * Chipset revisions. | 78 | * Chipset revisions. |
@@ -1944,6 +1947,11 @@ struct mac_iveiv_entry { | |||
1944 | #define RFCSR49_TX FIELD8(0x3f) | 1947 | #define RFCSR49_TX FIELD8(0x3f) |
1945 | 1948 | ||
1946 | /* | 1949 | /* |
1950 | * RFCSR 50: | ||
1951 | */ | ||
1952 | #define RFCSR50_TX FIELD8(0x3f) | ||
1953 | |||
1954 | /* | ||
1947 | * RF registers | 1955 | * RF registers |
1948 | */ | 1956 | */ |
1949 | 1957 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index dfc90d34be6d..4d3747c3010b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -1958,7 +1958,22 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | |||
1958 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | 1958 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); |
1959 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | 1959 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); |
1960 | 1960 | ||
1961 | if (rt2x00_rt(rt2x00dev, RT5392)) { | ||
1962 | rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); | ||
1963 | if (info->default_power1 > RT5390_POWER_BOUND) | ||
1964 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, | ||
1965 | RT5390_POWER_BOUND); | ||
1966 | else | ||
1967 | rt2x00_set_field8(&rfcsr, RFCSR50_TX, | ||
1968 | info->default_power2); | ||
1969 | rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); | ||
1970 | } | ||
1971 | |||
1961 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | 1972 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); |
1973 | if (rt2x00_rt(rt2x00dev, RT5392)) { | ||
1974 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); | ||
1975 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); | ||
1976 | } | ||
1962 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | 1977 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); |
1963 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); | 1978 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); |
1964 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | 1979 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); |
@@ -2060,9 +2075,11 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
2060 | case RF3052: | 2075 | case RF3052: |
2061 | rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); | 2076 | rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); |
2062 | break; | 2077 | break; |
2078 | case RF5360: | ||
2063 | case RF5370: | 2079 | case RF5370: |
2064 | case RF5372: | 2080 | case RF5372: |
2065 | case RF5390: | 2081 | case RF5390: |
2082 | case RF5392: | ||
2066 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | 2083 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); |
2067 | break; | 2084 | break; |
2068 | default: | 2085 | default: |
@@ -2549,9 +2566,11 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) | |||
2549 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); | 2566 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); |
2550 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); | 2567 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); |
2551 | break; | 2568 | break; |
2569 | case RF5360: | ||
2552 | case RF5370: | 2570 | case RF5370: |
2553 | case RF5372: | 2571 | case RF5372: |
2554 | case RF5390: | 2572 | case RF5390: |
2573 | case RF5392: | ||
2555 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | 2574 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); |
2556 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | 2575 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); |
2557 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | 2576 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); |
@@ -4263,9 +4282,11 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
4263 | case RF3022: | 4282 | case RF3022: |
4264 | case RF3052: | 4283 | case RF3052: |
4265 | case RF3320: | 4284 | case RF3320: |
4285 | case RF5360: | ||
4266 | case RF5370: | 4286 | case RF5370: |
4267 | case RF5372: | 4287 | case RF5372: |
4268 | case RF5390: | 4288 | case RF5390: |
4289 | case RF5392: | ||
4269 | break; | 4290 | break; |
4270 | default: | 4291 | default: |
4271 | ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", | 4292 | ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", |
@@ -4577,9 +4598,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
4577 | rt2x00_rf(rt2x00dev, RF3021) || | 4598 | rt2x00_rf(rt2x00dev, RF3021) || |
4578 | rt2x00_rf(rt2x00dev, RF3022) || | 4599 | rt2x00_rf(rt2x00dev, RF3022) || |
4579 | rt2x00_rf(rt2x00dev, RF3320) || | 4600 | rt2x00_rf(rt2x00dev, RF3320) || |
4601 | rt2x00_rf(rt2x00dev, RF5360) || | ||
4580 | rt2x00_rf(rt2x00dev, RF5370) || | 4602 | rt2x00_rf(rt2x00dev, RF5370) || |
4581 | rt2x00_rf(rt2x00dev, RF5372) || | 4603 | rt2x00_rf(rt2x00dev, RF5372) || |
4582 | rt2x00_rf(rt2x00dev, RF5390)) { | 4604 | rt2x00_rf(rt2x00dev, RF5390) || |
4605 | rt2x00_rf(rt2x00dev, RF5392)) { | ||
4583 | spec->num_channels = 14; | 4606 | spec->num_channels = 14; |
4584 | spec->channels = rf_vals_3x; | 4607 | spec->channels = rf_vals_3x; |
4585 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { | 4608 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { |
@@ -4662,9 +4685,11 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
4662 | case RF3022: | 4685 | case RF3022: |
4663 | case RF3320: | 4686 | case RF3320: |
4664 | case RF3052: | 4687 | case RF3052: |
4688 | case RF5360: | ||
4665 | case RF5370: | 4689 | case RF5370: |
4666 | case RF5372: | 4690 | case RF5372: |
4667 | case RF5390: | 4691 | case RF5390: |
4692 | case RF5392: | ||
4668 | __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); | 4693 | __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); |
4669 | break; | 4694 | break; |
4670 | } | 4695 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index cad25bfebd7a..206158b67426 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -1188,6 +1188,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
1188 | { PCI_DEVICE(0x1814, 0x3593) }, | 1188 | { PCI_DEVICE(0x1814, 0x3593) }, |
1189 | #endif | 1189 | #endif |
1190 | #ifdef CONFIG_RT2800PCI_RT53XX | 1190 | #ifdef CONFIG_RT2800PCI_RT53XX |
1191 | { PCI_DEVICE(0x1814, 0x5360) }, | ||
1191 | { PCI_DEVICE(0x1814, 0x5362) }, | 1192 | { PCI_DEVICE(0x1814, 0x5362) }, |
1192 | { PCI_DEVICE(0x1814, 0x5390) }, | 1193 | { PCI_DEVICE(0x1814, 0x5390) }, |
1193 | { PCI_DEVICE(0x1814, 0x5392) }, | 1194 | { PCI_DEVICE(0x1814, 0x5392) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index bf78317a6adb..20a504072895 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1137,6 +1137,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1137 | #ifdef CONFIG_RT2800USB_RT33XX | 1137 | #ifdef CONFIG_RT2800USB_RT33XX |
1138 | /* Belkin */ | 1138 | /* Belkin */ |
1139 | { USB_DEVICE(0x050d, 0x945b) }, | 1139 | { USB_DEVICE(0x050d, 0x945b) }, |
1140 | /* D-Link */ | ||
1141 | { USB_DEVICE(0x2001, 0x3c17) }, | ||
1140 | /* Panasonic */ | 1142 | /* Panasonic */ |
1141 | { USB_DEVICE(0x083a, 0xb511) }, | 1143 | { USB_DEVICE(0x083a, 0xb511) }, |
1142 | /* Philips */ | 1144 | /* Philips */ |
@@ -1237,7 +1239,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1237 | /* D-Link */ | 1239 | /* D-Link */ |
1238 | { USB_DEVICE(0x07d1, 0x3c0b) }, | 1240 | { USB_DEVICE(0x07d1, 0x3c0b) }, |
1239 | { USB_DEVICE(0x07d1, 0x3c17) }, | 1241 | { USB_DEVICE(0x07d1, 0x3c17) }, |
1240 | { USB_DEVICE(0x2001, 0x3c17) }, | ||
1241 | /* Encore */ | 1242 | /* Encore */ |
1242 | { USB_DEVICE(0x203d, 0x14a1) }, | 1243 | { USB_DEVICE(0x203d, 0x14a1) }, |
1243 | /* Gemtek */ | 1244 | /* Gemtek */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index e5404e576251..a6b88bd4a1a5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1161,6 +1161,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1161 | BIT(NL80211_IFTYPE_MESH_POINT) | | 1161 | BIT(NL80211_IFTYPE_MESH_POINT) | |
1162 | BIT(NL80211_IFTYPE_WDS); | 1162 | BIT(NL80211_IFTYPE_WDS); |
1163 | 1163 | ||
1164 | rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | ||
1165 | |||
1164 | /* | 1166 | /* |
1165 | * Initialize work. | 1167 | * Initialize work. |
1166 | */ | 1168 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index dd24b2663b5e..4ff26c2159bf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -506,9 +506,19 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
506 | 506 | ||
507 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 507 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
508 | return 0; | 508 | return 0; |
509 | else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) | 509 | |
510 | if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) | ||
511 | return -EOPNOTSUPP; | ||
512 | |||
513 | /* | ||
514 | * To support IBSS RSN, don't program group keys in IBSS, the | ||
515 | * hardware will then not attempt to decrypt the frames. | ||
516 | */ | ||
517 | if (vif->type == NL80211_IFTYPE_ADHOC && | ||
518 | !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
510 | return -EOPNOTSUPP; | 519 | return -EOPNOTSUPP; |
511 | else if (key->keylen > 32) | 520 | |
521 | if (key->keylen > 32) | ||
512 | return -ENOSPC; | 522 | return -ENOSPC; |
513 | 523 | ||
514 | memset(&crypto, 0, sizeof(crypto)); | 524 | memset(&crypto, 0, sizeof(crypto)); |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index f4c852c6749b..58e1f7bb4df1 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -907,7 +907,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
907 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); | 907 | struct ieee80211_hdr *hdr = rtl_get_hdr(skb); |
908 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 908 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
909 | __le16 fc = hdr->frame_control; | 909 | __le16 fc = hdr->frame_control; |
910 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); | 910 | u8 *act = (u8 *)skb->data + MAC80211_3ADDR_LEN; |
911 | u8 category; | 911 | u8 category; |
912 | 912 | ||
913 | if (!ieee80211_is_action(fc)) | 913 | if (!ieee80211_is_action(fc)) |
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 3d8cc4a0c86d..2d1a8220d5c0 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c | |||
@@ -146,7 +146,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, | |||
146 | } | 146 | } |
147 | 147 | ||
148 | rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, | 148 | rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, |
149 | (u8 *) key_content, us_config); | 149 | key_content, us_config); |
150 | 150 | ||
151 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); | 151 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); |
152 | 152 | ||
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 278e9f957e0d..a18ad2a98938 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -680,7 +680,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
680 | 680 | ||
681 | mac->short_preamble = bss_conf->use_short_preamble; | 681 | mac->short_preamble = bss_conf->use_short_preamble; |
682 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, | 682 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, |
683 | (u8 *) (&mac->short_preamble)); | 683 | &mac->short_preamble); |
684 | } | 684 | } |
685 | 685 | ||
686 | if (changed & BSS_CHANGED_ERP_SLOT) { | 686 | if (changed & BSS_CHANGED_ERP_SLOT) { |
@@ -693,7 +693,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
693 | mac->slot_time = RTL_SLOT_TIME_20; | 693 | mac->slot_time = RTL_SLOT_TIME_20; |
694 | 694 | ||
695 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 695 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, |
696 | (u8 *) (&mac->slot_time)); | 696 | &mac->slot_time); |
697 | } | 697 | } |
698 | 698 | ||
699 | if (changed & BSS_CHANGED_HT) { | 699 | if (changed & BSS_CHANGED_HT) { |
@@ -713,7 +713,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
713 | rcu_read_unlock(); | 713 | rcu_read_unlock(); |
714 | 714 | ||
715 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, | 715 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SHORTGI_DENSITY, |
716 | (u8 *) (&mac->max_mss_density)); | 716 | &mac->max_mss_density); |
717 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, | 717 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_FACTOR, |
718 | &mac->current_ampdu_factor); | 718 | &mac->current_ampdu_factor); |
719 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, | 719 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AMPDU_MIN_SPACE, |
@@ -801,7 +801,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
801 | u8 mstatus = RT_MEDIA_CONNECT; | 801 | u8 mstatus = RT_MEDIA_CONNECT; |
802 | rtlpriv->cfg->ops->set_hw_reg(hw, | 802 | rtlpriv->cfg->ops->set_hw_reg(hw, |
803 | HW_VAR_H2C_FW_JOINBSSRPT, | 803 | HW_VAR_H2C_FW_JOINBSSRPT, |
804 | (u8 *) (&mstatus)); | 804 | &mstatus); |
805 | ppsc->report_linked = true; | 805 | ppsc->report_linked = true; |
806 | } | 806 | } |
807 | } else { | 807 | } else { |
@@ -809,7 +809,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
809 | u8 mstatus = RT_MEDIA_DISCONNECT; | 809 | u8 mstatus = RT_MEDIA_DISCONNECT; |
810 | rtlpriv->cfg->ops->set_hw_reg(hw, | 810 | rtlpriv->cfg->ops->set_hw_reg(hw, |
811 | HW_VAR_H2C_FW_JOINBSSRPT, | 811 | HW_VAR_H2C_FW_JOINBSSRPT, |
812 | (u8 *)(&mstatus)); | 812 | &mstatus); |
813 | ppsc->report_linked = false; | 813 | ppsc->report_linked = false; |
814 | } | 814 | } |
815 | } | 815 | } |
@@ -836,7 +836,7 @@ static void rtl_op_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
836 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; | 836 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; |
837 | 837 | ||
838 | mac->tsf = tsf; | 838 | mac->tsf = tsf; |
839 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss)); | 839 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, &bibss); |
840 | } | 840 | } |
841 | 841 | ||
842 | static void rtl_op_reset_tsf(struct ieee80211_hw *hw, | 842 | static void rtl_op_reset_tsf(struct ieee80211_hw *hw, |
@@ -845,7 +845,7 @@ static void rtl_op_reset_tsf(struct ieee80211_hw *hw, | |||
845 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 845 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
846 | u8 tmp = 0; | 846 | u8 tmp = 0; |
847 | 847 | ||
848 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, (u8 *) (&tmp)); | 848 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DUAL_TSF_RST, &tmp); |
849 | } | 849 | } |
850 | 850 | ||
851 | static void rtl_op_sta_notify(struct ieee80211_hw *hw, | 851 | static void rtl_op_sta_notify(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 1f143800a8d7..8e2f9afb125a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
@@ -352,7 +352,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) | |||
352 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, | 352 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES, |
353 | (u8 *)&efuse_utilized); | 353 | (u8 *)&efuse_utilized); |
354 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, | 354 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE, |
355 | (u8 *)&efuse_usage); | 355 | &efuse_usage); |
356 | done: | 356 | done: |
357 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) | 357 | for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) |
358 | kfree(efuse_word[i]); | 358 | kfree(efuse_word[i]); |
@@ -409,7 +409,7 @@ void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, | |||
409 | else if (type == 2) | 409 | else if (type == 2) |
410 | efuse_shadow_read_2byte(hw, offset, (u16 *) value); | 410 | efuse_shadow_read_2byte(hw, offset, (u16 *) value); |
411 | else if (type == 4) | 411 | else if (type == 4) |
412 | efuse_shadow_read_4byte(hw, offset, (u32 *) value); | 412 | efuse_shadow_read_4byte(hw, offset, value); |
413 | 413 | ||
414 | } | 414 | } |
415 | 415 | ||
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 2062ea1d7c80..82d3afcfecd1 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -756,10 +756,10 @@ done: | |||
756 | if (index == rtlpci->rxringcount - 1) | 756 | if (index == rtlpci->rxringcount - 1) |
757 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, | 757 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, |
758 | HW_DESC_RXERO, | 758 | HW_DESC_RXERO, |
759 | (u8 *)&tmp_one); | 759 | &tmp_one); |
760 | 760 | ||
761 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, | 761 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, |
762 | (u8 *)&tmp_one); | 762 | &tmp_one); |
763 | 763 | ||
764 | index = (index + 1) % rtlpci->rxringcount; | 764 | index = (index + 1) % rtlpci->rxringcount; |
765 | } | 765 | } |
@@ -934,7 +934,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | |||
934 | __skb_queue_tail(&ring->queue, pskb); | 934 | __skb_queue_tail(&ring->queue, pskb); |
935 | 935 | ||
936 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, | 936 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true, HW_DESC_OWN, |
937 | (u8 *)&temp_one); | 937 | &temp_one); |
938 | 938 | ||
939 | return; | 939 | return; |
940 | } | 940 | } |
@@ -1126,11 +1126,11 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
1126 | rxbuffersize); | 1126 | rxbuffersize); |
1127 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, | 1127 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, |
1128 | HW_DESC_RXOWN, | 1128 | HW_DESC_RXOWN, |
1129 | (u8 *)&tmp_one); | 1129 | &tmp_one); |
1130 | } | 1130 | } |
1131 | 1131 | ||
1132 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, | 1132 | rtlpriv->cfg->ops->set_desc((u8 *) entry, false, |
1133 | HW_DESC_RXERO, (u8 *)&tmp_one); | 1133 | HW_DESC_RXERO, &tmp_one); |
1134 | } | 1134 | } |
1135 | return 0; | 1135 | return 0; |
1136 | } | 1136 | } |
@@ -1263,7 +1263,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1263 | rtlpriv->cfg->ops->set_desc((u8 *) entry, | 1263 | rtlpriv->cfg->ops->set_desc((u8 *) entry, |
1264 | false, | 1264 | false, |
1265 | HW_DESC_RXOWN, | 1265 | HW_DESC_RXOWN, |
1266 | (u8 *)&tmp_one); | 1266 | &tmp_one); |
1267 | } | 1267 | } |
1268 | rtlpci->rx_ring[rx_queue_idx].idx = 0; | 1268 | rtlpci->rx_ring[rx_queue_idx].idx = 0; |
1269 | } | 1269 | } |
@@ -1422,7 +1422,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1422 | __skb_queue_tail(&ring->queue, skb); | 1422 | __skb_queue_tail(&ring->queue, skb); |
1423 | 1423 | ||
1424 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, | 1424 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true, |
1425 | HW_DESC_OWN, (u8 *)&temp_one); | 1425 | HW_DESC_OWN, &temp_one); |
1426 | 1426 | ||
1427 | 1427 | ||
1428 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && | 1428 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 5ae26647f340..13ad33e85577 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -333,10 +333,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
333 | rpwm_val = 0x0C; /* RF on */ | 333 | rpwm_val = 0x0C; /* RF on */ |
334 | fw_pwrmode = FW_PS_ACTIVE_MODE; | 334 | fw_pwrmode = FW_PS_ACTIVE_MODE; |
335 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, | 335 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, |
336 | (u8 *) (&rpwm_val)); | 336 | &rpwm_val); |
337 | rtlpriv->cfg->ops->set_hw_reg(hw, | 337 | rtlpriv->cfg->ops->set_hw_reg(hw, |
338 | HW_VAR_H2C_FW_PWRMODE, | 338 | HW_VAR_H2C_FW_PWRMODE, |
339 | (u8 *) (&fw_pwrmode)); | 339 | &fw_pwrmode); |
340 | fw_current_inps = false; | 340 | fw_current_inps = false; |
341 | 341 | ||
342 | rtlpriv->cfg->ops->set_hw_reg(hw, | 342 | rtlpriv->cfg->ops->set_hw_reg(hw, |
@@ -356,11 +356,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
356 | (u8 *) (&fw_current_inps)); | 356 | (u8 *) (&fw_current_inps)); |
357 | rtlpriv->cfg->ops->set_hw_reg(hw, | 357 | rtlpriv->cfg->ops->set_hw_reg(hw, |
358 | HW_VAR_H2C_FW_PWRMODE, | 358 | HW_VAR_H2C_FW_PWRMODE, |
359 | (u8 *) (&ppsc->fwctrl_psmode)); | 359 | &ppsc->fwctrl_psmode); |
360 | 360 | ||
361 | rtlpriv->cfg->ops->set_hw_reg(hw, | 361 | rtlpriv->cfg->ops->set_hw_reg(hw, |
362 | HW_VAR_SET_RPWM, | 362 | HW_VAR_SET_RPWM, |
363 | (u8 *) (&rpwm_val)); | 363 | &rpwm_val); |
364 | } else { | 364 | } else { |
365 | /* Reset the power save related parameters. */ | 365 | /* Reset the power save related parameters. */ |
366 | ppsc->dot11_psmode = EACTIVE; | 366 | ppsc->dot11_psmode = EACTIVE; |
@@ -446,7 +446,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) | |||
446 | { | 446 | { |
447 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 447 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
448 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 448 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
449 | struct ieee80211_hdr *hdr = (void *) data; | 449 | struct ieee80211_hdr *hdr = data; |
450 | struct ieee80211_tim_ie *tim_ie; | 450 | struct ieee80211_tim_ie *tim_ie; |
451 | u8 *tim; | 451 | u8 *tim; |
452 | u8 tim_len; | 452 | u8 tim_len; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index f7f48c7ac854..a45afda8259c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -656,9 +656,8 @@ static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
656 | } else { | 656 | } else { |
657 | if (rtlpriv->dm.current_turbo_edca) { | 657 | if (rtlpriv->dm.current_turbo_edca) { |
658 | u8 tmp = AC0_BE; | 658 | u8 tmp = AC0_BE; |
659 | rtlpriv->cfg->ops->set_hw_reg(hw, | 659 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
660 | HW_VAR_AC_PARAM, | 660 | &tmp); |
661 | (u8 *) (&tmp)); | ||
662 | rtlpriv->dm.current_turbo_edca = false; | 661 | rtlpriv->dm.current_turbo_edca = false; |
663 | } | 662 | } |
664 | } | 663 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 692c8ef5ee89..44febfde9493 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
@@ -168,7 +168,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, | |||
168 | { | 168 | { |
169 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 169 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
170 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 170 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
171 | u8 *bufferPtr = (u8 *) buffer; | 171 | u8 *bufferPtr = buffer; |
172 | 172 | ||
173 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); | 173 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); |
174 | 174 | ||
@@ -262,7 +262,7 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
262 | return 1; | 262 | return 1; |
263 | 263 | ||
264 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; | 264 | pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; |
265 | pfwdata = (u8 *) rtlhal->pfirmware; | 265 | pfwdata = rtlhal->pfirmware; |
266 | fwsize = rtlhal->fwsize; | 266 | fwsize = rtlhal->fwsize; |
267 | 267 | ||
268 | if (IS_FW_HEADER_EXIST(pfwheader)) { | 268 | if (IS_FW_HEADER_EXIST(pfwheader)) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 5c4d9bc040f1..bd0da7ef290b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -214,13 +214,13 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
214 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | 214 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { |
215 | rtlpriv->cfg->ops->set_hw_reg(hw, | 215 | rtlpriv->cfg->ops->set_hw_reg(hw, |
216 | HW_VAR_AC_PARAM, | 216 | HW_VAR_AC_PARAM, |
217 | (u8 *) (&e_aci)); | 217 | &e_aci); |
218 | } | 218 | } |
219 | break; | 219 | break; |
220 | } | 220 | } |
221 | case HW_VAR_ACK_PREAMBLE:{ | 221 | case HW_VAR_ACK_PREAMBLE:{ |
222 | u8 reg_tmp; | 222 | u8 reg_tmp; |
223 | u8 short_preamble = (bool) (*(u8 *) val); | 223 | u8 short_preamble = (bool)*val; |
224 | reg_tmp = (mac->cur_40_prime_sc) << 5; | 224 | reg_tmp = (mac->cur_40_prime_sc) << 5; |
225 | if (short_preamble) | 225 | if (short_preamble) |
226 | reg_tmp |= 0x80; | 226 | reg_tmp |= 0x80; |
@@ -232,7 +232,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
232 | u8 min_spacing_to_set; | 232 | u8 min_spacing_to_set; |
233 | u8 sec_min_space; | 233 | u8 sec_min_space; |
234 | 234 | ||
235 | min_spacing_to_set = *((u8 *) val); | 235 | min_spacing_to_set = *val; |
236 | if (min_spacing_to_set <= 7) { | 236 | if (min_spacing_to_set <= 7) { |
237 | sec_min_space = 0; | 237 | sec_min_space = 0; |
238 | 238 | ||
@@ -257,7 +257,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
257 | case HW_VAR_SHORTGI_DENSITY:{ | 257 | case HW_VAR_SHORTGI_DENSITY:{ |
258 | u8 density_to_set; | 258 | u8 density_to_set; |
259 | 259 | ||
260 | density_to_set = *((u8 *) val); | 260 | density_to_set = *val; |
261 | mac->min_space_cfg |= (density_to_set << 3); | 261 | mac->min_space_cfg |= (density_to_set << 3); |
262 | 262 | ||
263 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 263 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
@@ -284,7 +284,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
284 | else | 284 | else |
285 | p_regtoset = regtoset_normal; | 285 | p_regtoset = regtoset_normal; |
286 | 286 | ||
287 | factor_toset = *((u8 *) val); | 287 | factor_toset = *(val); |
288 | if (factor_toset <= 3) { | 288 | if (factor_toset <= 3) { |
289 | factor_toset = (1 << (factor_toset + 2)); | 289 | factor_toset = (1 << (factor_toset + 2)); |
290 | if (factor_toset > 0xf) | 290 | if (factor_toset > 0xf) |
@@ -316,17 +316,17 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | case HW_VAR_AC_PARAM:{ | 318 | case HW_VAR_AC_PARAM:{ |
319 | u8 e_aci = *((u8 *) val); | 319 | u8 e_aci = *(val); |
320 | rtl92c_dm_init_edca_turbo(hw); | 320 | rtl92c_dm_init_edca_turbo(hw); |
321 | 321 | ||
322 | if (rtlpci->acm_method != eAcmWay2_SW) | 322 | if (rtlpci->acm_method != eAcmWay2_SW) |
323 | rtlpriv->cfg->ops->set_hw_reg(hw, | 323 | rtlpriv->cfg->ops->set_hw_reg(hw, |
324 | HW_VAR_ACM_CTRL, | 324 | HW_VAR_ACM_CTRL, |
325 | (u8 *) (&e_aci)); | 325 | (&e_aci)); |
326 | break; | 326 | break; |
327 | } | 327 | } |
328 | case HW_VAR_ACM_CTRL:{ | 328 | case HW_VAR_ACM_CTRL:{ |
329 | u8 e_aci = *((u8 *) val); | 329 | u8 e_aci = *(val); |
330 | union aci_aifsn *p_aci_aifsn = | 330 | union aci_aifsn *p_aci_aifsn = |
331 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | 331 | (union aci_aifsn *)(&(mac->ac[0].aifs)); |
332 | u8 acm = p_aci_aifsn->f.acm; | 332 | u8 acm = p_aci_aifsn->f.acm; |
@@ -382,7 +382,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
382 | break; | 382 | break; |
383 | } | 383 | } |
384 | case HW_VAR_RETRY_LIMIT:{ | 384 | case HW_VAR_RETRY_LIMIT:{ |
385 | u8 retry_limit = ((u8 *) (val))[0]; | 385 | u8 retry_limit = val[0]; |
386 | 386 | ||
387 | rtl_write_word(rtlpriv, REG_RL, | 387 | rtl_write_word(rtlpriv, REG_RL, |
388 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 388 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -396,13 +396,13 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
396 | rtlefuse->efuse_usedbytes = *((u16 *) val); | 396 | rtlefuse->efuse_usedbytes = *((u16 *) val); |
397 | break; | 397 | break; |
398 | case HW_VAR_EFUSE_USAGE: | 398 | case HW_VAR_EFUSE_USAGE: |
399 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | 399 | rtlefuse->efuse_usedpercentage = *val; |
400 | break; | 400 | break; |
401 | case HW_VAR_IO_CMD: | 401 | case HW_VAR_IO_CMD: |
402 | rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 402 | rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); |
403 | break; | 403 | break; |
404 | case HW_VAR_WPA_CONFIG: | 404 | case HW_VAR_WPA_CONFIG: |
405 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | 405 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
406 | break; | 406 | break; |
407 | case HW_VAR_SET_RPWM:{ | 407 | case HW_VAR_SET_RPWM:{ |
408 | u8 rpwm_val; | 408 | u8 rpwm_val; |
@@ -411,31 +411,30 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
411 | udelay(1); | 411 | udelay(1); |
412 | 412 | ||
413 | if (rpwm_val & BIT(7)) { | 413 | if (rpwm_val & BIT(7)) { |
414 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 414 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val); |
415 | (*(u8 *) val)); | ||
416 | } else { | 415 | } else { |
417 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | 416 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, |
418 | ((*(u8 *) val) | BIT(7))); | 417 | *val | BIT(7)); |
419 | } | 418 | } |
420 | 419 | ||
421 | break; | 420 | break; |
422 | } | 421 | } |
423 | case HW_VAR_H2C_FW_PWRMODE:{ | 422 | case HW_VAR_H2C_FW_PWRMODE:{ |
424 | u8 psmode = (*(u8 *) val); | 423 | u8 psmode = *val; |
425 | 424 | ||
426 | if ((psmode != FW_PS_ACTIVE_MODE) && | 425 | if ((psmode != FW_PS_ACTIVE_MODE) && |
427 | (!IS_92C_SERIAL(rtlhal->version))) { | 426 | (!IS_92C_SERIAL(rtlhal->version))) { |
428 | rtl92c_dm_rf_saving(hw, true); | 427 | rtl92c_dm_rf_saving(hw, true); |
429 | } | 428 | } |
430 | 429 | ||
431 | rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); | 430 | rtl92c_set_fw_pwrmode_cmd(hw, *val); |
432 | break; | 431 | break; |
433 | } | 432 | } |
434 | case HW_VAR_FW_PSMODE_STATUS: | 433 | case HW_VAR_FW_PSMODE_STATUS: |
435 | ppsc->fw_current_inpsmode = *((bool *) val); | 434 | ppsc->fw_current_inpsmode = *((bool *) val); |
436 | break; | 435 | break; |
437 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | 436 | case HW_VAR_H2C_FW_JOINBSSRPT:{ |
438 | u8 mstatus = (*(u8 *) val); | 437 | u8 mstatus = *val; |
439 | u8 tmp_regcr, tmp_reg422; | 438 | u8 tmp_regcr, tmp_reg422; |
440 | bool recover = false; | 439 | bool recover = false; |
441 | 440 | ||
@@ -472,7 +471,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
472 | rtl_write_byte(rtlpriv, REG_CR + 1, | 471 | rtl_write_byte(rtlpriv, REG_CR + 1, |
473 | (tmp_regcr & ~(BIT(0)))); | 472 | (tmp_regcr & ~(BIT(0)))); |
474 | } | 473 | } |
475 | rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | 474 | rtl92c_set_fw_joinbss_report_cmd(hw, *val); |
476 | 475 | ||
477 | break; | 476 | break; |
478 | } | 477 | } |
@@ -486,7 +485,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
486 | break; | 485 | break; |
487 | } | 486 | } |
488 | case HW_VAR_CORRECT_TSF:{ | 487 | case HW_VAR_CORRECT_TSF:{ |
489 | u8 btype_ibss = ((u8 *) (val))[0]; | 488 | u8 btype_ibss = val[0]; |
490 | 489 | ||
491 | if (btype_ibss) | 490 | if (btype_ibss) |
492 | _rtl92ce_stop_tx_beacon(hw); | 491 | _rtl92ce_stop_tx_beacon(hw); |
@@ -1589,10 +1588,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1589 | rtlefuse->autoload_failflag, | 1588 | rtlefuse->autoload_failflag, |
1590 | hwinfo); | 1589 | hwinfo); |
1591 | 1590 | ||
1592 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1591 | rtlefuse->eeprom_channelplan = *&hwinfo[EEPROM_CHANNELPLAN]; |
1593 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | 1592 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; |
1594 | rtlefuse->txpwr_fromeprom = true; | 1593 | rtlefuse->txpwr_fromeprom = true; |
1595 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1594 | rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMER_ID]; |
1596 | 1595 | ||
1597 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1596 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
1598 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); | 1597 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); |
@@ -1939,7 +1938,7 @@ void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw) | |||
1939 | u16 sifs_timer; | 1938 | u16 sifs_timer; |
1940 | 1939 | ||
1941 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 1940 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, |
1942 | (u8 *)&mac->slot_time); | 1941 | &mac->slot_time); |
1943 | if (!mac->ht_enable) | 1942 | if (!mac->ht_enable) |
1944 | sifs_timer = 0x0a0a; | 1943 | sifs_timer = 0x0a0a; |
1945 | else | 1944 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 3af874e69595..52166640f167 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -605,7 +605,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
605 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 605 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
606 | bool defaultadapter = true; | 606 | bool defaultadapter = true; |
607 | struct ieee80211_sta *sta; | 607 | struct ieee80211_sta *sta; |
608 | u8 *pdesc = (u8 *) pdesc_tx; | 608 | u8 *pdesc = pdesc_tx; |
609 | u16 seq_number; | 609 | u16 seq_number; |
610 | __le16 fc = hdr->frame_control; | 610 | __le16 fc = hdr->frame_control; |
611 | u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue); | 611 | u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue); |
@@ -806,7 +806,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
806 | 806 | ||
807 | SET_TX_DESC_OWN(pdesc, 1); | 807 | SET_TX_DESC_OWN(pdesc, 1); |
808 | 808 | ||
809 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | 809 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len)); |
810 | 810 | ||
811 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 811 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
812 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 812 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 0c74d4f2eeb4..4bbb711a36c5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -381,11 +381,11 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) | |||
381 | rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); | 381 | rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); |
382 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", | 382 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", |
383 | rtlefuse->eeprom_vid, rtlefuse->eeprom_did); | 383 | rtlefuse->eeprom_vid, rtlefuse->eeprom_did); |
384 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 384 | rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; |
385 | rtlefuse->eeprom_version = | 385 | rtlefuse->eeprom_version = |
386 | le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); | 386 | le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); |
387 | rtlefuse->txpwr_fromeprom = true; | 387 | rtlefuse->txpwr_fromeprom = true; |
388 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 388 | rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; |
389 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", | 389 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", |
390 | rtlefuse->eeprom_oemid); | 390 | rtlefuse->eeprom_oemid); |
391 | if (rtlhal->oem_id == RT_CID_DEFAULT) { | 391 | if (rtlhal->oem_id == RT_CID_DEFAULT) { |
@@ -1660,7 +1660,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1660 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) | 1660 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) |
1661 | rtlpriv->cfg->ops->set_hw_reg(hw, | 1661 | rtlpriv->cfg->ops->set_hw_reg(hw, |
1662 | HW_VAR_AC_PARAM, | 1662 | HW_VAR_AC_PARAM, |
1663 | (u8 *)(&e_aci)); | 1663 | &e_aci); |
1664 | } else { | 1664 | } else { |
1665 | u8 sifstime = 0; | 1665 | u8 sifstime = 0; |
1666 | u8 u1bAIFS; | 1666 | u8 u1bAIFS; |
@@ -1685,7 +1685,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1685 | } | 1685 | } |
1686 | case HW_VAR_ACK_PREAMBLE:{ | 1686 | case HW_VAR_ACK_PREAMBLE:{ |
1687 | u8 reg_tmp; | 1687 | u8 reg_tmp; |
1688 | u8 short_preamble = (bool) (*(u8 *) val); | 1688 | u8 short_preamble = (bool)*val; |
1689 | reg_tmp = 0; | 1689 | reg_tmp = 0; |
1690 | if (short_preamble) | 1690 | if (short_preamble) |
1691 | reg_tmp |= 0x80; | 1691 | reg_tmp |= 0x80; |
@@ -1696,7 +1696,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1696 | u8 min_spacing_to_set; | 1696 | u8 min_spacing_to_set; |
1697 | u8 sec_min_space; | 1697 | u8 sec_min_space; |
1698 | 1698 | ||
1699 | min_spacing_to_set = *((u8 *) val); | 1699 | min_spacing_to_set = *val; |
1700 | if (min_spacing_to_set <= 7) { | 1700 | if (min_spacing_to_set <= 7) { |
1701 | switch (rtlpriv->sec.pairwise_enc_algorithm) { | 1701 | switch (rtlpriv->sec.pairwise_enc_algorithm) { |
1702 | case NO_ENCRYPTION: | 1702 | case NO_ENCRYPTION: |
@@ -1729,7 +1729,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1729 | case HW_VAR_SHORTGI_DENSITY:{ | 1729 | case HW_VAR_SHORTGI_DENSITY:{ |
1730 | u8 density_to_set; | 1730 | u8 density_to_set; |
1731 | 1731 | ||
1732 | density_to_set = *((u8 *) val); | 1732 | density_to_set = *val; |
1733 | density_to_set &= 0x1f; | 1733 | density_to_set &= 0x1f; |
1734 | mac->min_space_cfg &= 0x07; | 1734 | mac->min_space_cfg &= 0x07; |
1735 | mac->min_space_cfg |= (density_to_set << 3); | 1735 | mac->min_space_cfg |= (density_to_set << 3); |
@@ -1747,7 +1747,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1747 | u8 index = 0; | 1747 | u8 index = 0; |
1748 | 1748 | ||
1749 | p_regtoset = regtoset_normal; | 1749 | p_regtoset = regtoset_normal; |
1750 | factor_toset = *((u8 *) val); | 1750 | factor_toset = *val; |
1751 | if (factor_toset <= 3) { | 1751 | if (factor_toset <= 3) { |
1752 | factor_toset = (1 << (factor_toset + 2)); | 1752 | factor_toset = (1 << (factor_toset + 2)); |
1753 | if (factor_toset > 0xf) | 1753 | if (factor_toset > 0xf) |
@@ -1774,7 +1774,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1774 | break; | 1774 | break; |
1775 | } | 1775 | } |
1776 | case HW_VAR_AC_PARAM:{ | 1776 | case HW_VAR_AC_PARAM:{ |
1777 | u8 e_aci = *((u8 *) val); | 1777 | u8 e_aci = *val; |
1778 | u32 u4b_ac_param; | 1778 | u32 u4b_ac_param; |
1779 | u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); | 1779 | u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); |
1780 | u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); | 1780 | u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); |
@@ -1814,11 +1814,11 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1814 | } | 1814 | } |
1815 | if (rtlusb->acm_method != eAcmWay2_SW) | 1815 | if (rtlusb->acm_method != eAcmWay2_SW) |
1816 | rtlpriv->cfg->ops->set_hw_reg(hw, | 1816 | rtlpriv->cfg->ops->set_hw_reg(hw, |
1817 | HW_VAR_ACM_CTRL, (u8 *)(&e_aci)); | 1817 | HW_VAR_ACM_CTRL, &e_aci); |
1818 | break; | 1818 | break; |
1819 | } | 1819 | } |
1820 | case HW_VAR_ACM_CTRL:{ | 1820 | case HW_VAR_ACM_CTRL:{ |
1821 | u8 e_aci = *((u8 *) val); | 1821 | u8 e_aci = *val; |
1822 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *) | 1822 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *) |
1823 | (&(mac->ac[0].aifs)); | 1823 | (&(mac->ac[0].aifs)); |
1824 | u8 acm = p_aci_aifsn->f.acm; | 1824 | u8 acm = p_aci_aifsn->f.acm; |
@@ -1874,7 +1874,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1874 | break; | 1874 | break; |
1875 | } | 1875 | } |
1876 | case HW_VAR_RETRY_LIMIT:{ | 1876 | case HW_VAR_RETRY_LIMIT:{ |
1877 | u8 retry_limit = ((u8 *) (val))[0]; | 1877 | u8 retry_limit = val[0]; |
1878 | 1878 | ||
1879 | rtl_write_word(rtlpriv, REG_RL, | 1879 | rtl_write_word(rtlpriv, REG_RL, |
1880 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 1880 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -1891,39 +1891,38 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1891 | rtlefuse->efuse_usedbytes = *((u16 *) val); | 1891 | rtlefuse->efuse_usedbytes = *((u16 *) val); |
1892 | break; | 1892 | break; |
1893 | case HW_VAR_EFUSE_USAGE: | 1893 | case HW_VAR_EFUSE_USAGE: |
1894 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | 1894 | rtlefuse->efuse_usedpercentage = *val; |
1895 | break; | 1895 | break; |
1896 | case HW_VAR_IO_CMD: | 1896 | case HW_VAR_IO_CMD: |
1897 | rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 1897 | rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); |
1898 | break; | 1898 | break; |
1899 | case HW_VAR_WPA_CONFIG: | 1899 | case HW_VAR_WPA_CONFIG: |
1900 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | 1900 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
1901 | break; | 1901 | break; |
1902 | case HW_VAR_SET_RPWM:{ | 1902 | case HW_VAR_SET_RPWM:{ |
1903 | u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); | 1903 | u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); |
1904 | 1904 | ||
1905 | if (rpwm_val & BIT(7)) | 1905 | if (rpwm_val & BIT(7)) |
1906 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, | 1906 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val); |
1907 | (*(u8 *)val)); | ||
1908 | else | 1907 | else |
1909 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, | 1908 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, |
1910 | ((*(u8 *)val) | BIT(7))); | 1909 | *val | BIT(7)); |
1911 | break; | 1910 | break; |
1912 | } | 1911 | } |
1913 | case HW_VAR_H2C_FW_PWRMODE:{ | 1912 | case HW_VAR_H2C_FW_PWRMODE:{ |
1914 | u8 psmode = (*(u8 *) val); | 1913 | u8 psmode = *val; |
1915 | 1914 | ||
1916 | if ((psmode != FW_PS_ACTIVE_MODE) && | 1915 | if ((psmode != FW_PS_ACTIVE_MODE) && |
1917 | (!IS_92C_SERIAL(rtlhal->version))) | 1916 | (!IS_92C_SERIAL(rtlhal->version))) |
1918 | rtl92c_dm_rf_saving(hw, true); | 1917 | rtl92c_dm_rf_saving(hw, true); |
1919 | rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); | 1918 | rtl92c_set_fw_pwrmode_cmd(hw, (*val)); |
1920 | break; | 1919 | break; |
1921 | } | 1920 | } |
1922 | case HW_VAR_FW_PSMODE_STATUS: | 1921 | case HW_VAR_FW_PSMODE_STATUS: |
1923 | ppsc->fw_current_inpsmode = *((bool *) val); | 1922 | ppsc->fw_current_inpsmode = *((bool *) val); |
1924 | break; | 1923 | break; |
1925 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | 1924 | case HW_VAR_H2C_FW_JOINBSSRPT:{ |
1926 | u8 mstatus = (*(u8 *) val); | 1925 | u8 mstatus = *val; |
1927 | u8 tmp_reg422; | 1926 | u8 tmp_reg422; |
1928 | bool recover = false; | 1927 | bool recover = false; |
1929 | 1928 | ||
@@ -1948,7 +1947,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1948 | tmp_reg422 | BIT(6)); | 1947 | tmp_reg422 | BIT(6)); |
1949 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); | 1948 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); |
1950 | } | 1949 | } |
1951 | rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | 1950 | rtl92c_set_fw_joinbss_report_cmd(hw, (*val)); |
1952 | break; | 1951 | break; |
1953 | } | 1952 | } |
1954 | case HW_VAR_AID:{ | 1953 | case HW_VAR_AID:{ |
@@ -1961,7 +1960,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
1961 | break; | 1960 | break; |
1962 | } | 1961 | } |
1963 | case HW_VAR_CORRECT_TSF:{ | 1962 | case HW_VAR_CORRECT_TSF:{ |
1964 | u8 btype_ibss = ((u8 *) (val))[0]; | 1963 | u8 btype_ibss = val[0]; |
1965 | 1964 | ||
1966 | if (btype_ibss) | 1965 | if (btype_ibss) |
1967 | _rtl92cu_stop_tx_beacon(hw); | 1966 | _rtl92cu_stop_tx_beacon(hw); |
@@ -2184,7 +2183,7 @@ void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2184 | u16 sifs_timer; | 2183 | u16 sifs_timer; |
2185 | 2184 | ||
2186 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2185 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, |
2187 | (u8 *)&mac->slot_time); | 2186 | &mac->slot_time); |
2188 | if (!mac->ht_enable) | 2187 | if (!mac->ht_enable) |
2189 | sifs_timer = 0x0a0a; | 2188 | sifs_timer = 0x0a0a; |
2190 | else | 2189 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 21bc827c5fa6..2e6eb356a93e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -668,7 +668,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
668 | SET_TX_DESC_RATE_ID(pdesc, 7); | 668 | SET_TX_DESC_RATE_ID(pdesc, 7); |
669 | SET_TX_DESC_MACID(pdesc, 0); | 669 | SET_TX_DESC_MACID(pdesc, 0); |
670 | SET_TX_DESC_OWN(pdesc, 1); | 670 | SET_TX_DESC_OWN(pdesc, 1); |
671 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | 671 | SET_TX_DESC_PKT_SIZE(pdesc, (u16)skb->len); |
672 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 672 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
673 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 673 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
674 | SET_TX_DESC_OFFSET(pdesc, 0x20); | 674 | SET_TX_DESC_OFFSET(pdesc, 0x20); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index a7d63a84551a..c0201ed69dd7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c | |||
@@ -696,7 +696,7 @@ static void rtl92d_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
696 | if (rtlpriv->dm.current_turbo_edca) { | 696 | if (rtlpriv->dm.current_turbo_edca) { |
697 | u8 tmp = AC0_BE; | 697 | u8 tmp = AC0_BE; |
698 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | 698 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
699 | (u8 *) (&tmp)); | 699 | &tmp); |
700 | rtlpriv->dm.current_turbo_edca = false; | 700 | rtlpriv->dm.current_turbo_edca = false; |
701 | } | 701 | } |
702 | } | 702 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index f548a8d0068d..895ae6c1f354 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c | |||
@@ -120,7 +120,7 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw, | |||
120 | { | 120 | { |
121 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 121 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
122 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 122 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
123 | u8 *bufferPtr = (u8 *) buffer; | 123 | u8 *bufferPtr = buffer; |
124 | u32 pagenums, remainSize; | 124 | u32 pagenums, remainSize; |
125 | u32 page, offset; | 125 | u32 page, offset; |
126 | 126 | ||
@@ -256,8 +256,8 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) | |||
256 | if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) | 256 | if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) |
257 | return 1; | 257 | return 1; |
258 | fwsize = rtlhal->fwsize; | 258 | fwsize = rtlhal->fwsize; |
259 | pfwheader = (u8 *) rtlhal->pfirmware; | 259 | pfwheader = rtlhal->pfirmware; |
260 | pfwdata = (u8 *) rtlhal->pfirmware; | 260 | pfwdata = rtlhal->pfirmware; |
261 | rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); | 261 | rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); |
262 | rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); | 262 | rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); |
263 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 263 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index b338d526c422..f4051f4f0390 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c | |||
@@ -235,12 +235,12 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
235 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) | 235 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) |
236 | rtlpriv->cfg->ops->set_hw_reg(hw, | 236 | rtlpriv->cfg->ops->set_hw_reg(hw, |
237 | HW_VAR_AC_PARAM, | 237 | HW_VAR_AC_PARAM, |
238 | (u8 *) (&e_aci)); | 238 | (&e_aci)); |
239 | break; | 239 | break; |
240 | } | 240 | } |
241 | case HW_VAR_ACK_PREAMBLE: { | 241 | case HW_VAR_ACK_PREAMBLE: { |
242 | u8 reg_tmp; | 242 | u8 reg_tmp; |
243 | u8 short_preamble = (bool) (*(u8 *) val); | 243 | u8 short_preamble = (bool) (*val); |
244 | 244 | ||
245 | reg_tmp = (mac->cur_40_prime_sc) << 5; | 245 | reg_tmp = (mac->cur_40_prime_sc) << 5; |
246 | if (short_preamble) | 246 | if (short_preamble) |
@@ -252,7 +252,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
252 | u8 min_spacing_to_set; | 252 | u8 min_spacing_to_set; |
253 | u8 sec_min_space; | 253 | u8 sec_min_space; |
254 | 254 | ||
255 | min_spacing_to_set = *((u8 *) val); | 255 | min_spacing_to_set = *val; |
256 | if (min_spacing_to_set <= 7) { | 256 | if (min_spacing_to_set <= 7) { |
257 | sec_min_space = 0; | 257 | sec_min_space = 0; |
258 | if (min_spacing_to_set < sec_min_space) | 258 | if (min_spacing_to_set < sec_min_space) |
@@ -271,7 +271,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
271 | case HW_VAR_SHORTGI_DENSITY: { | 271 | case HW_VAR_SHORTGI_DENSITY: { |
272 | u8 density_to_set; | 272 | u8 density_to_set; |
273 | 273 | ||
274 | density_to_set = *((u8 *) val); | 274 | density_to_set = *val; |
275 | mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; | 275 | mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; |
276 | mac->min_space_cfg |= (density_to_set << 3); | 276 | mac->min_space_cfg |= (density_to_set << 3); |
277 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 277 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
@@ -293,7 +293,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
293 | regtoSet = 0x66626641; | 293 | regtoSet = 0x66626641; |
294 | else | 294 | else |
295 | regtoSet = 0xb972a841; | 295 | regtoSet = 0xb972a841; |
296 | factor_toset = *((u8 *) val); | 296 | factor_toset = *val; |
297 | if (factor_toset <= 3) { | 297 | if (factor_toset <= 3) { |
298 | factor_toset = (1 << (factor_toset + 2)); | 298 | factor_toset = (1 << (factor_toset + 2)); |
299 | if (factor_toset > 0xf) | 299 | if (factor_toset > 0xf) |
@@ -316,15 +316,15 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | case HW_VAR_AC_PARAM: { | 318 | case HW_VAR_AC_PARAM: { |
319 | u8 e_aci = *((u8 *) val); | 319 | u8 e_aci = *val; |
320 | rtl92d_dm_init_edca_turbo(hw); | 320 | rtl92d_dm_init_edca_turbo(hw); |
321 | if (rtlpci->acm_method != eAcmWay2_SW) | 321 | if (rtlpci->acm_method != eAcmWay2_SW) |
322 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, | 322 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, |
323 | (u8 *) (&e_aci)); | 323 | &e_aci); |
324 | break; | 324 | break; |
325 | } | 325 | } |
326 | case HW_VAR_ACM_CTRL: { | 326 | case HW_VAR_ACM_CTRL: { |
327 | u8 e_aci = *((u8 *) val); | 327 | u8 e_aci = *val; |
328 | union aci_aifsn *p_aci_aifsn = | 328 | union aci_aifsn *p_aci_aifsn = |
329 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | 329 | (union aci_aifsn *)(&(mac->ac[0].aifs)); |
330 | u8 acm = p_aci_aifsn->f.acm; | 330 | u8 acm = p_aci_aifsn->f.acm; |
@@ -376,7 +376,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
376 | rtlpci->receive_config = ((u32 *) (val))[0]; | 376 | rtlpci->receive_config = ((u32 *) (val))[0]; |
377 | break; | 377 | break; |
378 | case HW_VAR_RETRY_LIMIT: { | 378 | case HW_VAR_RETRY_LIMIT: { |
379 | u8 retry_limit = ((u8 *) (val))[0]; | 379 | u8 retry_limit = val[0]; |
380 | 380 | ||
381 | rtl_write_word(rtlpriv, REG_RL, | 381 | rtl_write_word(rtlpriv, REG_RL, |
382 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 382 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -390,16 +390,16 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
390 | rtlefuse->efuse_usedbytes = *((u16 *) val); | 390 | rtlefuse->efuse_usedbytes = *((u16 *) val); |
391 | break; | 391 | break; |
392 | case HW_VAR_EFUSE_USAGE: | 392 | case HW_VAR_EFUSE_USAGE: |
393 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | 393 | rtlefuse->efuse_usedpercentage = *val; |
394 | break; | 394 | break; |
395 | case HW_VAR_IO_CMD: | 395 | case HW_VAR_IO_CMD: |
396 | rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); | 396 | rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); |
397 | break; | 397 | break; |
398 | case HW_VAR_WPA_CONFIG: | 398 | case HW_VAR_WPA_CONFIG: |
399 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | 399 | rtl_write_byte(rtlpriv, REG_SECCFG, *val); |
400 | break; | 400 | break; |
401 | case HW_VAR_SET_RPWM: | 401 | case HW_VAR_SET_RPWM: |
402 | rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (u8 *) (val)); | 402 | rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (val)); |
403 | break; | 403 | break; |
404 | case HW_VAR_H2C_FW_PWRMODE: | 404 | case HW_VAR_H2C_FW_PWRMODE: |
405 | break; | 405 | break; |
@@ -407,7 +407,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
407 | ppsc->fw_current_inpsmode = *((bool *) val); | 407 | ppsc->fw_current_inpsmode = *((bool *) val); |
408 | break; | 408 | break; |
409 | case HW_VAR_H2C_FW_JOINBSSRPT: { | 409 | case HW_VAR_H2C_FW_JOINBSSRPT: { |
410 | u8 mstatus = (*(u8 *) val); | 410 | u8 mstatus = (*val); |
411 | u8 tmp_regcr, tmp_reg422; | 411 | u8 tmp_regcr, tmp_reg422; |
412 | bool recover = false; | 412 | bool recover = false; |
413 | 413 | ||
@@ -435,7 +435,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
435 | rtl_write_byte(rtlpriv, REG_CR + 1, | 435 | rtl_write_byte(rtlpriv, REG_CR + 1, |
436 | (tmp_regcr & ~(BIT(0)))); | 436 | (tmp_regcr & ~(BIT(0)))); |
437 | } | 437 | } |
438 | rtl92d_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | 438 | rtl92d_set_fw_joinbss_report_cmd(hw, (*val)); |
439 | break; | 439 | break; |
440 | } | 440 | } |
441 | case HW_VAR_AID: { | 441 | case HW_VAR_AID: { |
@@ -447,7 +447,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
447 | break; | 447 | break; |
448 | } | 448 | } |
449 | case HW_VAR_CORRECT_TSF: { | 449 | case HW_VAR_CORRECT_TSF: { |
450 | u8 btype_ibss = ((u8 *) (val))[0]; | 450 | u8 btype_ibss = val[0]; |
451 | 451 | ||
452 | if (btype_ibss) | 452 | if (btype_ibss) |
453 | _rtl92de_stop_tx_beacon(hw); | 453 | _rtl92de_stop_tx_beacon(hw); |
@@ -1794,7 +1794,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) | |||
1794 | "RTL819X Not boot from eeprom, check it !!\n"); | 1794 | "RTL819X Not boot from eeprom, check it !!\n"); |
1795 | return; | 1795 | return; |
1796 | } | 1796 | } |
1797 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1797 | rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID]; |
1798 | _rtl92de_read_macphymode_and_bandtype(hw, hwinfo); | 1798 | _rtl92de_read_macphymode_and_bandtype(hw, hwinfo); |
1799 | 1799 | ||
1800 | /* VID, DID SE 0xA-D */ | 1800 | /* VID, DID SE 0xA-D */ |
@@ -2115,7 +2115,7 @@ void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2115 | u16 sifs_timer; | 2115 | u16 sifs_timer; |
2116 | 2116 | ||
2117 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2117 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, |
2118 | (u8 *)&mac->slot_time); | 2118 | &mac->slot_time); |
2119 | if (!mac->ht_enable) | 2119 | if (!mac->ht_enable) |
2120 | sifs_timer = 0x0a0a; | 2120 | sifs_timer = 0x0a0a; |
2121 | else | 2121 | else |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 1666ef7fd87b..f80690d82c11 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
@@ -560,7 +560,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, | |||
560 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | 560 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); |
561 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 561 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
562 | struct ieee80211_sta *sta = info->control.sta; | 562 | struct ieee80211_sta *sta = info->control.sta; |
563 | u8 *pdesc = (u8 *) pdesc_tx; | 563 | u8 *pdesc = pdesc_tx; |
564 | u16 seq_number; | 564 | u16 seq_number; |
565 | __le16 fc = hdr->frame_control; | 565 | __le16 fc = hdr->frame_control; |
566 | unsigned int buf_len = 0; | 566 | unsigned int buf_len = 0; |
@@ -761,11 +761,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
761 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); | 761 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); |
762 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 762 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
763 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 763 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
764 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); | 764 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)skb->len); |
765 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); | 765 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); |
766 | SET_TX_DESC_RATE_ID(pdesc, 7); | 766 | SET_TX_DESC_RATE_ID(pdesc, 7); |
767 | SET_TX_DESC_MACID(pdesc, 0); | 767 | SET_TX_DESC_MACID(pdesc, 0); |
768 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | 768 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len)); |
769 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | 769 | SET_TX_DESC_FIRST_SEG(pdesc, 1); |
770 | SET_TX_DESC_LAST_SEG(pdesc, 1); | 770 | SET_TX_DESC_LAST_SEG(pdesc, 1); |
771 | SET_TX_DESC_OFFSET(pdesc, 0x20); | 771 | SET_TX_DESC_OFFSET(pdesc, 0x20); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 2e1158026fb7..465f58157101 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c | |||
@@ -146,7 +146,7 @@ static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw) | |||
146 | if (rtlpriv->dm.current_turbo_edca) { | 146 | if (rtlpriv->dm.current_turbo_edca) { |
147 | u8 tmp = AC0_BE; | 147 | u8 tmp = AC0_BE; |
148 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, | 148 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, |
149 | (u8 *)(&tmp)); | 149 | &tmp); |
150 | rtlpriv->dm.current_turbo_edca = false; | 150 | rtlpriv->dm.current_turbo_edca = false; |
151 | } | 151 | } |
152 | } | 152 | } |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index b141c35bf926..4542e6952b97 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
@@ -145,13 +145,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
145 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | 145 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { |
146 | rtlpriv->cfg->ops->set_hw_reg(hw, | 146 | rtlpriv->cfg->ops->set_hw_reg(hw, |
147 | HW_VAR_AC_PARAM, | 147 | HW_VAR_AC_PARAM, |
148 | (u8 *)(&e_aci)); | 148 | (&e_aci)); |
149 | } | 149 | } |
150 | break; | 150 | break; |
151 | } | 151 | } |
152 | case HW_VAR_ACK_PREAMBLE:{ | 152 | case HW_VAR_ACK_PREAMBLE:{ |
153 | u8 reg_tmp; | 153 | u8 reg_tmp; |
154 | u8 short_preamble = (bool) (*(u8 *) val); | 154 | u8 short_preamble = (bool) (*val); |
155 | reg_tmp = (mac->cur_40_prime_sc) << 5; | 155 | reg_tmp = (mac->cur_40_prime_sc) << 5; |
156 | if (short_preamble) | 156 | if (short_preamble) |
157 | reg_tmp |= 0x80; | 157 | reg_tmp |= 0x80; |
@@ -163,7 +163,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
163 | u8 min_spacing_to_set; | 163 | u8 min_spacing_to_set; |
164 | u8 sec_min_space; | 164 | u8 sec_min_space; |
165 | 165 | ||
166 | min_spacing_to_set = *((u8 *)val); | 166 | min_spacing_to_set = *val; |
167 | if (min_spacing_to_set <= 7) { | 167 | if (min_spacing_to_set <= 7) { |
168 | if (rtlpriv->sec.pairwise_enc_algorithm == | 168 | if (rtlpriv->sec.pairwise_enc_algorithm == |
169 | NO_ENCRYPTION) | 169 | NO_ENCRYPTION) |
@@ -194,7 +194,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
194 | case HW_VAR_SHORTGI_DENSITY:{ | 194 | case HW_VAR_SHORTGI_DENSITY:{ |
195 | u8 density_to_set; | 195 | u8 density_to_set; |
196 | 196 | ||
197 | density_to_set = *((u8 *) val); | 197 | density_to_set = *val; |
198 | mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; | 198 | mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; |
199 | mac->min_space_cfg |= (density_to_set << 3); | 199 | mac->min_space_cfg |= (density_to_set << 3); |
200 | 200 | ||
@@ -216,7 +216,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
216 | 15, 15, 15, 15, 0}; | 216 | 15, 15, 15, 15, 0}; |
217 | u8 index = 0; | 217 | u8 index = 0; |
218 | 218 | ||
219 | factor_toset = *((u8 *) val); | 219 | factor_toset = *val; |
220 | if (factor_toset <= 3) { | 220 | if (factor_toset <= 3) { |
221 | factor_toset = (1 << (factor_toset + 2)); | 221 | factor_toset = (1 << (factor_toset + 2)); |
222 | if (factor_toset > 0xf) | 222 | if (factor_toset > 0xf) |
@@ -248,17 +248,17 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
248 | break; | 248 | break; |
249 | } | 249 | } |
250 | case HW_VAR_AC_PARAM:{ | 250 | case HW_VAR_AC_PARAM:{ |
251 | u8 e_aci = *((u8 *) val); | 251 | u8 e_aci = *val; |
252 | rtl92s_dm_init_edca_turbo(hw); | 252 | rtl92s_dm_init_edca_turbo(hw); |
253 | 253 | ||
254 | if (rtlpci->acm_method != eAcmWay2_SW) | 254 | if (rtlpci->acm_method != eAcmWay2_SW) |
255 | rtlpriv->cfg->ops->set_hw_reg(hw, | 255 | rtlpriv->cfg->ops->set_hw_reg(hw, |
256 | HW_VAR_ACM_CTRL, | 256 | HW_VAR_ACM_CTRL, |
257 | (u8 *)(&e_aci)); | 257 | &e_aci); |
258 | break; | 258 | break; |
259 | } | 259 | } |
260 | case HW_VAR_ACM_CTRL:{ | 260 | case HW_VAR_ACM_CTRL:{ |
261 | u8 e_aci = *((u8 *) val); | 261 | u8 e_aci = *val; |
262 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( | 262 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( |
263 | mac->ac[0].aifs)); | 263 | mac->ac[0].aifs)); |
264 | u8 acm = p_aci_aifsn->f.acm; | 264 | u8 acm = p_aci_aifsn->f.acm; |
@@ -313,7 +313,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
313 | break; | 313 | break; |
314 | } | 314 | } |
315 | case HW_VAR_RETRY_LIMIT:{ | 315 | case HW_VAR_RETRY_LIMIT:{ |
316 | u8 retry_limit = ((u8 *) (val))[0]; | 316 | u8 retry_limit = val[0]; |
317 | 317 | ||
318 | rtl_write_word(rtlpriv, RETRY_LIMIT, | 318 | rtl_write_word(rtlpriv, RETRY_LIMIT, |
319 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | 319 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | |
@@ -328,14 +328,14 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
328 | break; | 328 | break; |
329 | } | 329 | } |
330 | case HW_VAR_EFUSE_USAGE: { | 330 | case HW_VAR_EFUSE_USAGE: { |
331 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | 331 | rtlefuse->efuse_usedpercentage = *val; |
332 | break; | 332 | break; |
333 | } | 333 | } |
334 | case HW_VAR_IO_CMD: { | 334 | case HW_VAR_IO_CMD: { |
335 | break; | 335 | break; |
336 | } | 336 | } |
337 | case HW_VAR_WPA_CONFIG: { | 337 | case HW_VAR_WPA_CONFIG: { |
338 | rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val)); | 338 | rtl_write_byte(rtlpriv, REG_SECR, *val); |
339 | break; | 339 | break; |
340 | } | 340 | } |
341 | case HW_VAR_SET_RPWM:{ | 341 | case HW_VAR_SET_RPWM:{ |
@@ -1813,8 +1813,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1813 | else | 1813 | else |
1814 | index = 2; | 1814 | index = 2; |
1815 | 1815 | ||
1816 | tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF + | 1816 | tempval = hwinfo[EEPROM_TX_PWR_HT20_DIFF + index] & 0xff; |
1817 | index]) & 0xff; | ||
1818 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); | 1817 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); |
1819 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = | 1818 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = |
1820 | ((tempval >> 4) & 0xF); | 1819 | ((tempval >> 4) & 0xF); |
@@ -1830,14 +1829,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1830 | else | 1829 | else |
1831 | index = 1; | 1830 | index = 1; |
1832 | 1831 | ||
1833 | tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index]) | 1832 | tempval = hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index] & 0xff; |
1834 | & 0xff; | ||
1835 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = | 1833 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = |
1836 | (tempval & 0xF); | 1834 | (tempval & 0xF); |
1837 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = | 1835 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = |
1838 | ((tempval >> 4) & 0xF); | 1836 | ((tempval >> 4) & 0xF); |
1839 | 1837 | ||
1840 | tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]); | 1838 | tempval = hwinfo[TX_PWR_SAFETY_CHK]; |
1841 | rtlefuse->txpwr_safetyflag = (tempval & 0x01); | 1839 | rtlefuse->txpwr_safetyflag = (tempval & 0x01); |
1842 | } | 1840 | } |
1843 | 1841 | ||
@@ -1876,7 +1874,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1876 | 1874 | ||
1877 | /* Read RF-indication and Tx Power gain | 1875 | /* Read RF-indication and Tx Power gain |
1878 | * index diff of legacy to HT OFDM rate. */ | 1876 | * index diff of legacy to HT OFDM rate. */ |
1879 | tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff; | 1877 | tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff; |
1880 | rtlefuse->eeprom_txpowerdiff = tempval; | 1878 | rtlefuse->eeprom_txpowerdiff = tempval; |
1881 | rtlefuse->legacy_httxpowerdiff = | 1879 | rtlefuse->legacy_httxpowerdiff = |
1882 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; | 1880 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; |
@@ -1887,7 +1885,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1887 | /* Get TSSI value for each path. */ | 1885 | /* Get TSSI value for each path. */ |
1888 | usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; | 1886 | usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; |
1889 | rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); | 1887 | rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); |
1890 | usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; | 1888 | usvalue = hwinfo[EEPROM_TSSI_B]; |
1891 | rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); | 1889 | rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); |
1892 | 1890 | ||
1893 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", | 1891 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", |
@@ -1896,7 +1894,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1896 | 1894 | ||
1897 | /* Read antenna tx power offset of B/C/D to A from EEPROM */ | 1895 | /* Read antenna tx power offset of B/C/D to A from EEPROM */ |
1898 | /* and read ThermalMeter from EEPROM */ | 1896 | /* and read ThermalMeter from EEPROM */ |
1899 | tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; | 1897 | tempval = hwinfo[EEPROM_THERMALMETER]; |
1900 | rtlefuse->eeprom_thermalmeter = tempval; | 1898 | rtlefuse->eeprom_thermalmeter = tempval; |
1901 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | 1899 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, |
1902 | "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); | 1900 | "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); |
@@ -1906,20 +1904,20 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1906 | rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; | 1904 | rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; |
1907 | 1905 | ||
1908 | /* Read CrystalCap from EEPROM */ | 1906 | /* Read CrystalCap from EEPROM */ |
1909 | tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4; | 1907 | tempval = hwinfo[EEPROM_CRYSTALCAP] >> 4; |
1910 | rtlefuse->eeprom_crystalcap = tempval; | 1908 | rtlefuse->eeprom_crystalcap = tempval; |
1911 | /* CrystalCap, BIT(12)~15 */ | 1909 | /* CrystalCap, BIT(12)~15 */ |
1912 | rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; | 1910 | rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; |
1913 | 1911 | ||
1914 | /* Read IC Version && Channel Plan */ | 1912 | /* Read IC Version && Channel Plan */ |
1915 | /* Version ID, Channel plan */ | 1913 | /* Version ID, Channel plan */ |
1916 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1914 | rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; |
1917 | rtlefuse->txpwr_fromeprom = true; | 1915 | rtlefuse->txpwr_fromeprom = true; |
1918 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | 1916 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, |
1919 | "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); | 1917 | "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); |
1920 | 1918 | ||
1921 | /* Read Customer ID or Board Type!!! */ | 1919 | /* Read Customer ID or Board Type!!! */ |
1922 | tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; | 1920 | tempval = hwinfo[EEPROM_BOARDTYPE]; |
1923 | /* Change RF type definition */ | 1921 | /* Change RF type definition */ |
1924 | if (tempval == 0) | 1922 | if (tempval == 0) |
1925 | rtlphy->rf_type = RF_2T2R; | 1923 | rtlphy->rf_type = RF_2T2R; |
@@ -1941,7 +1939,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) | |||
1941 | } | 1939 | } |
1942 | } | 1940 | } |
1943 | rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; | 1941 | rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; |
1944 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; | 1942 | rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID]; |
1945 | 1943 | ||
1946 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", | 1944 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", |
1947 | rtlefuse->eeprom_oemid); | 1945 | rtlefuse->eeprom_oemid); |
@@ -2251,7 +2249,7 @@ void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw) | |||
2251 | u16 sifs_timer; | 2249 | u16 sifs_timer; |
2252 | 2250 | ||
2253 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | 2251 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, |
2254 | (u8 *)&mac->slot_time); | 2252 | &mac->slot_time); |
2255 | sifs_timer = 0x0e0e; | 2253 | sifs_timer = 0x0e0e; |
2256 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); | 2254 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); |
2257 | 2255 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 812b5858f14a..36d1cb3aef8a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -599,7 +599,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, | |||
599 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 599 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
600 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 600 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
601 | struct ieee80211_sta *sta = info->control.sta; | 601 | struct ieee80211_sta *sta = info->control.sta; |
602 | u8 *pdesc = (u8 *) pdesc_tx; | 602 | u8 *pdesc = pdesc_tx; |
603 | u16 seq_number; | 603 | u16 seq_number; |
604 | __le16 fc = hdr->frame_control; | 604 | __le16 fc = hdr->frame_control; |
605 | u8 reserved_macid = 0; | 605 | u8 reserved_macid = 0; |
diff --git a/drivers/net/wireless/ti/Kconfig b/drivers/net/wireless/ti/Kconfig index 1a72932e2213..be800119d0a3 100644 --- a/drivers/net/wireless/ti/Kconfig +++ b/drivers/net/wireless/ti/Kconfig | |||
@@ -8,6 +8,7 @@ menuconfig WL_TI | |||
8 | if WL_TI | 8 | if WL_TI |
9 | source "drivers/net/wireless/ti/wl1251/Kconfig" | 9 | source "drivers/net/wireless/ti/wl1251/Kconfig" |
10 | source "drivers/net/wireless/ti/wl12xx/Kconfig" | 10 | source "drivers/net/wireless/ti/wl12xx/Kconfig" |
11 | source "drivers/net/wireless/ti/wl18xx/Kconfig" | ||
11 | 12 | ||
12 | # keep last for automatic dependencies | 13 | # keep last for automatic dependencies |
13 | source "drivers/net/wireless/ti/wlcore/Kconfig" | 14 | source "drivers/net/wireless/ti/wlcore/Kconfig" |
diff --git a/drivers/net/wireless/ti/Makefile b/drivers/net/wireless/ti/Makefile index 0a565622d4a4..4d6823983c04 100644 --- a/drivers/net/wireless/ti/Makefile +++ b/drivers/net/wireless/ti/Makefile | |||
@@ -2,3 +2,4 @@ obj-$(CONFIG_WLCORE) += wlcore/ | |||
2 | obj-$(CONFIG_WL12XX) += wl12xx/ | 2 | obj-$(CONFIG_WL12XX) += wl12xx/ |
3 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/ | 3 | obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wlcore/ |
4 | obj-$(CONFIG_WL1251) += wl1251/ | 4 | obj-$(CONFIG_WL1251) += wl1251/ |
5 | obj-$(CONFIG_WL18XX) += wl18xx/ | ||
diff --git a/drivers/net/wireless/ti/wl12xx/Makefile b/drivers/net/wireless/ti/wl12xx/Makefile index 87f64b14db35..da509aa7d009 100644 --- a/drivers/net/wireless/ti/wl12xx/Makefile +++ b/drivers/net/wireless/ti/wl12xx/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | wl12xx-objs = main.o cmd.o acx.o | 1 | wl12xx-objs = main.o cmd.o acx.o debugfs.o |
2 | 2 | ||
3 | obj-$(CONFIG_WL12XX) += wl12xx.o | 3 | obj-$(CONFIG_WL12XX) += wl12xx.o |
diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h index d1f5aba0afce..2a26868b837d 100644 --- a/drivers/net/wireless/ti/wl12xx/acx.h +++ b/drivers/net/wireless/ti/wl12xx/acx.h | |||
@@ -24,6 +24,21 @@ | |||
24 | #define __WL12XX_ACX_H__ | 24 | #define __WL12XX_ACX_H__ |
25 | 25 | ||
26 | #include "../wlcore/wlcore.h" | 26 | #include "../wlcore/wlcore.h" |
27 | #include "../wlcore/acx.h" | ||
28 | |||
29 | #define WL12XX_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ | ||
30 | WL1271_ACX_INTR_INIT_COMPLETE | \ | ||
31 | WL1271_ACX_INTR_EVENT_A | \ | ||
32 | WL1271_ACX_INTR_EVENT_B | \ | ||
33 | WL1271_ACX_INTR_CMD_COMPLETE | \ | ||
34 | WL1271_ACX_INTR_HW_AVAILABLE | \ | ||
35 | WL1271_ACX_INTR_DATA) | ||
36 | |||
37 | #define WL12XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ | ||
38 | WL1271_ACX_INTR_EVENT_A | \ | ||
39 | WL1271_ACX_INTR_EVENT_B | \ | ||
40 | WL1271_ACX_INTR_HW_AVAILABLE | \ | ||
41 | WL1271_ACX_INTR_DATA) | ||
27 | 42 | ||
28 | struct wl1271_acx_host_config_bitmap { | 43 | struct wl1271_acx_host_config_bitmap { |
29 | struct acx_header header; | 44 | struct acx_header header; |
@@ -31,6 +46,228 @@ struct wl1271_acx_host_config_bitmap { | |||
31 | __le32 host_cfg_bitmap; | 46 | __le32 host_cfg_bitmap; |
32 | } __packed; | 47 | } __packed; |
33 | 48 | ||
49 | struct wl12xx_acx_tx_statistics { | ||
50 | __le32 internal_desc_overflow; | ||
51 | } __packed; | ||
52 | |||
53 | struct wl12xx_acx_rx_statistics { | ||
54 | __le32 out_of_mem; | ||
55 | __le32 hdr_overflow; | ||
56 | __le32 hw_stuck; | ||
57 | __le32 dropped; | ||
58 | __le32 fcs_err; | ||
59 | __le32 xfr_hint_trig; | ||
60 | __le32 path_reset; | ||
61 | __le32 reset_counter; | ||
62 | } __packed; | ||
63 | |||
64 | struct wl12xx_acx_dma_statistics { | ||
65 | __le32 rx_requested; | ||
66 | __le32 rx_errors; | ||
67 | __le32 tx_requested; | ||
68 | __le32 tx_errors; | ||
69 | } __packed; | ||
70 | |||
71 | struct wl12xx_acx_isr_statistics { | ||
72 | /* host command complete */ | ||
73 | __le32 cmd_cmplt; | ||
74 | |||
75 | /* fiqisr() */ | ||
76 | __le32 fiqs; | ||
77 | |||
78 | /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ | ||
79 | __le32 rx_headers; | ||
80 | |||
81 | /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ | ||
82 | __le32 rx_completes; | ||
83 | |||
84 | /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ | ||
85 | __le32 rx_mem_overflow; | ||
86 | |||
87 | /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ | ||
88 | __le32 rx_rdys; | ||
89 | |||
90 | /* irqisr() */ | ||
91 | __le32 irqs; | ||
92 | |||
93 | /* (INT_STS_ND & INT_TRIG_TX_PROC) */ | ||
94 | __le32 tx_procs; | ||
95 | |||
96 | /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ | ||
97 | __le32 decrypt_done; | ||
98 | |||
99 | /* (INT_STS_ND & INT_TRIG_DMA0) */ | ||
100 | __le32 dma0_done; | ||
101 | |||
102 | /* (INT_STS_ND & INT_TRIG_DMA1) */ | ||
103 | __le32 dma1_done; | ||
104 | |||
105 | /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ | ||
106 | __le32 tx_exch_complete; | ||
107 | |||
108 | /* (INT_STS_ND & INT_TRIG_COMMAND) */ | ||
109 | __le32 commands; | ||
110 | |||
111 | /* (INT_STS_ND & INT_TRIG_RX_PROC) */ | ||
112 | __le32 rx_procs; | ||
113 | |||
114 | /* (INT_STS_ND & INT_TRIG_PM_802) */ | ||
115 | __le32 hw_pm_mode_changes; | ||
116 | |||
117 | /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ | ||
118 | __le32 host_acknowledges; | ||
119 | |||
120 | /* (INT_STS_ND & INT_TRIG_PM_PCI) */ | ||
121 | __le32 pci_pm; | ||
122 | |||
123 | /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ | ||
124 | __le32 wakeups; | ||
125 | |||
126 | /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ | ||
127 | __le32 low_rssi; | ||
128 | } __packed; | ||
129 | |||
130 | struct wl12xx_acx_wep_statistics { | ||
131 | /* WEP address keys configured */ | ||
132 | __le32 addr_key_count; | ||
133 | |||
134 | /* default keys configured */ | ||
135 | __le32 default_key_count; | ||
136 | |||
137 | __le32 reserved; | ||
138 | |||
139 | /* number of times that WEP key not found on lookup */ | ||
140 | __le32 key_not_found; | ||
141 | |||
142 | /* number of times that WEP key decryption failed */ | ||
143 | __le32 decrypt_fail; | ||
144 | |||
145 | /* WEP packets decrypted */ | ||
146 | __le32 packets; | ||
147 | |||
148 | /* WEP decrypt interrupts */ | ||
149 | __le32 interrupt; | ||
150 | } __packed; | ||
151 | |||
152 | #define ACX_MISSED_BEACONS_SPREAD 10 | ||
153 | |||
154 | struct wl12xx_acx_pwr_statistics { | ||
155 | /* the amount of enters into power save mode (both PD & ELP) */ | ||
156 | __le32 ps_enter; | ||
157 | |||
158 | /* the amount of enters into ELP mode */ | ||
159 | __le32 elp_enter; | ||
160 | |||
161 | /* the amount of missing beacon interrupts to the host */ | ||
162 | __le32 missing_bcns; | ||
163 | |||
164 | /* the amount of wake on host-access times */ | ||
165 | __le32 wake_on_host; | ||
166 | |||
167 | /* the amount of wake on timer-expire */ | ||
168 | __le32 wake_on_timer_exp; | ||
169 | |||
170 | /* the number of packets that were transmitted with PS bit set */ | ||
171 | __le32 tx_with_ps; | ||
172 | |||
173 | /* the number of packets that were transmitted with PS bit clear */ | ||
174 | __le32 tx_without_ps; | ||
175 | |||
176 | /* the number of received beacons */ | ||
177 | __le32 rcvd_beacons; | ||
178 | |||
179 | /* the number of entering into PowerOn (power save off) */ | ||
180 | __le32 power_save_off; | ||
181 | |||
182 | /* the number of entries into power save mode */ | ||
183 | __le16 enable_ps; | ||
184 | |||
185 | /* | ||
186 | * the number of exits from power save, not including failed PS | ||
187 | * transitions | ||
188 | */ | ||
189 | __le16 disable_ps; | ||
190 | |||
191 | /* | ||
192 | * the number of times the TSF counter was adjusted because | ||
193 | * of drift | ||
194 | */ | ||
195 | __le32 fix_tsf_ps; | ||
196 | |||
197 | /* Gives statistics about the spread continuous missed beacons. | ||
198 | * The 16 LSB are dedicated for the PS mode. | ||
199 | * The 16 MSB are dedicated for the PS mode. | ||
200 | * cont_miss_bcns_spread[0] - single missed beacon. | ||
201 | * cont_miss_bcns_spread[1] - two continuous missed beacons. | ||
202 | * cont_miss_bcns_spread[2] - three continuous missed beacons. | ||
203 | * ... | ||
204 | * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. | ||
205 | */ | ||
206 | __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; | ||
207 | |||
208 | /* the number of beacons in awake mode */ | ||
209 | __le32 rcvd_awake_beacons; | ||
210 | } __packed; | ||
211 | |||
212 | struct wl12xx_acx_mic_statistics { | ||
213 | __le32 rx_pkts; | ||
214 | __le32 calc_failure; | ||
215 | } __packed; | ||
216 | |||
217 | struct wl12xx_acx_aes_statistics { | ||
218 | __le32 encrypt_fail; | ||
219 | __le32 decrypt_fail; | ||
220 | __le32 encrypt_packets; | ||
221 | __le32 decrypt_packets; | ||
222 | __le32 encrypt_interrupt; | ||
223 | __le32 decrypt_interrupt; | ||
224 | } __packed; | ||
225 | |||
226 | struct wl12xx_acx_event_statistics { | ||
227 | __le32 heart_beat; | ||
228 | __le32 calibration; | ||
229 | __le32 rx_mismatch; | ||
230 | __le32 rx_mem_empty; | ||
231 | __le32 rx_pool; | ||
232 | __le32 oom_late; | ||
233 | __le32 phy_transmit_error; | ||
234 | __le32 tx_stuck; | ||
235 | } __packed; | ||
236 | |||
237 | struct wl12xx_acx_ps_statistics { | ||
238 | __le32 pspoll_timeouts; | ||
239 | __le32 upsd_timeouts; | ||
240 | __le32 upsd_max_sptime; | ||
241 | __le32 upsd_max_apturn; | ||
242 | __le32 pspoll_max_apturn; | ||
243 | __le32 pspoll_utilization; | ||
244 | __le32 upsd_utilization; | ||
245 | } __packed; | ||
246 | |||
247 | struct wl12xx_acx_rxpipe_statistics { | ||
248 | __le32 rx_prep_beacon_drop; | ||
249 | __le32 descr_host_int_trig_rx_data; | ||
250 | __le32 beacon_buffer_thres_host_int_trig_rx_data; | ||
251 | __le32 missed_beacon_host_int_trig_rx_data; | ||
252 | __le32 tx_xfr_host_int_trig_rx_data; | ||
253 | } __packed; | ||
254 | |||
255 | struct wl12xx_acx_statistics { | ||
256 | struct acx_header header; | ||
257 | |||
258 | struct wl12xx_acx_tx_statistics tx; | ||
259 | struct wl12xx_acx_rx_statistics rx; | ||
260 | struct wl12xx_acx_dma_statistics dma; | ||
261 | struct wl12xx_acx_isr_statistics isr; | ||
262 | struct wl12xx_acx_wep_statistics wep; | ||
263 | struct wl12xx_acx_pwr_statistics pwr; | ||
264 | struct wl12xx_acx_aes_statistics aes; | ||
265 | struct wl12xx_acx_mic_statistics mic; | ||
266 | struct wl12xx_acx_event_statistics event; | ||
267 | struct wl12xx_acx_ps_statistics ps; | ||
268 | struct wl12xx_acx_rxpipe_statistics rxpipe; | ||
269 | } __packed; | ||
270 | |||
34 | int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); | 271 | int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); |
35 | 272 | ||
36 | #endif /* __WL12XX_ACX_H__ */ | 273 | #endif /* __WL12XX_ACX_H__ */ |
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 8ffaeb5f2147..50ba7480b790 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c | |||
@@ -65,6 +65,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) | |||
65 | struct wl1271_general_parms_cmd *gen_parms; | 65 | struct wl1271_general_parms_cmd *gen_parms; |
66 | struct wl1271_ini_general_params *gp = | 66 | struct wl1271_ini_general_params *gp = |
67 | &((struct wl1271_nvs_file *)wl->nvs)->general_params; | 67 | &((struct wl1271_nvs_file *)wl->nvs)->general_params; |
68 | struct wl12xx_priv *priv = wl->priv; | ||
68 | bool answer = false; | 69 | bool answer = false; |
69 | int ret; | 70 | int ret; |
70 | 71 | ||
@@ -88,7 +89,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) | |||
88 | answer = true; | 89 | answer = true; |
89 | 90 | ||
90 | /* Override the REF CLK from the NVS with the one from platform data */ | 91 | /* Override the REF CLK from the NVS with the one from platform data */ |
91 | gen_parms->general_params.ref_clock = wl->ref_clock; | 92 | gen_parms->general_params.ref_clock = priv->ref_clock; |
92 | 93 | ||
93 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); | 94 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); |
94 | if (ret < 0) { | 95 | if (ret < 0) { |
@@ -118,6 +119,7 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) | |||
118 | struct wl128x_general_parms_cmd *gen_parms; | 119 | struct wl128x_general_parms_cmd *gen_parms; |
119 | struct wl128x_ini_general_params *gp = | 120 | struct wl128x_ini_general_params *gp = |
120 | &((struct wl128x_nvs_file *)wl->nvs)->general_params; | 121 | &((struct wl128x_nvs_file *)wl->nvs)->general_params; |
122 | struct wl12xx_priv *priv = wl->priv; | ||
121 | bool answer = false; | 123 | bool answer = false; |
122 | int ret; | 124 | int ret; |
123 | 125 | ||
@@ -141,8 +143,8 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) | |||
141 | answer = true; | 143 | answer = true; |
142 | 144 | ||
143 | /* Replace REF and TCXO CLKs with the ones from platform data */ | 145 | /* Replace REF and TCXO CLKs with the ones from platform data */ |
144 | gen_parms->general_params.ref_clock = wl->ref_clock; | 146 | gen_parms->general_params.ref_clock = priv->ref_clock; |
145 | gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock; | 147 | gen_parms->general_params.tcxo_ref_clock = priv->tcxo_clock; |
146 | 148 | ||
147 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); | 149 | ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); |
148 | if (ret < 0) { | 150 | if (ret < 0) { |
diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.c b/drivers/net/wireless/ti/wl12xx/debugfs.c new file mode 100644 index 000000000000..0521cbf858cf --- /dev/null +++ b/drivers/net/wireless/ti/wl12xx/debugfs.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * This file is part of wl12xx | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Copyright (C) 2011-2012 Texas Instruments | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "../wlcore/debugfs.h" | ||
24 | #include "../wlcore/wlcore.h" | ||
25 | |||
26 | #include "wl12xx.h" | ||
27 | #include "acx.h" | ||
28 | #include "debugfs.h" | ||
29 | |||
30 | #define WL12XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ | ||
31 | DEBUGFS_FWSTATS_FILE(a, b, c, wl12xx_acx_statistics) | ||
32 | |||
33 | WL12XX_DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); | ||
34 | |||
35 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); | ||
36 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); | ||
37 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); | ||
38 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); | ||
39 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); | ||
40 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); | ||
41 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); | ||
42 | WL12XX_DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); | ||
43 | |||
44 | WL12XX_DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); | ||
45 | WL12XX_DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); | ||
46 | WL12XX_DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); | ||
47 | WL12XX_DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); | ||
48 | |||
49 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); | ||
50 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); | ||
51 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); | ||
52 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); | ||
53 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); | ||
54 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); | ||
55 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); | ||
56 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); | ||
57 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); | ||
58 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); | ||
59 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); | ||
60 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); | ||
61 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); | ||
62 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); | ||
63 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); | ||
64 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); | ||
65 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); | ||
66 | WL12XX_DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); | ||
67 | |||
68 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); | ||
69 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); | ||
70 | /* skipping wep.reserved */ | ||
71 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); | ||
72 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); | ||
73 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); | ||
74 | WL12XX_DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); | ||
75 | |||
76 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); | ||
77 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); | ||
78 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); | ||
79 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); | ||
80 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); | ||
81 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); | ||
82 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); | ||
83 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); | ||
84 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); | ||
85 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); | ||
86 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); | ||
87 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); | ||
88 | /* skipping cont_miss_bcns_spread for now */ | ||
89 | WL12XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); | ||
90 | |||
91 | WL12XX_DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); | ||
92 | WL12XX_DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); | ||
93 | |||
94 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); | ||
95 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); | ||
96 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); | ||
97 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); | ||
98 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); | ||
99 | WL12XX_DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); | ||
100 | |||
101 | WL12XX_DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); | ||
102 | WL12XX_DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); | ||
103 | WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); | ||
104 | WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); | ||
105 | WL12XX_DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); | ||
106 | WL12XX_DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); | ||
107 | WL12XX_DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); | ||
108 | WL12XX_DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); | ||
109 | |||
110 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); | ||
111 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); | ||
112 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); | ||
113 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); | ||
114 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); | ||
115 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); | ||
116 | WL12XX_DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); | ||
117 | |||
118 | WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); | ||
119 | WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); | ||
120 | WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, | ||
121 | "%u"); | ||
122 | WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); | ||
123 | WL12XX_DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); | ||
124 | |||
125 | int wl12xx_debugfs_add_files(struct wl1271 *wl, | ||
126 | struct dentry *rootdir) | ||
127 | { | ||
128 | int ret = 0; | ||
129 | struct dentry *entry, *stats, *moddir; | ||
130 | |||
131 | moddir = debugfs_create_dir(KBUILD_MODNAME, rootdir); | ||
132 | if (!moddir || IS_ERR(moddir)) { | ||
133 | entry = moddir; | ||
134 | goto err; | ||
135 | } | ||
136 | |||
137 | stats = debugfs_create_dir("fw_stats", moddir); | ||
138 | if (!stats || IS_ERR(stats)) { | ||
139 | entry = stats; | ||
140 | goto err; | ||
141 | } | ||
142 | |||
143 | DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); | ||
144 | |||
145 | DEBUGFS_FWSTATS_ADD(rx, out_of_mem); | ||
146 | DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); | ||
147 | DEBUGFS_FWSTATS_ADD(rx, hw_stuck); | ||
148 | DEBUGFS_FWSTATS_ADD(rx, dropped); | ||
149 | DEBUGFS_FWSTATS_ADD(rx, fcs_err); | ||
150 | DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); | ||
151 | DEBUGFS_FWSTATS_ADD(rx, path_reset); | ||
152 | DEBUGFS_FWSTATS_ADD(rx, reset_counter); | ||
153 | |||
154 | DEBUGFS_FWSTATS_ADD(dma, rx_requested); | ||
155 | DEBUGFS_FWSTATS_ADD(dma, rx_errors); | ||
156 | DEBUGFS_FWSTATS_ADD(dma, tx_requested); | ||
157 | DEBUGFS_FWSTATS_ADD(dma, tx_errors); | ||
158 | |||
159 | DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); | ||
160 | DEBUGFS_FWSTATS_ADD(isr, fiqs); | ||
161 | DEBUGFS_FWSTATS_ADD(isr, rx_headers); | ||
162 | DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); | ||
163 | DEBUGFS_FWSTATS_ADD(isr, rx_rdys); | ||
164 | DEBUGFS_FWSTATS_ADD(isr, irqs); | ||
165 | DEBUGFS_FWSTATS_ADD(isr, tx_procs); | ||
166 | DEBUGFS_FWSTATS_ADD(isr, decrypt_done); | ||
167 | DEBUGFS_FWSTATS_ADD(isr, dma0_done); | ||
168 | DEBUGFS_FWSTATS_ADD(isr, dma1_done); | ||
169 | DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); | ||
170 | DEBUGFS_FWSTATS_ADD(isr, commands); | ||
171 | DEBUGFS_FWSTATS_ADD(isr, rx_procs); | ||
172 | DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); | ||
173 | DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); | ||
174 | DEBUGFS_FWSTATS_ADD(isr, pci_pm); | ||
175 | DEBUGFS_FWSTATS_ADD(isr, wakeups); | ||
176 | DEBUGFS_FWSTATS_ADD(isr, low_rssi); | ||
177 | |||
178 | DEBUGFS_FWSTATS_ADD(wep, addr_key_count); | ||
179 | DEBUGFS_FWSTATS_ADD(wep, default_key_count); | ||
180 | /* skipping wep.reserved */ | ||
181 | DEBUGFS_FWSTATS_ADD(wep, key_not_found); | ||
182 | DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); | ||
183 | DEBUGFS_FWSTATS_ADD(wep, packets); | ||
184 | DEBUGFS_FWSTATS_ADD(wep, interrupt); | ||
185 | |||
186 | DEBUGFS_FWSTATS_ADD(pwr, ps_enter); | ||
187 | DEBUGFS_FWSTATS_ADD(pwr, elp_enter); | ||
188 | DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); | ||
189 | DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); | ||
190 | DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); | ||
191 | DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); | ||
192 | DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); | ||
193 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); | ||
194 | DEBUGFS_FWSTATS_ADD(pwr, power_save_off); | ||
195 | DEBUGFS_FWSTATS_ADD(pwr, enable_ps); | ||
196 | DEBUGFS_FWSTATS_ADD(pwr, disable_ps); | ||
197 | DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); | ||
198 | /* skipping cont_miss_bcns_spread for now */ | ||
199 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); | ||
200 | |||
201 | DEBUGFS_FWSTATS_ADD(mic, rx_pkts); | ||
202 | DEBUGFS_FWSTATS_ADD(mic, calc_failure); | ||
203 | |||
204 | DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); | ||
205 | DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); | ||
206 | DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); | ||
207 | DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); | ||
208 | DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); | ||
209 | DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); | ||
210 | |||
211 | DEBUGFS_FWSTATS_ADD(event, heart_beat); | ||
212 | DEBUGFS_FWSTATS_ADD(event, calibration); | ||
213 | DEBUGFS_FWSTATS_ADD(event, rx_mismatch); | ||
214 | DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); | ||
215 | DEBUGFS_FWSTATS_ADD(event, rx_pool); | ||
216 | DEBUGFS_FWSTATS_ADD(event, oom_late); | ||
217 | DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); | ||
218 | DEBUGFS_FWSTATS_ADD(event, tx_stuck); | ||
219 | |||
220 | DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); | ||
221 | DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); | ||
222 | DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); | ||
223 | DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); | ||
224 | DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); | ||
225 | DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); | ||
226 | DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); | ||
227 | |||
228 | DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); | ||
229 | DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); | ||
230 | DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); | ||
231 | DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); | ||
232 | DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); | ||
233 | |||
234 | return 0; | ||
235 | |||
236 | err: | ||
237 | if (IS_ERR(entry)) | ||
238 | ret = PTR_ERR(entry); | ||
239 | else | ||
240 | ret = -ENOMEM; | ||
241 | |||
242 | return ret; | ||
243 | } | ||
diff --git a/drivers/net/wireless/ti/wl12xx/debugfs.h b/drivers/net/wireless/ti/wl12xx/debugfs.h new file mode 100644 index 000000000000..96898e291b78 --- /dev/null +++ b/drivers/net/wireless/ti/wl12xx/debugfs.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * This file is part of wl12xx | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL12XX_DEBUGFS_H__ | ||
23 | #define __WL12XX_DEBUGFS_H__ | ||
24 | |||
25 | int wl12xx_debugfs_add_files(struct wl1271 *wl, | ||
26 | struct dentry *rootdir); | ||
27 | |||
28 | #endif /* __WL12XX_DEBUGFS_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index d7dd3def07b5..85d1600ee340 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c | |||
@@ -39,6 +39,10 @@ | |||
39 | #include "reg.h" | 39 | #include "reg.h" |
40 | #include "cmd.h" | 40 | #include "cmd.h" |
41 | #include "acx.h" | 41 | #include "acx.h" |
42 | #include "debugfs.h" | ||
43 | |||
44 | static char *fref_param; | ||
45 | static char *tcxo_param; | ||
42 | 46 | ||
43 | static struct wlcore_conf wl12xx_conf = { | 47 | static struct wlcore_conf wl12xx_conf = { |
44 | .sg = { | 48 | .sg = { |
@@ -212,7 +216,7 @@ static struct wlcore_conf wl12xx_conf = { | |||
212 | .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, | 216 | .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, |
213 | .suspend_listen_interval = 3, | 217 | .suspend_listen_interval = 3, |
214 | .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, | 218 | .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, |
215 | .bcn_filt_ie_count = 2, | 219 | .bcn_filt_ie_count = 3, |
216 | .bcn_filt_ie = { | 220 | .bcn_filt_ie = { |
217 | [0] = { | 221 | [0] = { |
218 | .ie = WLAN_EID_CHANNEL_SWITCH, | 222 | .ie = WLAN_EID_CHANNEL_SWITCH, |
@@ -222,9 +226,13 @@ static struct wlcore_conf wl12xx_conf = { | |||
222 | .ie = WLAN_EID_HT_OPERATION, | 226 | .ie = WLAN_EID_HT_OPERATION, |
223 | .rule = CONF_BCN_RULE_PASS_ON_CHANGE, | 227 | .rule = CONF_BCN_RULE_PASS_ON_CHANGE, |
224 | }, | 228 | }, |
229 | [2] = { | ||
230 | .ie = WLAN_EID_ERP_INFO, | ||
231 | .rule = CONF_BCN_RULE_PASS_ON_CHANGE, | ||
232 | }, | ||
225 | }, | 233 | }, |
226 | .synch_fail_thold = 10, | 234 | .synch_fail_thold = 12, |
227 | .bss_lose_timeout = 100, | 235 | .bss_lose_timeout = 400, |
228 | .beacon_rx_timeout = 10000, | 236 | .beacon_rx_timeout = 10000, |
229 | .broadcast_timeout = 20000, | 237 | .broadcast_timeout = 20000, |
230 | .rx_broadcast_in_ps = 1, | 238 | .rx_broadcast_in_ps = 1, |
@@ -234,7 +242,7 @@ static struct wlcore_conf wl12xx_conf = { | |||
234 | .psm_entry_retries = 8, | 242 | .psm_entry_retries = 8, |
235 | .psm_exit_retries = 16, | 243 | .psm_exit_retries = 16, |
236 | .psm_entry_nullfunc_retries = 3, | 244 | .psm_entry_nullfunc_retries = 3, |
237 | .dynamic_ps_timeout = 40, | 245 | .dynamic_ps_timeout = 200, |
238 | .forced_ps = false, | 246 | .forced_ps = false, |
239 | .keep_alive_interval = 55000, | 247 | .keep_alive_interval = 55000, |
240 | .max_listen_interval = 20, | 248 | .max_listen_interval = 20, |
@@ -245,7 +253,7 @@ static struct wlcore_conf wl12xx_conf = { | |||
245 | }, | 253 | }, |
246 | .pm_config = { | 254 | .pm_config = { |
247 | .host_clk_settling_time = 5000, | 255 | .host_clk_settling_time = 5000, |
248 | .host_fast_wakeup_support = false | 256 | .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE, |
249 | }, | 257 | }, |
250 | .roam_trigger = { | 258 | .roam_trigger = { |
251 | .trigger_pacing = 1, | 259 | .trigger_pacing = 1, |
@@ -305,8 +313,8 @@ static struct wlcore_conf wl12xx_conf = { | |||
305 | .swallow_period = 5, | 313 | .swallow_period = 5, |
306 | .n_divider_fref_set_1 = 0xff, /* default */ | 314 | .n_divider_fref_set_1 = 0xff, /* default */ |
307 | .n_divider_fref_set_2 = 12, | 315 | .n_divider_fref_set_2 = 12, |
308 | .m_divider_fref_set_1 = 148, | 316 | .m_divider_fref_set_1 = 0xffff, |
309 | .m_divider_fref_set_2 = 0xffff, /* default */ | 317 | .m_divider_fref_set_2 = 148, /* default */ |
310 | .coex_pll_stabilization_time = 0xffffffff, /* default */ | 318 | .coex_pll_stabilization_time = 0xffffffff, /* default */ |
311 | .ldo_stabilization_time = 0xffff, /* default */ | 319 | .ldo_stabilization_time = 0xffff, /* default */ |
312 | .fm_disturbed_band_margin = 0xff, /* default */ | 320 | .fm_disturbed_band_margin = 0xff, /* default */ |
@@ -593,7 +601,7 @@ static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) | |||
593 | { | 601 | { |
594 | if (wl->chip.id != CHIP_ID_1283_PG20) { | 602 | if (wl->chip.id != CHIP_ID_1283_PG20) { |
595 | struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; | 603 | struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; |
596 | struct wl1271_rx_mem_pool_addr rx_mem_addr; | 604 | struct wl127x_rx_mem_pool_addr rx_mem_addr; |
597 | 605 | ||
598 | /* | 606 | /* |
599 | * Choose the block we want to read | 607 | * Choose the block we want to read |
@@ -621,10 +629,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) | |||
621 | wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", | 629 | wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete", |
622 | wl->chip.id); | 630 | wl->chip.id); |
623 | 631 | ||
624 | /* clear the alignment quirk, since we don't support it */ | 632 | wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | |
625 | wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; | 633 | WLCORE_QUIRK_TKIP_HEADER_SPACE; |
626 | |||
627 | wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; | ||
628 | wl->sr_fw_name = WL127X_FW_NAME_SINGLE; | 634 | wl->sr_fw_name = WL127X_FW_NAME_SINGLE; |
629 | wl->mr_fw_name = WL127X_FW_NAME_MULTI; | 635 | wl->mr_fw_name = WL127X_FW_NAME_MULTI; |
630 | memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x, | 636 | memcpy(&wl->conf.mem, &wl12xx_default_priv_conf.mem_wl127x, |
@@ -639,10 +645,8 @@ static int wl12xx_identify_chip(struct wl1271 *wl) | |||
639 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", | 645 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)", |
640 | wl->chip.id); | 646 | wl->chip.id); |
641 | 647 | ||
642 | /* clear the alignment quirk, since we don't support it */ | 648 | wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | |
643 | wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; | 649 | WLCORE_QUIRK_TKIP_HEADER_SPACE; |
644 | |||
645 | wl->quirks |= WLCORE_QUIRK_LEGACY_NVS; | ||
646 | wl->plt_fw_name = WL127X_PLT_FW_NAME; | 650 | wl->plt_fw_name = WL127X_PLT_FW_NAME; |
647 | wl->sr_fw_name = WL127X_FW_NAME_SINGLE; | 651 | wl->sr_fw_name = WL127X_FW_NAME_SINGLE; |
648 | wl->mr_fw_name = WL127X_FW_NAME_MULTI; | 652 | wl->mr_fw_name = WL127X_FW_NAME_MULTI; |
@@ -660,6 +664,11 @@ static int wl12xx_identify_chip(struct wl1271 *wl) | |||
660 | wl->plt_fw_name = WL128X_PLT_FW_NAME; | 664 | wl->plt_fw_name = WL128X_PLT_FW_NAME; |
661 | wl->sr_fw_name = WL128X_FW_NAME_SINGLE; | 665 | wl->sr_fw_name = WL128X_FW_NAME_SINGLE; |
662 | wl->mr_fw_name = WL128X_FW_NAME_MULTI; | 666 | wl->mr_fw_name = WL128X_FW_NAME_MULTI; |
667 | |||
668 | /* wl128x requires TX blocksize alignment */ | ||
669 | wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | | ||
670 | WLCORE_QUIRK_TKIP_HEADER_SPACE; | ||
671 | |||
663 | break; | 672 | break; |
664 | case CHIP_ID_1283_PG10: | 673 | case CHIP_ID_1283_PG10: |
665 | default: | 674 | default: |
@@ -773,6 +782,7 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) | |||
773 | u16 spare_reg; | 782 | u16 spare_reg; |
774 | u16 pll_config; | 783 | u16 pll_config; |
775 | u8 input_freq; | 784 | u8 input_freq; |
785 | struct wl12xx_priv *priv = wl->priv; | ||
776 | 786 | ||
777 | /* Mask bits [3:1] in the sys_clk_cfg register */ | 787 | /* Mask bits [3:1] in the sys_clk_cfg register */ |
778 | spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); | 788 | spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); |
@@ -782,8 +792,8 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) | |||
782 | wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); | 792 | wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); |
783 | 793 | ||
784 | /* Handle special cases of the TCXO clock */ | 794 | /* Handle special cases of the TCXO clock */ |
785 | if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || | 795 | if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || |
786 | wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6) | 796 | priv->tcxo_clock == WL12XX_TCXOCLOCK_33_6) |
787 | return wl128x_manually_configure_mcs_pll(wl); | 797 | return wl128x_manually_configure_mcs_pll(wl); |
788 | 798 | ||
789 | /* Set the input frequency according to the selected clock source */ | 799 | /* Set the input frequency according to the selected clock source */ |
@@ -808,11 +818,12 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) | |||
808 | */ | 818 | */ |
809 | static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) | 819 | static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) |
810 | { | 820 | { |
821 | struct wl12xx_priv *priv = wl->priv; | ||
811 | u16 sys_clk_cfg; | 822 | u16 sys_clk_cfg; |
812 | 823 | ||
813 | /* For XTAL-only modes, FREF will be used after switching from TCXO */ | 824 | /* For XTAL-only modes, FREF will be used after switching from TCXO */ |
814 | if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL || | 825 | if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL || |
815 | wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) { | 826 | priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) { |
816 | if (!wl128x_switch_tcxo_to_fref(wl)) | 827 | if (!wl128x_switch_tcxo_to_fref(wl)) |
817 | return -EINVAL; | 828 | return -EINVAL; |
818 | goto fref_clk; | 829 | goto fref_clk; |
@@ -826,8 +837,8 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) | |||
826 | goto fref_clk; | 837 | goto fref_clk; |
827 | 838 | ||
828 | /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */ | 839 | /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */ |
829 | if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || | 840 | if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_368 || |
830 | wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { | 841 | priv->tcxo_clock == WL12XX_TCXOCLOCK_32_736) { |
831 | if (!wl128x_switch_tcxo_to_fref(wl)) | 842 | if (!wl128x_switch_tcxo_to_fref(wl)) |
832 | return -EINVAL; | 843 | return -EINVAL; |
833 | goto fref_clk; | 844 | goto fref_clk; |
@@ -836,14 +847,14 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) | |||
836 | /* TCXO clock is selected */ | 847 | /* TCXO clock is selected */ |
837 | if (!wl128x_is_tcxo_valid(wl)) | 848 | if (!wl128x_is_tcxo_valid(wl)) |
838 | return -EINVAL; | 849 | return -EINVAL; |
839 | *selected_clock = wl->tcxo_clock; | 850 | *selected_clock = priv->tcxo_clock; |
840 | goto config_mcs_pll; | 851 | goto config_mcs_pll; |
841 | 852 | ||
842 | fref_clk: | 853 | fref_clk: |
843 | /* FREF clock is selected */ | 854 | /* FREF clock is selected */ |
844 | if (!wl128x_is_fref_valid(wl)) | 855 | if (!wl128x_is_fref_valid(wl)) |
845 | return -EINVAL; | 856 | return -EINVAL; |
846 | *selected_clock = wl->ref_clock; | 857 | *selected_clock = priv->ref_clock; |
847 | 858 | ||
848 | config_mcs_pll: | 859 | config_mcs_pll: |
849 | return wl128x_configure_mcs_pll(wl, *selected_clock); | 860 | return wl128x_configure_mcs_pll(wl, *selected_clock); |
@@ -851,25 +862,27 @@ config_mcs_pll: | |||
851 | 862 | ||
852 | static int wl127x_boot_clk(struct wl1271 *wl) | 863 | static int wl127x_boot_clk(struct wl1271 *wl) |
853 | { | 864 | { |
865 | struct wl12xx_priv *priv = wl->priv; | ||
854 | u32 pause; | 866 | u32 pause; |
855 | u32 clk; | 867 | u32 clk; |
856 | 868 | ||
857 | if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) | 869 | if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) |
858 | wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; | 870 | wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; |
859 | 871 | ||
860 | if (wl->ref_clock == CONF_REF_CLK_19_2_E || | 872 | if (priv->ref_clock == CONF_REF_CLK_19_2_E || |
861 | wl->ref_clock == CONF_REF_CLK_38_4_E || | 873 | priv->ref_clock == CONF_REF_CLK_38_4_E || |
862 | wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL) | 874 | priv->ref_clock == CONF_REF_CLK_38_4_M_XTAL) |
863 | /* ref clk: 19.2/38.4/38.4-XTAL */ | 875 | /* ref clk: 19.2/38.4/38.4-XTAL */ |
864 | clk = 0x3; | 876 | clk = 0x3; |
865 | else if (wl->ref_clock == CONF_REF_CLK_26_E || | 877 | else if (priv->ref_clock == CONF_REF_CLK_26_E || |
866 | wl->ref_clock == CONF_REF_CLK_52_E) | 878 | priv->ref_clock == CONF_REF_CLK_26_M_XTAL || |
879 | priv->ref_clock == CONF_REF_CLK_52_E) | ||
867 | /* ref clk: 26/52 */ | 880 | /* ref clk: 26/52 */ |
868 | clk = 0x5; | 881 | clk = 0x5; |
869 | else | 882 | else |
870 | return -EINVAL; | 883 | return -EINVAL; |
871 | 884 | ||
872 | if (wl->ref_clock != CONF_REF_CLK_19_2_E) { | 885 | if (priv->ref_clock != CONF_REF_CLK_19_2_E) { |
873 | u16 val; | 886 | u16 val; |
874 | /* Set clock type (open drain) */ | 887 | /* Set clock type (open drain) */ |
875 | val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE); | 888 | val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE); |
@@ -939,6 +952,7 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) | |||
939 | 952 | ||
940 | static int wl12xx_pre_boot(struct wl1271 *wl) | 953 | static int wl12xx_pre_boot(struct wl1271 *wl) |
941 | { | 954 | { |
955 | struct wl12xx_priv *priv = wl->priv; | ||
942 | int ret = 0; | 956 | int ret = 0; |
943 | u32 clk; | 957 | u32 clk; |
944 | int selected_clock = -1; | 958 | int selected_clock = -1; |
@@ -970,7 +984,7 @@ static int wl12xx_pre_boot(struct wl1271 *wl) | |||
970 | if (wl->chip.id == CHIP_ID_1283_PG20) | 984 | if (wl->chip.id == CHIP_ID_1283_PG20) |
971 | clk |= ((selected_clock & 0x3) << 1) << 4; | 985 | clk |= ((selected_clock & 0x3) << 1) << 4; |
972 | else | 986 | else |
973 | clk |= (wl->ref_clock << 1) << 4; | 987 | clk |= (priv->ref_clock << 1) << 4; |
974 | 988 | ||
975 | wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); | 989 | wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); |
976 | 990 | ||
@@ -989,7 +1003,7 @@ out: | |||
989 | 1003 | ||
990 | static void wl12xx_pre_upload(struct wl1271 *wl) | 1004 | static void wl12xx_pre_upload(struct wl1271 *wl) |
991 | { | 1005 | { |
992 | u32 tmp; | 1006 | u32 tmp, polarity; |
993 | 1007 | ||
994 | /* write firmware's last address (ie. it's length) to | 1008 | /* write firmware's last address (ie. it's length) to |
995 | * ACX_EEPROMLESS_IND_REG */ | 1009 | * ACX_EEPROMLESS_IND_REG */ |
@@ -1009,23 +1023,23 @@ static void wl12xx_pre_upload(struct wl1271 *wl) | |||
1009 | 1023 | ||
1010 | if (wl->chip.id == CHIP_ID_1283_PG20) | 1024 | if (wl->chip.id == CHIP_ID_1283_PG20) |
1011 | wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); | 1025 | wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); |
1012 | } | ||
1013 | |||
1014 | static void wl12xx_enable_interrupts(struct wl1271 *wl) | ||
1015 | { | ||
1016 | u32 polarity; | ||
1017 | 1026 | ||
1027 | /* polarity must be set before the firmware is loaded */ | ||
1018 | polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY); | 1028 | polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY); |
1019 | 1029 | ||
1020 | /* We use HIGH polarity, so unset the LOW bit */ | 1030 | /* We use HIGH polarity, so unset the LOW bit */ |
1021 | polarity &= ~POLARITY_LOW; | 1031 | polarity &= ~POLARITY_LOW; |
1022 | wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); | 1032 | wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); |
1023 | 1033 | ||
1024 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); | 1034 | } |
1035 | |||
1036 | static void wl12xx_enable_interrupts(struct wl1271 *wl) | ||
1037 | { | ||
1038 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR); | ||
1025 | 1039 | ||
1026 | wlcore_enable_interrupts(wl); | 1040 | wlcore_enable_interrupts(wl); |
1027 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, | 1041 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, |
1028 | WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); | 1042 | WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); |
1029 | 1043 | ||
1030 | wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); | 1044 | wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); |
1031 | } | 1045 | } |
@@ -1149,7 +1163,8 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, | |||
1149 | 1163 | ||
1150 | static void wl12xx_tx_delayed_compl(struct wl1271 *wl) | 1164 | static void wl12xx_tx_delayed_compl(struct wl1271 *wl) |
1151 | { | 1165 | { |
1152 | if (wl->fw_status->tx_results_counter == (wl->tx_results_count & 0xff)) | 1166 | if (wl->fw_status_1->tx_results_counter == |
1167 | (wl->tx_results_count & 0xff)) | ||
1153 | return; | 1168 | return; |
1154 | 1169 | ||
1155 | wl1271_tx_complete(wl); | 1170 | wl1271_tx_complete(wl); |
@@ -1288,10 +1303,90 @@ static void wl12xx_get_mac(struct wl1271 *wl) | |||
1288 | wl12xx_get_fuse_mac(wl); | 1303 | wl12xx_get_fuse_mac(wl); |
1289 | } | 1304 | } |
1290 | 1305 | ||
1306 | static void wl12xx_set_tx_desc_csum(struct wl1271 *wl, | ||
1307 | struct wl1271_tx_hw_descr *desc, | ||
1308 | struct sk_buff *skb) | ||
1309 | { | ||
1310 | desc->wl12xx_reserved = 0; | ||
1311 | } | ||
1312 | |||
1313 | static int wl12xx_plt_init(struct wl1271 *wl) | ||
1314 | { | ||
1315 | int ret; | ||
1316 | |||
1317 | ret = wl->ops->boot(wl); | ||
1318 | if (ret < 0) | ||
1319 | goto out; | ||
1320 | |||
1321 | ret = wl->ops->hw_init(wl); | ||
1322 | if (ret < 0) | ||
1323 | goto out_irq_disable; | ||
1324 | |||
1325 | ret = wl1271_acx_init_mem_config(wl); | ||
1326 | if (ret < 0) | ||
1327 | goto out_irq_disable; | ||
1328 | |||
1329 | ret = wl12xx_acx_mem_cfg(wl); | ||
1330 | if (ret < 0) | ||
1331 | goto out_free_memmap; | ||
1332 | |||
1333 | /* Enable data path */ | ||
1334 | ret = wl1271_cmd_data_path(wl, 1); | ||
1335 | if (ret < 0) | ||
1336 | goto out_free_memmap; | ||
1337 | |||
1338 | /* Configure for CAM power saving (ie. always active) */ | ||
1339 | ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); | ||
1340 | if (ret < 0) | ||
1341 | goto out_free_memmap; | ||
1342 | |||
1343 | /* configure PM */ | ||
1344 | ret = wl1271_acx_pm_config(wl); | ||
1345 | if (ret < 0) | ||
1346 | goto out_free_memmap; | ||
1347 | |||
1348 | goto out; | ||
1349 | |||
1350 | out_free_memmap: | ||
1351 | kfree(wl->target_mem_map); | ||
1352 | wl->target_mem_map = NULL; | ||
1353 | |||
1354 | out_irq_disable: | ||
1355 | mutex_unlock(&wl->mutex); | ||
1356 | /* Unlocking the mutex in the middle of handling is | ||
1357 | inherently unsafe. In this case we deem it safe to do, | ||
1358 | because we need to let any possibly pending IRQ out of | ||
1359 | the system (and while we are WL1271_STATE_OFF the IRQ | ||
1360 | work function will not do anything.) Also, any other | ||
1361 | possible concurrent operations will fail due to the | ||
1362 | current state, hence the wl1271 struct should be safe. */ | ||
1363 | wlcore_disable_interrupts(wl); | ||
1364 | mutex_lock(&wl->mutex); | ||
1365 | out: | ||
1366 | return ret; | ||
1367 | } | ||
1368 | |||
1369 | static int wl12xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
1370 | { | ||
1371 | if (is_gem) | ||
1372 | return WL12XX_TX_HW_BLOCK_GEM_SPARE; | ||
1373 | |||
1374 | return WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; | ||
1375 | } | ||
1376 | |||
1377 | static int wl12xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd, | ||
1378 | struct ieee80211_vif *vif, | ||
1379 | struct ieee80211_sta *sta, | ||
1380 | struct ieee80211_key_conf *key_conf) | ||
1381 | { | ||
1382 | return wlcore_set_key(wl, cmd, vif, sta, key_conf); | ||
1383 | } | ||
1384 | |||
1291 | static struct wlcore_ops wl12xx_ops = { | 1385 | static struct wlcore_ops wl12xx_ops = { |
1292 | .identify_chip = wl12xx_identify_chip, | 1386 | .identify_chip = wl12xx_identify_chip, |
1293 | .identify_fw = wl12xx_identify_fw, | 1387 | .identify_fw = wl12xx_identify_fw, |
1294 | .boot = wl12xx_boot, | 1388 | .boot = wl12xx_boot, |
1389 | .plt_init = wl12xx_plt_init, | ||
1295 | .trigger_cmd = wl12xx_trigger_cmd, | 1390 | .trigger_cmd = wl12xx_trigger_cmd, |
1296 | .ack_event = wl12xx_ack_event, | 1391 | .ack_event = wl12xx_ack_event, |
1297 | .calc_tx_blocks = wl12xx_calc_tx_blocks, | 1392 | .calc_tx_blocks = wl12xx_calc_tx_blocks, |
@@ -1306,6 +1401,13 @@ static struct wlcore_ops wl12xx_ops = { | |||
1306 | .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask, | 1401 | .sta_get_ap_rate_mask = wl12xx_sta_get_ap_rate_mask, |
1307 | .get_pg_ver = wl12xx_get_pg_ver, | 1402 | .get_pg_ver = wl12xx_get_pg_ver, |
1308 | .get_mac = wl12xx_get_mac, | 1403 | .get_mac = wl12xx_get_mac, |
1404 | .set_tx_desc_csum = wl12xx_set_tx_desc_csum, | ||
1405 | .set_rx_csum = NULL, | ||
1406 | .ap_get_mimo_wide_rate_mask = NULL, | ||
1407 | .debugfs_init = wl12xx_debugfs_add_files, | ||
1408 | .get_spare_blocks = wl12xx_get_spare_blocks, | ||
1409 | .set_key = wl12xx_set_key, | ||
1410 | .pre_pkt_send = NULL, | ||
1309 | }; | 1411 | }; |
1310 | 1412 | ||
1311 | static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { | 1413 | static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { |
@@ -1323,6 +1425,7 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { | |||
1323 | 1425 | ||
1324 | static int __devinit wl12xx_probe(struct platform_device *pdev) | 1426 | static int __devinit wl12xx_probe(struct platform_device *pdev) |
1325 | { | 1427 | { |
1428 | struct wl12xx_platform_data *pdata = pdev->dev.platform_data; | ||
1326 | struct wl1271 *wl; | 1429 | struct wl1271 *wl; |
1327 | struct ieee80211_hw *hw; | 1430 | struct ieee80211_hw *hw; |
1328 | struct wl12xx_priv *priv; | 1431 | struct wl12xx_priv *priv; |
@@ -1334,19 +1437,65 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) | |||
1334 | } | 1437 | } |
1335 | 1438 | ||
1336 | wl = hw->priv; | 1439 | wl = hw->priv; |
1440 | priv = wl->priv; | ||
1337 | wl->ops = &wl12xx_ops; | 1441 | wl->ops = &wl12xx_ops; |
1338 | wl->ptable = wl12xx_ptable; | 1442 | wl->ptable = wl12xx_ptable; |
1339 | wl->rtable = wl12xx_rtable; | 1443 | wl->rtable = wl12xx_rtable; |
1340 | wl->num_tx_desc = 16; | 1444 | wl->num_tx_desc = 16; |
1341 | wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT; | 1445 | wl->num_rx_desc = 8; |
1342 | wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE; | ||
1343 | wl->band_rate_to_idx = wl12xx_band_rate_to_idx; | 1446 | wl->band_rate_to_idx = wl12xx_band_rate_to_idx; |
1344 | wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; | 1447 | wl->hw_tx_rate_tbl_size = WL12XX_CONF_HW_RXTX_RATE_MAX; |
1345 | wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; | 1448 | wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; |
1346 | wl->fw_status_priv_len = 0; | 1449 | wl->fw_status_priv_len = 0; |
1347 | memcpy(&wl->ht_cap, &wl12xx_ht_cap, sizeof(wl12xx_ht_cap)); | 1450 | wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); |
1451 | memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap, | ||
1452 | sizeof(wl12xx_ht_cap)); | ||
1453 | memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap, | ||
1454 | sizeof(wl12xx_ht_cap)); | ||
1348 | wl12xx_conf_init(wl); | 1455 | wl12xx_conf_init(wl); |
1349 | 1456 | ||
1457 | if (!fref_param) { | ||
1458 | priv->ref_clock = pdata->board_ref_clock; | ||
1459 | } else { | ||
1460 | if (!strcmp(fref_param, "19.2")) | ||
1461 | priv->ref_clock = WL12XX_REFCLOCK_19; | ||
1462 | else if (!strcmp(fref_param, "26")) | ||
1463 | priv->ref_clock = WL12XX_REFCLOCK_26; | ||
1464 | else if (!strcmp(fref_param, "26x")) | ||
1465 | priv->ref_clock = WL12XX_REFCLOCK_26_XTAL; | ||
1466 | else if (!strcmp(fref_param, "38.4")) | ||
1467 | priv->ref_clock = WL12XX_REFCLOCK_38; | ||
1468 | else if (!strcmp(fref_param, "38.4x")) | ||
1469 | priv->ref_clock = WL12XX_REFCLOCK_38_XTAL; | ||
1470 | else if (!strcmp(fref_param, "52")) | ||
1471 | priv->ref_clock = WL12XX_REFCLOCK_52; | ||
1472 | else | ||
1473 | wl1271_error("Invalid fref parameter %s", fref_param); | ||
1474 | } | ||
1475 | |||
1476 | if (!tcxo_param) { | ||
1477 | priv->tcxo_clock = pdata->board_tcxo_clock; | ||
1478 | } else { | ||
1479 | if (!strcmp(tcxo_param, "19.2")) | ||
1480 | priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2; | ||
1481 | else if (!strcmp(tcxo_param, "26")) | ||
1482 | priv->tcxo_clock = WL12XX_TCXOCLOCK_26; | ||
1483 | else if (!strcmp(tcxo_param, "38.4")) | ||
1484 | priv->tcxo_clock = WL12XX_TCXOCLOCK_38_4; | ||
1485 | else if (!strcmp(tcxo_param, "52")) | ||
1486 | priv->tcxo_clock = WL12XX_TCXOCLOCK_52; | ||
1487 | else if (!strcmp(tcxo_param, "16.368")) | ||
1488 | priv->tcxo_clock = WL12XX_TCXOCLOCK_16_368; | ||
1489 | else if (!strcmp(tcxo_param, "32.736")) | ||
1490 | priv->tcxo_clock = WL12XX_TCXOCLOCK_32_736; | ||
1491 | else if (!strcmp(tcxo_param, "16.8")) | ||
1492 | priv->tcxo_clock = WL12XX_TCXOCLOCK_16_8; | ||
1493 | else if (!strcmp(tcxo_param, "33.6")) | ||
1494 | priv->tcxo_clock = WL12XX_TCXOCLOCK_33_6; | ||
1495 | else | ||
1496 | wl1271_error("Invalid tcxo parameter %s", tcxo_param); | ||
1497 | } | ||
1498 | |||
1350 | return wlcore_probe(wl, pdev); | 1499 | return wlcore_probe(wl, pdev); |
1351 | } | 1500 | } |
1352 | 1501 | ||
@@ -1378,6 +1527,13 @@ static void __exit wl12xx_exit(void) | |||
1378 | } | 1527 | } |
1379 | module_exit(wl12xx_exit); | 1528 | module_exit(wl12xx_exit); |
1380 | 1529 | ||
1530 | module_param_named(fref, fref_param, charp, 0); | ||
1531 | MODULE_PARM_DESC(fref, "FREF clock: 19.2, 26, 26x, 38.4, 38.4x, 52"); | ||
1532 | |||
1533 | module_param_named(tcxo, tcxo_param, charp, 0); | ||
1534 | MODULE_PARM_DESC(tcxo, | ||
1535 | "TCXO clock: 19.2, 26, 38.4, 52, 16.368, 32.736, 16.8, 33.6"); | ||
1536 | |||
1381 | MODULE_LICENSE("GPL v2"); | 1537 | MODULE_LICENSE("GPL v2"); |
1382 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 1538 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
1383 | MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); | 1539 | MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); |
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h index 74cd332e23ef..de1132410876 100644 --- a/drivers/net/wireless/ti/wl12xx/wl12xx.h +++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h | |||
@@ -24,8 +24,16 @@ | |||
24 | 24 | ||
25 | #include "conf.h" | 25 | #include "conf.h" |
26 | 26 | ||
27 | struct wl127x_rx_mem_pool_addr { | ||
28 | u32 addr; | ||
29 | u32 addr_extra; | ||
30 | }; | ||
31 | |||
27 | struct wl12xx_priv { | 32 | struct wl12xx_priv { |
28 | struct wl12xx_priv_conf conf; | 33 | struct wl12xx_priv_conf conf; |
34 | |||
35 | int ref_clock; | ||
36 | int tcxo_clock; | ||
29 | }; | 37 | }; |
30 | 38 | ||
31 | #endif /* __WL12XX_PRIV_H__ */ | 39 | #endif /* __WL12XX_PRIV_H__ */ |
diff --git a/drivers/net/wireless/ti/wl18xx/Kconfig b/drivers/net/wireless/ti/wl18xx/Kconfig new file mode 100644 index 000000000000..1cfdb2548821 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/Kconfig | |||
@@ -0,0 +1,7 @@ | |||
1 | config WL18XX | ||
2 | tristate "TI wl18xx support" | ||
3 | depends on MAC80211 | ||
4 | select WLCORE | ||
5 | ---help--- | ||
6 | This module adds support for wireless adapters based on TI | ||
7 | WiLink 8 chipsets. | ||
diff --git a/drivers/net/wireless/ti/wl18xx/Makefile b/drivers/net/wireless/ti/wl18xx/Makefile new file mode 100644 index 000000000000..67c098734c7f --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | wl18xx-objs = main.o acx.o tx.o io.o debugfs.o | ||
2 | |||
3 | obj-$(CONFIG_WL18XX) += wl18xx.o | ||
diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c new file mode 100644 index 000000000000..72840e23bf59 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/acx.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "../wlcore/cmd.h" | ||
23 | #include "../wlcore/debug.h" | ||
24 | #include "../wlcore/acx.h" | ||
25 | |||
26 | #include "acx.h" | ||
27 | |||
28 | int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, | ||
29 | u32 sdio_blk_size, u32 extra_mem_blks, | ||
30 | u32 len_field_size) | ||
31 | { | ||
32 | struct wl18xx_acx_host_config_bitmap *bitmap_conf; | ||
33 | int ret; | ||
34 | |||
35 | wl1271_debug(DEBUG_ACX, "acx cfg bitmap %d blk %d spare %d field %d", | ||
36 | host_cfg_bitmap, sdio_blk_size, extra_mem_blks, | ||
37 | len_field_size); | ||
38 | |||
39 | bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); | ||
40 | if (!bitmap_conf) { | ||
41 | ret = -ENOMEM; | ||
42 | goto out; | ||
43 | } | ||
44 | |||
45 | bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap); | ||
46 | bitmap_conf->host_sdio_block_size = cpu_to_le32(sdio_blk_size); | ||
47 | bitmap_conf->extra_mem_blocks = cpu_to_le32(extra_mem_blks); | ||
48 | bitmap_conf->length_field_size = cpu_to_le32(len_field_size); | ||
49 | |||
50 | ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP, | ||
51 | bitmap_conf, sizeof(*bitmap_conf)); | ||
52 | if (ret < 0) { | ||
53 | wl1271_warning("wl1271 bitmap config opt failed: %d", ret); | ||
54 | goto out; | ||
55 | } | ||
56 | |||
57 | out: | ||
58 | kfree(bitmap_conf); | ||
59 | |||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | int wl18xx_acx_set_checksum_state(struct wl1271 *wl) | ||
64 | { | ||
65 | struct wl18xx_acx_checksum_state *acx; | ||
66 | int ret; | ||
67 | |||
68 | wl1271_debug(DEBUG_ACX, "acx checksum state"); | ||
69 | |||
70 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
71 | if (!acx) { | ||
72 | ret = -ENOMEM; | ||
73 | goto out; | ||
74 | } | ||
75 | |||
76 | acx->checksum_state = CHECKSUM_OFFLOAD_ENABLED; | ||
77 | |||
78 | ret = wl1271_cmd_configure(wl, ACX_CHECKSUM_CONFIG, acx, sizeof(*acx)); | ||
79 | if (ret < 0) { | ||
80 | wl1271_warning("failed to set Tx checksum state: %d", ret); | ||
81 | goto out; | ||
82 | } | ||
83 | |||
84 | out: | ||
85 | kfree(acx); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | int wl18xx_acx_clear_statistics(struct wl1271 *wl) | ||
90 | { | ||
91 | struct wl18xx_acx_clear_statistics *acx; | ||
92 | int ret = 0; | ||
93 | |||
94 | wl1271_debug(DEBUG_ACX, "acx clear statistics"); | ||
95 | |||
96 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
97 | if (!acx) { | ||
98 | ret = -ENOMEM; | ||
99 | goto out; | ||
100 | } | ||
101 | |||
102 | ret = wl1271_cmd_configure(wl, ACX_CLEAR_STATISTICS, acx, sizeof(*acx)); | ||
103 | if (ret < 0) { | ||
104 | wl1271_warning("failed to clear firmware statistics: %d", ret); | ||
105 | goto out; | ||
106 | } | ||
107 | |||
108 | out: | ||
109 | kfree(acx); | ||
110 | return ret; | ||
111 | } | ||
diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h new file mode 100644 index 000000000000..ebbaf611e97b --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/acx.h | |||
@@ -0,0 +1,291 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_ACX_H__ | ||
23 | #define __WL18XX_ACX_H__ | ||
24 | |||
25 | #include "../wlcore/wlcore.h" | ||
26 | #include "../wlcore/acx.h" | ||
27 | |||
28 | enum { | ||
29 | ACX_CLEAR_STATISTICS = 0x0047, | ||
30 | }; | ||
31 | |||
32 | /* numbers of bits the length field takes (add 1 for the actual number) */ | ||
33 | #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 | ||
34 | |||
35 | #define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \ | ||
36 | WL1271_ACX_INTR_INIT_COMPLETE | \ | ||
37 | WL1271_ACX_INTR_EVENT_A | \ | ||
38 | WL1271_ACX_INTR_EVENT_B | \ | ||
39 | WL1271_ACX_INTR_CMD_COMPLETE | \ | ||
40 | WL1271_ACX_INTR_HW_AVAILABLE | \ | ||
41 | WL1271_ACX_INTR_DATA) | ||
42 | |||
43 | #define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \ | ||
44 | WL1271_ACX_SW_INTR_WATCHDOG) | ||
45 | |||
46 | #define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \ | ||
47 | WL1271_ACX_INTR_EVENT_A | \ | ||
48 | WL1271_ACX_INTR_EVENT_B | \ | ||
49 | WL1271_ACX_INTR_HW_AVAILABLE | \ | ||
50 | WL1271_ACX_INTR_DATA) | ||
51 | |||
52 | #define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \ | ||
53 | WL1271_ACX_SW_INTR_WATCHDOG) | ||
54 | |||
55 | struct wl18xx_acx_host_config_bitmap { | ||
56 | struct acx_header header; | ||
57 | |||
58 | __le32 host_cfg_bitmap; | ||
59 | |||
60 | __le32 host_sdio_block_size; | ||
61 | |||
62 | /* extra mem blocks per frame in TX. */ | ||
63 | __le32 extra_mem_blocks; | ||
64 | |||
65 | /* | ||
66 | * number of bits of the length field in the first TX word | ||
67 | * (up to 15 - for using the entire 16 bits). | ||
68 | */ | ||
69 | __le32 length_field_size; | ||
70 | |||
71 | } __packed; | ||
72 | |||
73 | enum { | ||
74 | CHECKSUM_OFFLOAD_DISABLED = 0, | ||
75 | CHECKSUM_OFFLOAD_ENABLED = 1, | ||
76 | CHECKSUM_OFFLOAD_FAKE_RX = 2, | ||
77 | CHECKSUM_OFFLOAD_INVALID = 0xFF | ||
78 | }; | ||
79 | |||
80 | struct wl18xx_acx_checksum_state { | ||
81 | struct acx_header header; | ||
82 | |||
83 | /* enum acx_checksum_state */ | ||
84 | u8 checksum_state; | ||
85 | u8 pad[3]; | ||
86 | } __packed; | ||
87 | |||
88 | |||
89 | struct wl18xx_acx_error_stats { | ||
90 | u32 error_frame; | ||
91 | u32 error_null_Frame_tx_start; | ||
92 | u32 error_numll_frame_cts_start; | ||
93 | u32 error_bar_retry; | ||
94 | u32 error_frame_cts_nul_flid; | ||
95 | } __packed; | ||
96 | |||
97 | struct wl18xx_acx_debug_stats { | ||
98 | u32 debug1; | ||
99 | u32 debug2; | ||
100 | u32 debug3; | ||
101 | u32 debug4; | ||
102 | u32 debug5; | ||
103 | u32 debug6; | ||
104 | } __packed; | ||
105 | |||
106 | struct wl18xx_acx_ring_stats { | ||
107 | u32 prepared_descs; | ||
108 | u32 tx_cmplt; | ||
109 | } __packed; | ||
110 | |||
111 | struct wl18xx_acx_tx_stats { | ||
112 | u32 tx_prepared_descs; | ||
113 | u32 tx_cmplt; | ||
114 | u32 tx_template_prepared; | ||
115 | u32 tx_data_prepared; | ||
116 | u32 tx_template_programmed; | ||
117 | u32 tx_data_programmed; | ||
118 | u32 tx_burst_programmed; | ||
119 | u32 tx_starts; | ||
120 | u32 tx_imm_resp; | ||
121 | u32 tx_start_templates; | ||
122 | u32 tx_start_int_templates; | ||
123 | u32 tx_start_fw_gen; | ||
124 | u32 tx_start_data; | ||
125 | u32 tx_start_null_frame; | ||
126 | u32 tx_exch; | ||
127 | u32 tx_retry_template; | ||
128 | u32 tx_retry_data; | ||
129 | u32 tx_exch_pending; | ||
130 | u32 tx_exch_expiry; | ||
131 | u32 tx_done_template; | ||
132 | u32 tx_done_data; | ||
133 | u32 tx_done_int_template; | ||
134 | u32 tx_frame_checksum; | ||
135 | u32 tx_checksum_result; | ||
136 | u32 frag_called; | ||
137 | u32 frag_mpdu_alloc_failed; | ||
138 | u32 frag_init_called; | ||
139 | u32 frag_in_process_called; | ||
140 | u32 frag_tkip_called; | ||
141 | u32 frag_key_not_found; | ||
142 | u32 frag_need_fragmentation; | ||
143 | u32 frag_bad_mblk_num; | ||
144 | u32 frag_failed; | ||
145 | u32 frag_cache_hit; | ||
146 | u32 frag_cache_miss; | ||
147 | } __packed; | ||
148 | |||
149 | struct wl18xx_acx_rx_stats { | ||
150 | u32 rx_beacon_early_term; | ||
151 | u32 rx_out_of_mpdu_nodes; | ||
152 | u32 rx_hdr_overflow; | ||
153 | u32 rx_dropped_frame; | ||
154 | u32 rx_done_stage; | ||
155 | u32 rx_done; | ||
156 | u32 rx_defrag; | ||
157 | u32 rx_defrag_end; | ||
158 | u32 rx_cmplt; | ||
159 | u32 rx_pre_complt; | ||
160 | u32 rx_cmplt_task; | ||
161 | u32 rx_phy_hdr; | ||
162 | u32 rx_timeout; | ||
163 | u32 rx_timeout_wa; | ||
164 | u32 rx_wa_density_dropped_frame; | ||
165 | u32 rx_wa_ba_not_expected; | ||
166 | u32 rx_frame_checksum; | ||
167 | u32 rx_checksum_result; | ||
168 | u32 defrag_called; | ||
169 | u32 defrag_init_called; | ||
170 | u32 defrag_in_process_called; | ||
171 | u32 defrag_tkip_called; | ||
172 | u32 defrag_need_defrag; | ||
173 | u32 defrag_decrypt_failed; | ||
174 | u32 decrypt_key_not_found; | ||
175 | u32 defrag_need_decrypt; | ||
176 | u32 rx_tkip_replays; | ||
177 | } __packed; | ||
178 | |||
179 | struct wl18xx_acx_isr_stats { | ||
180 | u32 irqs; | ||
181 | } __packed; | ||
182 | |||
183 | #define PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD 10 | ||
184 | |||
185 | struct wl18xx_acx_pwr_stats { | ||
186 | u32 missing_bcns_cnt; | ||
187 | u32 rcvd_bcns_cnt; | ||
188 | u32 connection_out_of_sync; | ||
189 | u32 cont_miss_bcns_spread[PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD]; | ||
190 | u32 rcvd_awake_bcns_cnt; | ||
191 | } __packed; | ||
192 | |||
193 | struct wl18xx_acx_event_stats { | ||
194 | u32 calibration; | ||
195 | u32 rx_mismatch; | ||
196 | u32 rx_mem_empty; | ||
197 | } __packed; | ||
198 | |||
199 | struct wl18xx_acx_ps_poll_stats { | ||
200 | u32 ps_poll_timeouts; | ||
201 | u32 upsd_timeouts; | ||
202 | u32 upsd_max_ap_turn; | ||
203 | u32 ps_poll_max_ap_turn; | ||
204 | u32 ps_poll_utilization; | ||
205 | u32 upsd_utilization; | ||
206 | } __packed; | ||
207 | |||
208 | struct wl18xx_acx_rx_filter_stats { | ||
209 | u32 beacon_filter; | ||
210 | u32 arp_filter; | ||
211 | u32 mc_filter; | ||
212 | u32 dup_filter; | ||
213 | u32 data_filter; | ||
214 | u32 ibss_filter; | ||
215 | u32 protection_filter; | ||
216 | u32 accum_arp_pend_requests; | ||
217 | u32 max_arp_queue_dep; | ||
218 | } __packed; | ||
219 | |||
220 | struct wl18xx_acx_rx_rate_stats { | ||
221 | u32 rx_frames_per_rates[50]; | ||
222 | } __packed; | ||
223 | |||
224 | #define AGGR_STATS_TX_AGG 16 | ||
225 | #define AGGR_STATS_TX_RATE 16 | ||
226 | #define AGGR_STATS_RX_SIZE_LEN 16 | ||
227 | |||
228 | struct wl18xx_acx_aggr_stats { | ||
229 | u32 tx_agg_vs_rate[AGGR_STATS_TX_AGG * AGGR_STATS_TX_RATE]; | ||
230 | u32 rx_size[AGGR_STATS_RX_SIZE_LEN]; | ||
231 | } __packed; | ||
232 | |||
233 | #define PIPE_STATS_HW_FIFO 11 | ||
234 | |||
235 | struct wl18xx_acx_pipeline_stats { | ||
236 | u32 hs_tx_stat_fifo_int; | ||
237 | u32 hs_rx_stat_fifo_int; | ||
238 | u32 tcp_tx_stat_fifo_int; | ||
239 | u32 tcp_rx_stat_fifo_int; | ||
240 | u32 enc_tx_stat_fifo_int; | ||
241 | u32 enc_rx_stat_fifo_int; | ||
242 | u32 rx_complete_stat_fifo_int; | ||
243 | u32 pre_proc_swi; | ||
244 | u32 post_proc_swi; | ||
245 | u32 sec_frag_swi; | ||
246 | u32 pre_to_defrag_swi; | ||
247 | u32 defrag_to_csum_swi; | ||
248 | u32 csum_to_rx_xfer_swi; | ||
249 | u32 dec_packet_in; | ||
250 | u32 dec_packet_in_fifo_full; | ||
251 | u32 dec_packet_out; | ||
252 | u32 cs_rx_packet_in; | ||
253 | u32 cs_rx_packet_out; | ||
254 | u16 pipeline_fifo_full[PIPE_STATS_HW_FIFO]; | ||
255 | } __packed; | ||
256 | |||
257 | struct wl18xx_acx_mem_stats { | ||
258 | u32 rx_free_mem_blks; | ||
259 | u32 tx_free_mem_blks; | ||
260 | u32 fwlog_free_mem_blks; | ||
261 | u32 fw_gen_free_mem_blks; | ||
262 | } __packed; | ||
263 | |||
264 | struct wl18xx_acx_statistics { | ||
265 | struct acx_header header; | ||
266 | |||
267 | struct wl18xx_acx_error_stats error; | ||
268 | struct wl18xx_acx_debug_stats debug; | ||
269 | struct wl18xx_acx_tx_stats tx; | ||
270 | struct wl18xx_acx_rx_stats rx; | ||
271 | struct wl18xx_acx_isr_stats isr; | ||
272 | struct wl18xx_acx_pwr_stats pwr; | ||
273 | struct wl18xx_acx_ps_poll_stats ps_poll; | ||
274 | struct wl18xx_acx_rx_filter_stats rx_filter; | ||
275 | struct wl18xx_acx_rx_rate_stats rx_rate; | ||
276 | struct wl18xx_acx_aggr_stats aggr_size; | ||
277 | struct wl18xx_acx_pipeline_stats pipeline; | ||
278 | struct wl18xx_acx_mem_stats mem; | ||
279 | } __packed; | ||
280 | |||
281 | struct wl18xx_acx_clear_statistics { | ||
282 | struct acx_header header; | ||
283 | }; | ||
284 | |||
285 | int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, | ||
286 | u32 sdio_blk_size, u32 extra_mem_blks, | ||
287 | u32 len_field_size); | ||
288 | int wl18xx_acx_set_checksum_state(struct wl1271 *wl); | ||
289 | int wl18xx_acx_clear_statistics(struct wl1271 *wl); | ||
290 | |||
291 | #endif /* __WL18XX_ACX_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h new file mode 100644 index 000000000000..fac0b7e87e75 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/conf.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_CONF_H__ | ||
23 | #define __WL18XX_CONF_H__ | ||
24 | |||
25 | #define WL18XX_CONF_MAGIC 0x10e100ca | ||
26 | #define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0002) | ||
27 | #define WL18XX_CONF_MASK 0x0000ffff | ||
28 | #define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ | ||
29 | sizeof(struct wl18xx_priv_conf)) | ||
30 | |||
31 | #define NUM_OF_CHANNELS_11_ABG 150 | ||
32 | #define NUM_OF_CHANNELS_11_P 7 | ||
33 | #define WL18XX_NUM_OF_SUB_BANDS 9 | ||
34 | #define SRF_TABLE_LEN 16 | ||
35 | #define PIN_MUXING_SIZE 2 | ||
36 | |||
37 | struct wl18xx_mac_and_phy_params { | ||
38 | u8 phy_standalone; | ||
39 | u8 rdl; | ||
40 | u8 enable_clpc; | ||
41 | u8 enable_tx_low_pwr_on_siso_rdl; | ||
42 | u8 auto_detect; | ||
43 | u8 dedicated_fem; | ||
44 | |||
45 | u8 low_band_component; | ||
46 | |||
47 | /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ | ||
48 | u8 low_band_component_type; | ||
49 | |||
50 | u8 high_band_component; | ||
51 | |||
52 | /* Bit 0: One Hot, Bit 1: Control Enable, Bit 2: 1.8V, Bit 3: 3V */ | ||
53 | u8 high_band_component_type; | ||
54 | u8 number_of_assembled_ant2_4; | ||
55 | u8 number_of_assembled_ant5; | ||
56 | u8 pin_muxing_platform_options[PIN_MUXING_SIZE]; | ||
57 | u8 external_pa_dc2dc; | ||
58 | u8 tcxo_ldo_voltage; | ||
59 | u8 xtal_itrim_val; | ||
60 | u8 srf_state; | ||
61 | u8 srf1[SRF_TABLE_LEN]; | ||
62 | u8 srf2[SRF_TABLE_LEN]; | ||
63 | u8 srf3[SRF_TABLE_LEN]; | ||
64 | u8 io_configuration; | ||
65 | u8 sdio_configuration; | ||
66 | u8 settings; | ||
67 | u8 rx_profile; | ||
68 | u8 per_chan_pwr_limit_arr_11abg[NUM_OF_CHANNELS_11_ABG]; | ||
69 | u8 pwr_limit_reference_11_abg; | ||
70 | u8 per_chan_pwr_limit_arr_11p[NUM_OF_CHANNELS_11_P]; | ||
71 | u8 pwr_limit_reference_11p; | ||
72 | u8 per_sub_band_tx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; | ||
73 | u8 per_sub_band_rx_trace_loss[WL18XX_NUM_OF_SUB_BANDS]; | ||
74 | u8 primary_clock_setting_time; | ||
75 | u8 clock_valid_on_wake_up; | ||
76 | u8 secondary_clock_setting_time; | ||
77 | u8 board_type; | ||
78 | /* enable point saturation */ | ||
79 | u8 psat; | ||
80 | /* low/medium/high Tx power in dBm */ | ||
81 | s8 low_power_val; | ||
82 | s8 med_power_val; | ||
83 | s8 high_power_val; | ||
84 | u8 padding[1]; | ||
85 | } __packed; | ||
86 | |||
87 | struct wl18xx_priv_conf { | ||
88 | /* this structure is copied wholesale to FW */ | ||
89 | struct wl18xx_mac_and_phy_params phy; | ||
90 | } __packed; | ||
91 | |||
92 | #endif /* __WL18XX_CONF_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c new file mode 100644 index 000000000000..3ce6f1039af3 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/debugfs.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Copyright (C) 2011-2012 Texas Instruments | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include "../wlcore/debugfs.h" | ||
24 | #include "../wlcore/wlcore.h" | ||
25 | |||
26 | #include "wl18xx.h" | ||
27 | #include "acx.h" | ||
28 | #include "debugfs.h" | ||
29 | |||
30 | #define WL18XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ | ||
31 | DEBUGFS_FWSTATS_FILE(a, b, c, wl18xx_acx_statistics) | ||
32 | #define WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c) \ | ||
33 | DEBUGFS_FWSTATS_FILE_ARRAY(a, b, c, wl18xx_acx_statistics) | ||
34 | |||
35 | |||
36 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug1, "%u"); | ||
37 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug2, "%u"); | ||
38 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug3, "%u"); | ||
39 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug4, "%u"); | ||
40 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug5, "%u"); | ||
41 | WL18XX_DEBUGFS_FWSTATS_FILE(debug, debug6, "%u"); | ||
42 | |||
43 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame, "%u"); | ||
44 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_null_Frame_tx_start, "%u"); | ||
45 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_numll_frame_cts_start, "%u"); | ||
46 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_bar_retry, "%u"); | ||
47 | WL18XX_DEBUGFS_FWSTATS_FILE(error, error_frame_cts_nul_flid, "%u"); | ||
48 | |||
49 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_prepared_descs, "%u"); | ||
50 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_cmplt, "%u"); | ||
51 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_prepared, "%u"); | ||
52 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_prepared, "%u"); | ||
53 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_template_programmed, "%u"); | ||
54 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_data_programmed, "%u"); | ||
55 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_burst_programmed, "%u"); | ||
56 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_starts, "%u"); | ||
57 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_imm_resp, "%u"); | ||
58 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_templates, "%u"); | ||
59 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_int_templates, "%u"); | ||
60 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_fw_gen, "%u"); | ||
61 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_data, "%u"); | ||
62 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_start_null_frame, "%u"); | ||
63 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch, "%u"); | ||
64 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_template, "%u"); | ||
65 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_retry_data, "%u"); | ||
66 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_pending, "%u"); | ||
67 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_exch_expiry, "%u"); | ||
68 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_template, "%u"); | ||
69 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_data, "%u"); | ||
70 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_done_int_template, "%u"); | ||
71 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_frame_checksum, "%u"); | ||
72 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, tx_checksum_result, "%u"); | ||
73 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_called, "%u"); | ||
74 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_mpdu_alloc_failed, "%u"); | ||
75 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_init_called, "%u"); | ||
76 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_in_process_called, "%u"); | ||
77 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_tkip_called, "%u"); | ||
78 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_key_not_found, "%u"); | ||
79 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_need_fragmentation, "%u"); | ||
80 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_bad_mblk_num, "%u"); | ||
81 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_failed, "%u"); | ||
82 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_hit, "%u"); | ||
83 | WL18XX_DEBUGFS_FWSTATS_FILE(tx, frag_cache_miss, "%u"); | ||
84 | |||
85 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_beacon_early_term, "%u"); | ||
86 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_out_of_mpdu_nodes, "%u"); | ||
87 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_hdr_overflow, "%u"); | ||
88 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_dropped_frame, "%u"); | ||
89 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_done, "%u"); | ||
90 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag, "%u"); | ||
91 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_defrag_end, "%u"); | ||
92 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt, "%u"); | ||
93 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_pre_complt, "%u"); | ||
94 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_cmplt_task, "%u"); | ||
95 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_phy_hdr, "%u"); | ||
96 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout, "%u"); | ||
97 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_timeout_wa, "%u"); | ||
98 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_density_dropped_frame, "%u"); | ||
99 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_wa_ba_not_expected, "%u"); | ||
100 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_frame_checksum, "%u"); | ||
101 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_checksum_result, "%u"); | ||
102 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_called, "%u"); | ||
103 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_init_called, "%u"); | ||
104 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_in_process_called, "%u"); | ||
105 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_tkip_called, "%u"); | ||
106 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_defrag, "%u"); | ||
107 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_decrypt_failed, "%u"); | ||
108 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, decrypt_key_not_found, "%u"); | ||
109 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, defrag_need_decrypt, "%u"); | ||
110 | WL18XX_DEBUGFS_FWSTATS_FILE(rx, rx_tkip_replays, "%u"); | ||
111 | |||
112 | WL18XX_DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); | ||
113 | |||
114 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, missing_bcns_cnt, "%u"); | ||
115 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_bcns_cnt, "%u"); | ||
116 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, connection_out_of_sync, "%u"); | ||
117 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pwr, cont_miss_bcns_spread, | ||
118 | PWR_STAT_MAX_CONT_MISSED_BCNS_SPREAD); | ||
119 | WL18XX_DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_bcns_cnt, "%u"); | ||
120 | |||
121 | |||
122 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_timeouts, "%u"); | ||
123 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_timeouts, "%u"); | ||
124 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_max_ap_turn, "%u"); | ||
125 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_max_ap_turn, "%u"); | ||
126 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, ps_poll_utilization, "%u"); | ||
127 | WL18XX_DEBUGFS_FWSTATS_FILE(ps_poll, upsd_utilization, "%u"); | ||
128 | |||
129 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, beacon_filter, "%u"); | ||
130 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, arp_filter, "%u"); | ||
131 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, mc_filter, "%u"); | ||
132 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, dup_filter, "%u"); | ||
133 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, data_filter, "%u"); | ||
134 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, ibss_filter, "%u"); | ||
135 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u"); | ||
136 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, accum_arp_pend_requests, "%u"); | ||
137 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u"); | ||
138 | |||
139 | WL18XX_DEBUGFS_FWSTATS_FILE(rx_rate, rx_frames_per_rates, "%u"); | ||
140 | |||
141 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_vs_rate, | ||
142 | AGGR_STATS_TX_AGG*AGGR_STATS_TX_RATE); | ||
143 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, rx_size, | ||
144 | AGGR_STATS_RX_SIZE_LEN); | ||
145 | |||
146 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, hs_tx_stat_fifo_int, "%u"); | ||
147 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_tx_stat_fifo_int, "%u"); | ||
148 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, tcp_rx_stat_fifo_int, "%u"); | ||
149 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_tx_stat_fifo_int, "%u"); | ||
150 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, enc_rx_stat_fifo_int, "%u"); | ||
151 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, rx_complete_stat_fifo_int, "%u"); | ||
152 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_proc_swi, "%u"); | ||
153 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, post_proc_swi, "%u"); | ||
154 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, sec_frag_swi, "%u"); | ||
155 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, pre_to_defrag_swi, "%u"); | ||
156 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, defrag_to_csum_swi, "%u"); | ||
157 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, csum_to_rx_xfer_swi, "%u"); | ||
158 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in, "%u"); | ||
159 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_in_fifo_full, "%u"); | ||
160 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, dec_packet_out, "%u"); | ||
161 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_in, "%u"); | ||
162 | WL18XX_DEBUGFS_FWSTATS_FILE(pipeline, cs_rx_packet_out, "%u"); | ||
163 | |||
164 | WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(pipeline, pipeline_fifo_full, | ||
165 | PIPE_STATS_HW_FIFO); | ||
166 | |||
167 | WL18XX_DEBUGFS_FWSTATS_FILE(mem, rx_free_mem_blks, "%u"); | ||
168 | WL18XX_DEBUGFS_FWSTATS_FILE(mem, tx_free_mem_blks, "%u"); | ||
169 | WL18XX_DEBUGFS_FWSTATS_FILE(mem, fwlog_free_mem_blks, "%u"); | ||
170 | WL18XX_DEBUGFS_FWSTATS_FILE(mem, fw_gen_free_mem_blks, "%u"); | ||
171 | |||
172 | static ssize_t conf_read(struct file *file, char __user *user_buf, | ||
173 | size_t count, loff_t *ppos) | ||
174 | { | ||
175 | struct wl1271 *wl = file->private_data; | ||
176 | struct wl18xx_priv *priv = wl->priv; | ||
177 | struct wlcore_conf_header header; | ||
178 | char *buf, *pos; | ||
179 | size_t len; | ||
180 | int ret; | ||
181 | |||
182 | len = WL18XX_CONF_SIZE; | ||
183 | buf = kmalloc(len, GFP_KERNEL); | ||
184 | if (!buf) | ||
185 | return -ENOMEM; | ||
186 | |||
187 | header.magic = cpu_to_le32(WL18XX_CONF_MAGIC); | ||
188 | header.version = cpu_to_le32(WL18XX_CONF_VERSION); | ||
189 | header.checksum = 0; | ||
190 | |||
191 | mutex_lock(&wl->mutex); | ||
192 | |||
193 | pos = buf; | ||
194 | memcpy(pos, &header, sizeof(header)); | ||
195 | pos += sizeof(header); | ||
196 | memcpy(pos, &wl->conf, sizeof(wl->conf)); | ||
197 | pos += sizeof(wl->conf); | ||
198 | memcpy(pos, &priv->conf, sizeof(priv->conf)); | ||
199 | |||
200 | mutex_unlock(&wl->mutex); | ||
201 | |||
202 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
203 | |||
204 | kfree(buf); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static const struct file_operations conf_ops = { | ||
209 | .read = conf_read, | ||
210 | .open = simple_open, | ||
211 | .llseek = default_llseek, | ||
212 | }; | ||
213 | |||
214 | static ssize_t clear_fw_stats_write(struct file *file, | ||
215 | const char __user *user_buf, | ||
216 | size_t count, loff_t *ppos) | ||
217 | { | ||
218 | struct wl1271 *wl = file->private_data; | ||
219 | int ret; | ||
220 | |||
221 | mutex_lock(&wl->mutex); | ||
222 | |||
223 | if (wl->state == WL1271_STATE_OFF) | ||
224 | goto out; | ||
225 | |||
226 | ret = wl18xx_acx_clear_statistics(wl); | ||
227 | if (ret < 0) { | ||
228 | count = ret; | ||
229 | goto out; | ||
230 | } | ||
231 | out: | ||
232 | mutex_unlock(&wl->mutex); | ||
233 | return count; | ||
234 | } | ||
235 | |||
236 | static const struct file_operations clear_fw_stats_ops = { | ||
237 | .write = clear_fw_stats_write, | ||
238 | .open = simple_open, | ||
239 | .llseek = default_llseek, | ||
240 | }; | ||
241 | |||
242 | int wl18xx_debugfs_add_files(struct wl1271 *wl, | ||
243 | struct dentry *rootdir) | ||
244 | { | ||
245 | int ret = 0; | ||
246 | struct dentry *entry, *stats, *moddir; | ||
247 | |||
248 | moddir = debugfs_create_dir(KBUILD_MODNAME, rootdir); | ||
249 | if (!moddir || IS_ERR(moddir)) { | ||
250 | entry = moddir; | ||
251 | goto err; | ||
252 | } | ||
253 | |||
254 | stats = debugfs_create_dir("fw_stats", moddir); | ||
255 | if (!stats || IS_ERR(stats)) { | ||
256 | entry = stats; | ||
257 | goto err; | ||
258 | } | ||
259 | |||
260 | DEBUGFS_ADD(clear_fw_stats, stats); | ||
261 | |||
262 | DEBUGFS_FWSTATS_ADD(debug, debug1); | ||
263 | DEBUGFS_FWSTATS_ADD(debug, debug2); | ||
264 | DEBUGFS_FWSTATS_ADD(debug, debug3); | ||
265 | DEBUGFS_FWSTATS_ADD(debug, debug4); | ||
266 | DEBUGFS_FWSTATS_ADD(debug, debug5); | ||
267 | DEBUGFS_FWSTATS_ADD(debug, debug6); | ||
268 | |||
269 | DEBUGFS_FWSTATS_ADD(error, error_frame); | ||
270 | DEBUGFS_FWSTATS_ADD(error, error_null_Frame_tx_start); | ||
271 | DEBUGFS_FWSTATS_ADD(error, error_numll_frame_cts_start); | ||
272 | DEBUGFS_FWSTATS_ADD(error, error_bar_retry); | ||
273 | DEBUGFS_FWSTATS_ADD(error, error_frame_cts_nul_flid); | ||
274 | |||
275 | DEBUGFS_FWSTATS_ADD(tx, tx_prepared_descs); | ||
276 | DEBUGFS_FWSTATS_ADD(tx, tx_cmplt); | ||
277 | DEBUGFS_FWSTATS_ADD(tx, tx_template_prepared); | ||
278 | DEBUGFS_FWSTATS_ADD(tx, tx_data_prepared); | ||
279 | DEBUGFS_FWSTATS_ADD(tx, tx_template_programmed); | ||
280 | DEBUGFS_FWSTATS_ADD(tx, tx_data_programmed); | ||
281 | DEBUGFS_FWSTATS_ADD(tx, tx_burst_programmed); | ||
282 | DEBUGFS_FWSTATS_ADD(tx, tx_starts); | ||
283 | DEBUGFS_FWSTATS_ADD(tx, tx_imm_resp); | ||
284 | DEBUGFS_FWSTATS_ADD(tx, tx_start_templates); | ||
285 | DEBUGFS_FWSTATS_ADD(tx, tx_start_int_templates); | ||
286 | DEBUGFS_FWSTATS_ADD(tx, tx_start_fw_gen); | ||
287 | DEBUGFS_FWSTATS_ADD(tx, tx_start_data); | ||
288 | DEBUGFS_FWSTATS_ADD(tx, tx_start_null_frame); | ||
289 | DEBUGFS_FWSTATS_ADD(tx, tx_exch); | ||
290 | DEBUGFS_FWSTATS_ADD(tx, tx_retry_template); | ||
291 | DEBUGFS_FWSTATS_ADD(tx, tx_retry_data); | ||
292 | DEBUGFS_FWSTATS_ADD(tx, tx_exch_pending); | ||
293 | DEBUGFS_FWSTATS_ADD(tx, tx_exch_expiry); | ||
294 | DEBUGFS_FWSTATS_ADD(tx, tx_done_template); | ||
295 | DEBUGFS_FWSTATS_ADD(tx, tx_done_data); | ||
296 | DEBUGFS_FWSTATS_ADD(tx, tx_done_int_template); | ||
297 | DEBUGFS_FWSTATS_ADD(tx, tx_frame_checksum); | ||
298 | DEBUGFS_FWSTATS_ADD(tx, tx_checksum_result); | ||
299 | DEBUGFS_FWSTATS_ADD(tx, frag_called); | ||
300 | DEBUGFS_FWSTATS_ADD(tx, frag_mpdu_alloc_failed); | ||
301 | DEBUGFS_FWSTATS_ADD(tx, frag_init_called); | ||
302 | DEBUGFS_FWSTATS_ADD(tx, frag_in_process_called); | ||
303 | DEBUGFS_FWSTATS_ADD(tx, frag_tkip_called); | ||
304 | DEBUGFS_FWSTATS_ADD(tx, frag_key_not_found); | ||
305 | DEBUGFS_FWSTATS_ADD(tx, frag_need_fragmentation); | ||
306 | DEBUGFS_FWSTATS_ADD(tx, frag_bad_mblk_num); | ||
307 | DEBUGFS_FWSTATS_ADD(tx, frag_failed); | ||
308 | DEBUGFS_FWSTATS_ADD(tx, frag_cache_hit); | ||
309 | DEBUGFS_FWSTATS_ADD(tx, frag_cache_miss); | ||
310 | |||
311 | DEBUGFS_FWSTATS_ADD(rx, rx_beacon_early_term); | ||
312 | DEBUGFS_FWSTATS_ADD(rx, rx_out_of_mpdu_nodes); | ||
313 | DEBUGFS_FWSTATS_ADD(rx, rx_hdr_overflow); | ||
314 | DEBUGFS_FWSTATS_ADD(rx, rx_dropped_frame); | ||
315 | DEBUGFS_FWSTATS_ADD(rx, rx_done); | ||
316 | DEBUGFS_FWSTATS_ADD(rx, rx_defrag); | ||
317 | DEBUGFS_FWSTATS_ADD(rx, rx_defrag_end); | ||
318 | DEBUGFS_FWSTATS_ADD(rx, rx_cmplt); | ||
319 | DEBUGFS_FWSTATS_ADD(rx, rx_pre_complt); | ||
320 | DEBUGFS_FWSTATS_ADD(rx, rx_cmplt_task); | ||
321 | DEBUGFS_FWSTATS_ADD(rx, rx_phy_hdr); | ||
322 | DEBUGFS_FWSTATS_ADD(rx, rx_timeout); | ||
323 | DEBUGFS_FWSTATS_ADD(rx, rx_timeout_wa); | ||
324 | DEBUGFS_FWSTATS_ADD(rx, rx_wa_density_dropped_frame); | ||
325 | DEBUGFS_FWSTATS_ADD(rx, rx_wa_ba_not_expected); | ||
326 | DEBUGFS_FWSTATS_ADD(rx, rx_frame_checksum); | ||
327 | DEBUGFS_FWSTATS_ADD(rx, rx_checksum_result); | ||
328 | DEBUGFS_FWSTATS_ADD(rx, defrag_called); | ||
329 | DEBUGFS_FWSTATS_ADD(rx, defrag_init_called); | ||
330 | DEBUGFS_FWSTATS_ADD(rx, defrag_in_process_called); | ||
331 | DEBUGFS_FWSTATS_ADD(rx, defrag_tkip_called); | ||
332 | DEBUGFS_FWSTATS_ADD(rx, defrag_need_defrag); | ||
333 | DEBUGFS_FWSTATS_ADD(rx, defrag_decrypt_failed); | ||
334 | DEBUGFS_FWSTATS_ADD(rx, decrypt_key_not_found); | ||
335 | DEBUGFS_FWSTATS_ADD(rx, defrag_need_decrypt); | ||
336 | DEBUGFS_FWSTATS_ADD(rx, rx_tkip_replays); | ||
337 | |||
338 | DEBUGFS_FWSTATS_ADD(isr, irqs); | ||
339 | |||
340 | DEBUGFS_FWSTATS_ADD(pwr, missing_bcns_cnt); | ||
341 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_bcns_cnt); | ||
342 | DEBUGFS_FWSTATS_ADD(pwr, connection_out_of_sync); | ||
343 | DEBUGFS_FWSTATS_ADD(pwr, cont_miss_bcns_spread); | ||
344 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_bcns_cnt); | ||
345 | |||
346 | DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_timeouts); | ||
347 | DEBUGFS_FWSTATS_ADD(ps_poll, upsd_timeouts); | ||
348 | DEBUGFS_FWSTATS_ADD(ps_poll, upsd_max_ap_turn); | ||
349 | DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_max_ap_turn); | ||
350 | DEBUGFS_FWSTATS_ADD(ps_poll, ps_poll_utilization); | ||
351 | DEBUGFS_FWSTATS_ADD(ps_poll, upsd_utilization); | ||
352 | |||
353 | DEBUGFS_FWSTATS_ADD(rx_filter, beacon_filter); | ||
354 | DEBUGFS_FWSTATS_ADD(rx_filter, arp_filter); | ||
355 | DEBUGFS_FWSTATS_ADD(rx_filter, mc_filter); | ||
356 | DEBUGFS_FWSTATS_ADD(rx_filter, dup_filter); | ||
357 | DEBUGFS_FWSTATS_ADD(rx_filter, data_filter); | ||
358 | DEBUGFS_FWSTATS_ADD(rx_filter, ibss_filter); | ||
359 | DEBUGFS_FWSTATS_ADD(rx_filter, protection_filter); | ||
360 | DEBUGFS_FWSTATS_ADD(rx_filter, accum_arp_pend_requests); | ||
361 | DEBUGFS_FWSTATS_ADD(rx_filter, max_arp_queue_dep); | ||
362 | |||
363 | DEBUGFS_FWSTATS_ADD(rx_rate, rx_frames_per_rates); | ||
364 | |||
365 | DEBUGFS_FWSTATS_ADD(aggr_size, tx_agg_vs_rate); | ||
366 | DEBUGFS_FWSTATS_ADD(aggr_size, rx_size); | ||
367 | |||
368 | DEBUGFS_FWSTATS_ADD(pipeline, hs_tx_stat_fifo_int); | ||
369 | DEBUGFS_FWSTATS_ADD(pipeline, tcp_tx_stat_fifo_int); | ||
370 | DEBUGFS_FWSTATS_ADD(pipeline, tcp_rx_stat_fifo_int); | ||
371 | DEBUGFS_FWSTATS_ADD(pipeline, enc_tx_stat_fifo_int); | ||
372 | DEBUGFS_FWSTATS_ADD(pipeline, enc_rx_stat_fifo_int); | ||
373 | DEBUGFS_FWSTATS_ADD(pipeline, rx_complete_stat_fifo_int); | ||
374 | DEBUGFS_FWSTATS_ADD(pipeline, pre_proc_swi); | ||
375 | DEBUGFS_FWSTATS_ADD(pipeline, post_proc_swi); | ||
376 | DEBUGFS_FWSTATS_ADD(pipeline, sec_frag_swi); | ||
377 | DEBUGFS_FWSTATS_ADD(pipeline, pre_to_defrag_swi); | ||
378 | DEBUGFS_FWSTATS_ADD(pipeline, defrag_to_csum_swi); | ||
379 | DEBUGFS_FWSTATS_ADD(pipeline, csum_to_rx_xfer_swi); | ||
380 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in); | ||
381 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_in_fifo_full); | ||
382 | DEBUGFS_FWSTATS_ADD(pipeline, dec_packet_out); | ||
383 | DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_in); | ||
384 | DEBUGFS_FWSTATS_ADD(pipeline, cs_rx_packet_out); | ||
385 | DEBUGFS_FWSTATS_ADD(pipeline, pipeline_fifo_full); | ||
386 | |||
387 | DEBUGFS_FWSTATS_ADD(mem, rx_free_mem_blks); | ||
388 | DEBUGFS_FWSTATS_ADD(mem, tx_free_mem_blks); | ||
389 | DEBUGFS_FWSTATS_ADD(mem, fwlog_free_mem_blks); | ||
390 | DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks); | ||
391 | |||
392 | DEBUGFS_ADD(conf, moddir); | ||
393 | |||
394 | return 0; | ||
395 | |||
396 | err: | ||
397 | if (IS_ERR(entry)) | ||
398 | ret = PTR_ERR(entry); | ||
399 | else | ||
400 | ret = -ENOMEM; | ||
401 | |||
402 | return ret; | ||
403 | } | ||
diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.h b/drivers/net/wireless/ti/wl18xx/debugfs.h new file mode 100644 index 000000000000..ed679bebf620 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/debugfs.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_DEBUGFS_H__ | ||
23 | #define __WL18XX_DEBUGFS_H__ | ||
24 | |||
25 | int wl18xx_debugfs_add_files(struct wl1271 *wl, | ||
26 | struct dentry *rootdir); | ||
27 | |||
28 | #endif /* __WL18XX_DEBUGFS_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/io.c b/drivers/net/wireless/ti/wl18xx/io.c new file mode 100644 index 000000000000..598c057e722b --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/io.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "../wlcore/wlcore.h" | ||
23 | #include "../wlcore/io.h" | ||
24 | |||
25 | #include "io.h" | ||
26 | |||
27 | void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) | ||
28 | { | ||
29 | u32 tmp; | ||
30 | |||
31 | if (WARN_ON(addr % 2)) | ||
32 | return; | ||
33 | |||
34 | if ((addr % 4) == 0) { | ||
35 | tmp = wl1271_read32(wl, addr); | ||
36 | tmp = (tmp & 0xffff0000) | val; | ||
37 | wl1271_write32(wl, addr, tmp); | ||
38 | } else { | ||
39 | tmp = wl1271_read32(wl, addr - 2); | ||
40 | tmp = (tmp & 0xffff) | (val << 16); | ||
41 | wl1271_write32(wl, addr - 2, tmp); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr) | ||
46 | { | ||
47 | u32 val; | ||
48 | |||
49 | if (WARN_ON(addr % 2)) | ||
50 | return 0; | ||
51 | |||
52 | if ((addr % 4) == 0) { | ||
53 | /* address is 4-bytes aligned */ | ||
54 | val = wl1271_read32(wl, addr); | ||
55 | return val & 0xffff; | ||
56 | } else { | ||
57 | val = wl1271_read32(wl, addr - 2); | ||
58 | return (val & 0xffff0000) >> 16; | ||
59 | } | ||
60 | } | ||
diff --git a/drivers/net/wireless/ti/wl18xx/io.h b/drivers/net/wireless/ti/wl18xx/io.h new file mode 100644 index 000000000000..be4e126ff617 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/io.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_IO_H__ | ||
23 | #define __WL18XX_IO_H__ | ||
24 | |||
25 | void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); | ||
26 | u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr); | ||
27 | |||
28 | #endif /* __WL18XX_IO_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c new file mode 100644 index 000000000000..ed9c3650e08a --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -0,0 +1,1463 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/ip.h> | ||
25 | #include <linux/firmware.h> | ||
26 | |||
27 | #include "../wlcore/wlcore.h" | ||
28 | #include "../wlcore/debug.h" | ||
29 | #include "../wlcore/io.h" | ||
30 | #include "../wlcore/acx.h" | ||
31 | #include "../wlcore/tx.h" | ||
32 | #include "../wlcore/rx.h" | ||
33 | #include "../wlcore/io.h" | ||
34 | #include "../wlcore/boot.h" | ||
35 | |||
36 | #include "reg.h" | ||
37 | #include "conf.h" | ||
38 | #include "acx.h" | ||
39 | #include "tx.h" | ||
40 | #include "wl18xx.h" | ||
41 | #include "io.h" | ||
42 | #include "debugfs.h" | ||
43 | |||
44 | #define WL18XX_RX_CHECKSUM_MASK 0x40 | ||
45 | |||
46 | static char *ht_mode_param = "wide"; | ||
47 | static char *board_type_param = "hdk"; | ||
48 | static bool checksum_param = false; | ||
49 | static bool enable_11a_param = true; | ||
50 | |||
51 | /* phy paramters */ | ||
52 | static int dc2dc_param = -1; | ||
53 | static int n_antennas_2_param = -1; | ||
54 | static int n_antennas_5_param = -1; | ||
55 | static int low_band_component_param = -1; | ||
56 | static int low_band_component_type_param = -1; | ||
57 | static int high_band_component_param = -1; | ||
58 | static int high_band_component_type_param = -1; | ||
59 | static int pwr_limit_reference_11_abg_param = -1; | ||
60 | |||
61 | static const u8 wl18xx_rate_to_idx_2ghz[] = { | ||
62 | /* MCS rates are used only with 11n */ | ||
63 | 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ | ||
64 | 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ | ||
65 | 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ | ||
66 | 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ | ||
67 | 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ | ||
68 | 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ | ||
69 | 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ | ||
70 | 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ | ||
71 | 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ | ||
72 | 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ | ||
73 | 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ | ||
74 | 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ | ||
75 | 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ | ||
76 | 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ | ||
77 | 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ | ||
78 | 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ | ||
79 | |||
80 | 11, /* WL18XX_CONF_HW_RXTX_RATE_54 */ | ||
81 | 10, /* WL18XX_CONF_HW_RXTX_RATE_48 */ | ||
82 | 9, /* WL18XX_CONF_HW_RXTX_RATE_36 */ | ||
83 | 8, /* WL18XX_CONF_HW_RXTX_RATE_24 */ | ||
84 | |||
85 | /* TI-specific rate */ | ||
86 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ | ||
87 | |||
88 | 7, /* WL18XX_CONF_HW_RXTX_RATE_18 */ | ||
89 | 6, /* WL18XX_CONF_HW_RXTX_RATE_12 */ | ||
90 | 3, /* WL18XX_CONF_HW_RXTX_RATE_11 */ | ||
91 | 5, /* WL18XX_CONF_HW_RXTX_RATE_9 */ | ||
92 | 4, /* WL18XX_CONF_HW_RXTX_RATE_6 */ | ||
93 | 2, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ | ||
94 | 1, /* WL18XX_CONF_HW_RXTX_RATE_2 */ | ||
95 | 0 /* WL18XX_CONF_HW_RXTX_RATE_1 */ | ||
96 | }; | ||
97 | |||
98 | static const u8 wl18xx_rate_to_idx_5ghz[] = { | ||
99 | /* MCS rates are used only with 11n */ | ||
100 | 15, /* WL18XX_CONF_HW_RXTX_RATE_MCS15 */ | ||
101 | 14, /* WL18XX_CONF_HW_RXTX_RATE_MCS14 */ | ||
102 | 13, /* WL18XX_CONF_HW_RXTX_RATE_MCS13 */ | ||
103 | 12, /* WL18XX_CONF_HW_RXTX_RATE_MCS12 */ | ||
104 | 11, /* WL18XX_CONF_HW_RXTX_RATE_MCS11 */ | ||
105 | 10, /* WL18XX_CONF_HW_RXTX_RATE_MCS10 */ | ||
106 | 9, /* WL18XX_CONF_HW_RXTX_RATE_MCS9 */ | ||
107 | 8, /* WL18XX_CONF_HW_RXTX_RATE_MCS8 */ | ||
108 | 7, /* WL18XX_CONF_HW_RXTX_RATE_MCS7 */ | ||
109 | 6, /* WL18XX_CONF_HW_RXTX_RATE_MCS6 */ | ||
110 | 5, /* WL18XX_CONF_HW_RXTX_RATE_MCS5 */ | ||
111 | 4, /* WL18XX_CONF_HW_RXTX_RATE_MCS4 */ | ||
112 | 3, /* WL18XX_CONF_HW_RXTX_RATE_MCS3 */ | ||
113 | 2, /* WL18XX_CONF_HW_RXTX_RATE_MCS2 */ | ||
114 | 1, /* WL18XX_CONF_HW_RXTX_RATE_MCS1 */ | ||
115 | 0, /* WL18XX_CONF_HW_RXTX_RATE_MCS0 */ | ||
116 | |||
117 | 7, /* WL18XX_CONF_HW_RXTX_RATE_54 */ | ||
118 | 6, /* WL18XX_CONF_HW_RXTX_RATE_48 */ | ||
119 | 5, /* WL18XX_CONF_HW_RXTX_RATE_36 */ | ||
120 | 4, /* WL18XX_CONF_HW_RXTX_RATE_24 */ | ||
121 | |||
122 | /* TI-specific rate */ | ||
123 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_22 */ | ||
124 | |||
125 | 3, /* WL18XX_CONF_HW_RXTX_RATE_18 */ | ||
126 | 2, /* WL18XX_CONF_HW_RXTX_RATE_12 */ | ||
127 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_11 */ | ||
128 | 1, /* WL18XX_CONF_HW_RXTX_RATE_9 */ | ||
129 | 0, /* WL18XX_CONF_HW_RXTX_RATE_6 */ | ||
130 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_5_5 */ | ||
131 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_2 */ | ||
132 | CONF_HW_RXTX_RATE_UNSUPPORTED, /* WL18XX_CONF_HW_RXTX_RATE_1 */ | ||
133 | }; | ||
134 | |||
135 | static const u8 *wl18xx_band_rate_to_idx[] = { | ||
136 | [IEEE80211_BAND_2GHZ] = wl18xx_rate_to_idx_2ghz, | ||
137 | [IEEE80211_BAND_5GHZ] = wl18xx_rate_to_idx_5ghz | ||
138 | }; | ||
139 | |||
140 | enum wl18xx_hw_rates { | ||
141 | WL18XX_CONF_HW_RXTX_RATE_MCS15 = 0, | ||
142 | WL18XX_CONF_HW_RXTX_RATE_MCS14, | ||
143 | WL18XX_CONF_HW_RXTX_RATE_MCS13, | ||
144 | WL18XX_CONF_HW_RXTX_RATE_MCS12, | ||
145 | WL18XX_CONF_HW_RXTX_RATE_MCS11, | ||
146 | WL18XX_CONF_HW_RXTX_RATE_MCS10, | ||
147 | WL18XX_CONF_HW_RXTX_RATE_MCS9, | ||
148 | WL18XX_CONF_HW_RXTX_RATE_MCS8, | ||
149 | WL18XX_CONF_HW_RXTX_RATE_MCS7, | ||
150 | WL18XX_CONF_HW_RXTX_RATE_MCS6, | ||
151 | WL18XX_CONF_HW_RXTX_RATE_MCS5, | ||
152 | WL18XX_CONF_HW_RXTX_RATE_MCS4, | ||
153 | WL18XX_CONF_HW_RXTX_RATE_MCS3, | ||
154 | WL18XX_CONF_HW_RXTX_RATE_MCS2, | ||
155 | WL18XX_CONF_HW_RXTX_RATE_MCS1, | ||
156 | WL18XX_CONF_HW_RXTX_RATE_MCS0, | ||
157 | WL18XX_CONF_HW_RXTX_RATE_54, | ||
158 | WL18XX_CONF_HW_RXTX_RATE_48, | ||
159 | WL18XX_CONF_HW_RXTX_RATE_36, | ||
160 | WL18XX_CONF_HW_RXTX_RATE_24, | ||
161 | WL18XX_CONF_HW_RXTX_RATE_22, | ||
162 | WL18XX_CONF_HW_RXTX_RATE_18, | ||
163 | WL18XX_CONF_HW_RXTX_RATE_12, | ||
164 | WL18XX_CONF_HW_RXTX_RATE_11, | ||
165 | WL18XX_CONF_HW_RXTX_RATE_9, | ||
166 | WL18XX_CONF_HW_RXTX_RATE_6, | ||
167 | WL18XX_CONF_HW_RXTX_RATE_5_5, | ||
168 | WL18XX_CONF_HW_RXTX_RATE_2, | ||
169 | WL18XX_CONF_HW_RXTX_RATE_1, | ||
170 | WL18XX_CONF_HW_RXTX_RATE_MAX, | ||
171 | }; | ||
172 | |||
173 | static struct wlcore_conf wl18xx_conf = { | ||
174 | .sg = { | ||
175 | .params = { | ||
176 | [CONF_SG_ACL_BT_MASTER_MIN_BR] = 10, | ||
177 | [CONF_SG_ACL_BT_MASTER_MAX_BR] = 180, | ||
178 | [CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10, | ||
179 | [CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180, | ||
180 | [CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10, | ||
181 | [CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80, | ||
182 | [CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10, | ||
183 | [CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80, | ||
184 | [CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8, | ||
185 | [CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8, | ||
186 | [CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20, | ||
187 | [CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20, | ||
188 | [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20, | ||
189 | [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35, | ||
190 | [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16, | ||
191 | [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35, | ||
192 | [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32, | ||
193 | [CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50, | ||
194 | [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28, | ||
195 | [CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50, | ||
196 | [CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10, | ||
197 | [CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20, | ||
198 | [CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75, | ||
199 | [CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15, | ||
200 | [CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27, | ||
201 | [CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17, | ||
202 | /* active scan params */ | ||
203 | [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, | ||
204 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, | ||
205 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, | ||
206 | /* passive scan params */ | ||
207 | [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800, | ||
208 | [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200, | ||
209 | [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, | ||
210 | /* passive scan in dual antenna params */ | ||
211 | [CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0, | ||
212 | [CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0, | ||
213 | [CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0, | ||
214 | /* general params */ | ||
215 | [CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1, | ||
216 | [CONF_SG_ANTENNA_CONFIGURATION] = 0, | ||
217 | [CONF_SG_BEACON_MISS_PERCENT] = 60, | ||
218 | [CONF_SG_DHCP_TIME] = 5000, | ||
219 | [CONF_SG_RXT] = 1200, | ||
220 | [CONF_SG_TXT] = 1000, | ||
221 | [CONF_SG_ADAPTIVE_RXT_TXT] = 1, | ||
222 | [CONF_SG_GENERAL_USAGE_BIT_MAP] = 3, | ||
223 | [CONF_SG_HV3_MAX_SERVED] = 6, | ||
224 | [CONF_SG_PS_POLL_TIMEOUT] = 10, | ||
225 | [CONF_SG_UPSD_TIMEOUT] = 10, | ||
226 | [CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2, | ||
227 | [CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5, | ||
228 | [CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30, | ||
229 | /* AP params */ | ||
230 | [CONF_AP_BEACON_MISS_TX] = 3, | ||
231 | [CONF_AP_RX_WINDOW_AFTER_BEACON] = 10, | ||
232 | [CONF_AP_BEACON_WINDOW_INTERVAL] = 2, | ||
233 | [CONF_AP_CONNECTION_PROTECTION_TIME] = 0, | ||
234 | [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25, | ||
235 | [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25, | ||
236 | /* CTS Diluting params */ | ||
237 | [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0, | ||
238 | [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0, | ||
239 | }, | ||
240 | .state = CONF_SG_PROTECTIVE, | ||
241 | }, | ||
242 | .rx = { | ||
243 | .rx_msdu_life_time = 512000, | ||
244 | .packet_detection_threshold = 0, | ||
245 | .ps_poll_timeout = 15, | ||
246 | .upsd_timeout = 15, | ||
247 | .rts_threshold = IEEE80211_MAX_RTS_THRESHOLD, | ||
248 | .rx_cca_threshold = 0, | ||
249 | .irq_blk_threshold = 0xFFFF, | ||
250 | .irq_pkt_threshold = 0, | ||
251 | .irq_timeout = 600, | ||
252 | .queue_type = CONF_RX_QUEUE_TYPE_LOW_PRIORITY, | ||
253 | }, | ||
254 | .tx = { | ||
255 | .tx_energy_detection = 0, | ||
256 | .sta_rc_conf = { | ||
257 | .enabled_rates = 0, | ||
258 | .short_retry_limit = 10, | ||
259 | .long_retry_limit = 10, | ||
260 | .aflags = 0, | ||
261 | }, | ||
262 | .ac_conf_count = 4, | ||
263 | .ac_conf = { | ||
264 | [CONF_TX_AC_BE] = { | ||
265 | .ac = CONF_TX_AC_BE, | ||
266 | .cw_min = 15, | ||
267 | .cw_max = 63, | ||
268 | .aifsn = 3, | ||
269 | .tx_op_limit = 0, | ||
270 | }, | ||
271 | [CONF_TX_AC_BK] = { | ||
272 | .ac = CONF_TX_AC_BK, | ||
273 | .cw_min = 15, | ||
274 | .cw_max = 63, | ||
275 | .aifsn = 7, | ||
276 | .tx_op_limit = 0, | ||
277 | }, | ||
278 | [CONF_TX_AC_VI] = { | ||
279 | .ac = CONF_TX_AC_VI, | ||
280 | .cw_min = 15, | ||
281 | .cw_max = 63, | ||
282 | .aifsn = CONF_TX_AIFS_PIFS, | ||
283 | .tx_op_limit = 3008, | ||
284 | }, | ||
285 | [CONF_TX_AC_VO] = { | ||
286 | .ac = CONF_TX_AC_VO, | ||
287 | .cw_min = 15, | ||
288 | .cw_max = 63, | ||
289 | .aifsn = CONF_TX_AIFS_PIFS, | ||
290 | .tx_op_limit = 1504, | ||
291 | }, | ||
292 | }, | ||
293 | .max_tx_retries = 100, | ||
294 | .ap_aging_period = 300, | ||
295 | .tid_conf_count = 4, | ||
296 | .tid_conf = { | ||
297 | [CONF_TX_AC_BE] = { | ||
298 | .queue_id = CONF_TX_AC_BE, | ||
299 | .channel_type = CONF_CHANNEL_TYPE_EDCF, | ||
300 | .tsid = CONF_TX_AC_BE, | ||
301 | .ps_scheme = CONF_PS_SCHEME_LEGACY, | ||
302 | .ack_policy = CONF_ACK_POLICY_LEGACY, | ||
303 | .apsd_conf = {0, 0}, | ||
304 | }, | ||
305 | [CONF_TX_AC_BK] = { | ||
306 | .queue_id = CONF_TX_AC_BK, | ||
307 | .channel_type = CONF_CHANNEL_TYPE_EDCF, | ||
308 | .tsid = CONF_TX_AC_BK, | ||
309 | .ps_scheme = CONF_PS_SCHEME_LEGACY, | ||
310 | .ack_policy = CONF_ACK_POLICY_LEGACY, | ||
311 | .apsd_conf = {0, 0}, | ||
312 | }, | ||
313 | [CONF_TX_AC_VI] = { | ||
314 | .queue_id = CONF_TX_AC_VI, | ||
315 | .channel_type = CONF_CHANNEL_TYPE_EDCF, | ||
316 | .tsid = CONF_TX_AC_VI, | ||
317 | .ps_scheme = CONF_PS_SCHEME_LEGACY, | ||
318 | .ack_policy = CONF_ACK_POLICY_LEGACY, | ||
319 | .apsd_conf = {0, 0}, | ||
320 | }, | ||
321 | [CONF_TX_AC_VO] = { | ||
322 | .queue_id = CONF_TX_AC_VO, | ||
323 | .channel_type = CONF_CHANNEL_TYPE_EDCF, | ||
324 | .tsid = CONF_TX_AC_VO, | ||
325 | .ps_scheme = CONF_PS_SCHEME_LEGACY, | ||
326 | .ack_policy = CONF_ACK_POLICY_LEGACY, | ||
327 | .apsd_conf = {0, 0}, | ||
328 | }, | ||
329 | }, | ||
330 | .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, | ||
331 | .tx_compl_timeout = 350, | ||
332 | .tx_compl_threshold = 10, | ||
333 | .basic_rate = CONF_HW_BIT_RATE_1MBPS, | ||
334 | .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, | ||
335 | .tmpl_short_retry_limit = 10, | ||
336 | .tmpl_long_retry_limit = 10, | ||
337 | .tx_watchdog_timeout = 5000, | ||
338 | }, | ||
339 | .conn = { | ||
340 | .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, | ||
341 | .listen_interval = 1, | ||
342 | .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, | ||
343 | .suspend_listen_interval = 3, | ||
344 | .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, | ||
345 | .bcn_filt_ie_count = 3, | ||
346 | .bcn_filt_ie = { | ||
347 | [0] = { | ||
348 | .ie = WLAN_EID_CHANNEL_SWITCH, | ||
349 | .rule = CONF_BCN_RULE_PASS_ON_APPEARANCE, | ||
350 | }, | ||
351 | [1] = { | ||
352 | .ie = WLAN_EID_HT_OPERATION, | ||
353 | .rule = CONF_BCN_RULE_PASS_ON_CHANGE, | ||
354 | }, | ||
355 | [2] = { | ||
356 | .ie = WLAN_EID_ERP_INFO, | ||
357 | .rule = CONF_BCN_RULE_PASS_ON_CHANGE, | ||
358 | }, | ||
359 | }, | ||
360 | .synch_fail_thold = 12, | ||
361 | .bss_lose_timeout = 400, | ||
362 | .beacon_rx_timeout = 10000, | ||
363 | .broadcast_timeout = 20000, | ||
364 | .rx_broadcast_in_ps = 1, | ||
365 | .ps_poll_threshold = 10, | ||
366 | .bet_enable = CONF_BET_MODE_ENABLE, | ||
367 | .bet_max_consecutive = 50, | ||
368 | .psm_entry_retries = 8, | ||
369 | .psm_exit_retries = 16, | ||
370 | .psm_entry_nullfunc_retries = 3, | ||
371 | .dynamic_ps_timeout = 200, | ||
372 | .forced_ps = false, | ||
373 | .keep_alive_interval = 55000, | ||
374 | .max_listen_interval = 20, | ||
375 | }, | ||
376 | .itrim = { | ||
377 | .enable = false, | ||
378 | .timeout = 50000, | ||
379 | }, | ||
380 | .pm_config = { | ||
381 | .host_clk_settling_time = 5000, | ||
382 | .host_fast_wakeup_support = CONF_FAST_WAKEUP_DISABLE, | ||
383 | }, | ||
384 | .roam_trigger = { | ||
385 | .trigger_pacing = 1, | ||
386 | .avg_weight_rssi_beacon = 20, | ||
387 | .avg_weight_rssi_data = 10, | ||
388 | .avg_weight_snr_beacon = 20, | ||
389 | .avg_weight_snr_data = 10, | ||
390 | }, | ||
391 | .scan = { | ||
392 | .min_dwell_time_active = 7500, | ||
393 | .max_dwell_time_active = 30000, | ||
394 | .min_dwell_time_passive = 100000, | ||
395 | .max_dwell_time_passive = 100000, | ||
396 | .num_probe_reqs = 2, | ||
397 | .split_scan_timeout = 50000, | ||
398 | }, | ||
399 | .sched_scan = { | ||
400 | /* | ||
401 | * Values are in TU/1000 but since sched scan FW command | ||
402 | * params are in TUs rounding up may occur. | ||
403 | */ | ||
404 | .base_dwell_time = 7500, | ||
405 | .max_dwell_time_delta = 22500, | ||
406 | /* based on 250bits per probe @1Mbps */ | ||
407 | .dwell_time_delta_per_probe = 2000, | ||
408 | /* based on 250bits per probe @6Mbps (plus a bit more) */ | ||
409 | .dwell_time_delta_per_probe_5 = 350, | ||
410 | .dwell_time_passive = 100000, | ||
411 | .dwell_time_dfs = 150000, | ||
412 | .num_probe_reqs = 2, | ||
413 | .rssi_threshold = -90, | ||
414 | .snr_threshold = 0, | ||
415 | }, | ||
416 | .ht = { | ||
417 | .rx_ba_win_size = 10, | ||
418 | .tx_ba_win_size = 64, | ||
419 | .inactivity_timeout = 10000, | ||
420 | .tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP, | ||
421 | }, | ||
422 | .mem = { | ||
423 | .num_stations = 1, | ||
424 | .ssid_profiles = 1, | ||
425 | .rx_block_num = 40, | ||
426 | .tx_min_block_num = 40, | ||
427 | .dynamic_memory = 1, | ||
428 | .min_req_tx_blocks = 45, | ||
429 | .min_req_rx_blocks = 22, | ||
430 | .tx_min = 27, | ||
431 | }, | ||
432 | .fm_coex = { | ||
433 | .enable = true, | ||
434 | .swallow_period = 5, | ||
435 | .n_divider_fref_set_1 = 0xff, /* default */ | ||
436 | .n_divider_fref_set_2 = 12, | ||
437 | .m_divider_fref_set_1 = 0xffff, | ||
438 | .m_divider_fref_set_2 = 148, /* default */ | ||
439 | .coex_pll_stabilization_time = 0xffffffff, /* default */ | ||
440 | .ldo_stabilization_time = 0xffff, /* default */ | ||
441 | .fm_disturbed_band_margin = 0xff, /* default */ | ||
442 | .swallow_clk_diff = 0xff, /* default */ | ||
443 | }, | ||
444 | .rx_streaming = { | ||
445 | .duration = 150, | ||
446 | .queues = 0x1, | ||
447 | .interval = 20, | ||
448 | .always = 0, | ||
449 | }, | ||
450 | .fwlog = { | ||
451 | .mode = WL12XX_FWLOG_ON_DEMAND, | ||
452 | .mem_blocks = 2, | ||
453 | .severity = 0, | ||
454 | .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, | ||
455 | .output = WL12XX_FWLOG_OUTPUT_HOST, | ||
456 | .threshold = 0, | ||
457 | }, | ||
458 | .rate = { | ||
459 | .rate_retry_score = 32000, | ||
460 | .per_add = 8192, | ||
461 | .per_th1 = 2048, | ||
462 | .per_th2 = 4096, | ||
463 | .max_per = 8100, | ||
464 | .inverse_curiosity_factor = 5, | ||
465 | .tx_fail_low_th = 4, | ||
466 | .tx_fail_high_th = 10, | ||
467 | .per_alpha_shift = 4, | ||
468 | .per_add_shift = 13, | ||
469 | .per_beta1_shift = 10, | ||
470 | .per_beta2_shift = 8, | ||
471 | .rate_check_up = 2, | ||
472 | .rate_check_down = 12, | ||
473 | .rate_retry_policy = { | ||
474 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
475 | 0x00, 0x00, 0x00, 0x00, 0x00, | ||
476 | 0x00, 0x00, 0x00, | ||
477 | }, | ||
478 | }, | ||
479 | .hangover = { | ||
480 | .recover_time = 0, | ||
481 | .hangover_period = 20, | ||
482 | .dynamic_mode = 1, | ||
483 | .early_termination_mode = 1, | ||
484 | .max_period = 20, | ||
485 | .min_period = 1, | ||
486 | .increase_delta = 1, | ||
487 | .decrease_delta = 2, | ||
488 | .quiet_time = 4, | ||
489 | .increase_time = 1, | ||
490 | .window_size = 16, | ||
491 | }, | ||
492 | }; | ||
493 | |||
494 | static struct wl18xx_priv_conf wl18xx_default_priv_conf = { | ||
495 | .phy = { | ||
496 | .phy_standalone = 0x00, | ||
497 | .primary_clock_setting_time = 0x05, | ||
498 | .clock_valid_on_wake_up = 0x00, | ||
499 | .secondary_clock_setting_time = 0x05, | ||
500 | .rdl = 0x01, | ||
501 | .auto_detect = 0x00, | ||
502 | .dedicated_fem = FEM_NONE, | ||
503 | .low_band_component = COMPONENT_2_WAY_SWITCH, | ||
504 | .low_band_component_type = 0x05, | ||
505 | .high_band_component = COMPONENT_2_WAY_SWITCH, | ||
506 | .high_band_component_type = 0x09, | ||
507 | .tcxo_ldo_voltage = 0x00, | ||
508 | .xtal_itrim_val = 0x04, | ||
509 | .srf_state = 0x00, | ||
510 | .io_configuration = 0x01, | ||
511 | .sdio_configuration = 0x00, | ||
512 | .settings = 0x00, | ||
513 | .enable_clpc = 0x00, | ||
514 | .enable_tx_low_pwr_on_siso_rdl = 0x00, | ||
515 | .rx_profile = 0x00, | ||
516 | .pwr_limit_reference_11_abg = 0xc8, | ||
517 | .psat = 0, | ||
518 | .low_power_val = 0x00, | ||
519 | .med_power_val = 0x0a, | ||
520 | .high_power_val = 0x1e, | ||
521 | .external_pa_dc2dc = 0, | ||
522 | .number_of_assembled_ant2_4 = 1, | ||
523 | .number_of_assembled_ant5 = 1, | ||
524 | }, | ||
525 | }; | ||
526 | |||
527 | static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { | ||
528 | [PART_TOP_PRCM_ELP_SOC] = { | ||
529 | .mem = { .start = 0x00A02000, .size = 0x00010000 }, | ||
530 | .reg = { .start = 0x00807000, .size = 0x00005000 }, | ||
531 | .mem2 = { .start = 0x00800000, .size = 0x0000B000 }, | ||
532 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | ||
533 | }, | ||
534 | [PART_DOWN] = { | ||
535 | .mem = { .start = 0x00000000, .size = 0x00014000 }, | ||
536 | .reg = { .start = 0x00810000, .size = 0x0000BFFF }, | ||
537 | .mem2 = { .start = 0x00000000, .size = 0x00000000 }, | ||
538 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | ||
539 | }, | ||
540 | [PART_BOOT] = { | ||
541 | .mem = { .start = 0x00700000, .size = 0x0000030c }, | ||
542 | .reg = { .start = 0x00802000, .size = 0x00014578 }, | ||
543 | .mem2 = { .start = 0x00B00404, .size = 0x00001000 }, | ||
544 | .mem3 = { .start = 0x00C00000, .size = 0x00000400 }, | ||
545 | }, | ||
546 | [PART_WORK] = { | ||
547 | .mem = { .start = 0x00800000, .size = 0x000050FC }, | ||
548 | .reg = { .start = 0x00B00404, .size = 0x00001000 }, | ||
549 | .mem2 = { .start = 0x00C00000, .size = 0x00000400 }, | ||
550 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | ||
551 | }, | ||
552 | [PART_PHY_INIT] = { | ||
553 | .mem = { .start = 0x80926000, | ||
554 | .size = sizeof(struct wl18xx_mac_and_phy_params) }, | ||
555 | .reg = { .start = 0x00000000, .size = 0x00000000 }, | ||
556 | .mem2 = { .start = 0x00000000, .size = 0x00000000 }, | ||
557 | .mem3 = { .start = 0x00000000, .size = 0x00000000 }, | ||
558 | }, | ||
559 | }; | ||
560 | |||
561 | static const int wl18xx_rtable[REG_TABLE_LEN] = { | ||
562 | [REG_ECPU_CONTROL] = WL18XX_REG_ECPU_CONTROL, | ||
563 | [REG_INTERRUPT_NO_CLEAR] = WL18XX_REG_INTERRUPT_NO_CLEAR, | ||
564 | [REG_INTERRUPT_ACK] = WL18XX_REG_INTERRUPT_ACK, | ||
565 | [REG_COMMAND_MAILBOX_PTR] = WL18XX_REG_COMMAND_MAILBOX_PTR, | ||
566 | [REG_EVENT_MAILBOX_PTR] = WL18XX_REG_EVENT_MAILBOX_PTR, | ||
567 | [REG_INTERRUPT_TRIG] = WL18XX_REG_INTERRUPT_TRIG_H, | ||
568 | [REG_INTERRUPT_MASK] = WL18XX_REG_INTERRUPT_MASK, | ||
569 | [REG_PC_ON_RECOVERY] = WL18XX_SCR_PAD4, | ||
570 | [REG_CHIP_ID_B] = WL18XX_REG_CHIP_ID_B, | ||
571 | [REG_CMD_MBOX_ADDRESS] = WL18XX_CMD_MBOX_ADDRESS, | ||
572 | |||
573 | /* data access memory addresses, used with partition translation */ | ||
574 | [REG_SLV_MEM_DATA] = WL18XX_SLV_MEM_DATA, | ||
575 | [REG_SLV_REG_DATA] = WL18XX_SLV_REG_DATA, | ||
576 | |||
577 | /* raw data access memory addresses */ | ||
578 | [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, | ||
579 | }; | ||
580 | |||
581 | static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = { | ||
582 | [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true }, | ||
583 | [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true }, | ||
584 | [CLOCK_CONFIG_16_8_M] = { 7, 100, 0, 0, false }, | ||
585 | [CLOCK_CONFIG_19_2_M] = { 8, 100, 0, 0, false }, | ||
586 | [CLOCK_CONFIG_26_M] = { 13, 120, 0, 0, false }, | ||
587 | [CLOCK_CONFIG_32_736_M] = { 9, 132, 3751, 4, true }, | ||
588 | [CLOCK_CONFIG_33_6_M] = { 7, 100, 0, 0, false }, | ||
589 | [CLOCK_CONFIG_38_468_M] = { 8, 100, 0, 0, false }, | ||
590 | [CLOCK_CONFIG_52_M] = { 13, 120, 0, 0, false }, | ||
591 | }; | ||
592 | |||
593 | /* TODO: maybe move to a new header file? */ | ||
594 | #define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw.bin" | ||
595 | |||
596 | static int wl18xx_identify_chip(struct wl1271 *wl) | ||
597 | { | ||
598 | int ret = 0; | ||
599 | |||
600 | switch (wl->chip.id) { | ||
601 | case CHIP_ID_185x_PG20: | ||
602 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG20)", | ||
603 | wl->chip.id); | ||
604 | wl->sr_fw_name = WL18XX_FW_NAME; | ||
605 | /* wl18xx uses the same firmware for PLT */ | ||
606 | wl->plt_fw_name = WL18XX_FW_NAME; | ||
607 | wl->quirks |= WLCORE_QUIRK_NO_ELP | | ||
608 | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | | ||
609 | WLCORE_QUIRK_TX_PAD_LAST_FRAME; | ||
610 | |||
611 | break; | ||
612 | case CHIP_ID_185x_PG10: | ||
613 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", | ||
614 | wl->chip.id); | ||
615 | wl->sr_fw_name = WL18XX_FW_NAME; | ||
616 | /* wl18xx uses the same firmware for PLT */ | ||
617 | wl->plt_fw_name = WL18XX_FW_NAME; | ||
618 | wl->quirks |= WLCORE_QUIRK_NO_ELP | | ||
619 | WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | | ||
620 | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | | ||
621 | WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; | ||
622 | |||
623 | /* PG 1.0 has some problems with MCS_13, so disable it */ | ||
624 | wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5); | ||
625 | |||
626 | break; | ||
627 | default: | ||
628 | wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); | ||
629 | ret = -ENODEV; | ||
630 | goto out; | ||
631 | } | ||
632 | |||
633 | out: | ||
634 | return ret; | ||
635 | } | ||
636 | |||
637 | static void wl18xx_set_clk(struct wl1271 *wl) | ||
638 | { | ||
639 | u32 clk_freq; | ||
640 | |||
641 | wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); | ||
642 | |||
643 | /* TODO: PG2: apparently we need to read the clk type */ | ||
644 | |||
645 | clk_freq = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT); | ||
646 | wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq, | ||
647 | wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m, | ||
648 | wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, | ||
649 | wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); | ||
650 | |||
651 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n); | ||
652 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, wl18xx_clk_table[clk_freq].m); | ||
653 | |||
654 | if (wl18xx_clk_table[clk_freq].swallow) { | ||
655 | /* first the 16 lower bits */ | ||
656 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, | ||
657 | wl18xx_clk_table[clk_freq].q & | ||
658 | PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); | ||
659 | /* then the 16 higher bits, masked out */ | ||
660 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, | ||
661 | (wl18xx_clk_table[clk_freq].q >> 16) & | ||
662 | PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); | ||
663 | |||
664 | /* first the 16 lower bits */ | ||
665 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, | ||
666 | wl18xx_clk_table[clk_freq].p & | ||
667 | PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); | ||
668 | /* then the 16 higher bits, masked out */ | ||
669 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, | ||
670 | (wl18xx_clk_table[clk_freq].p >> 16) & | ||
671 | PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); | ||
672 | } else { | ||
673 | wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, | ||
674 | PLLSH_WCS_PLL_SWALLOW_EN_VAL2); | ||
675 | } | ||
676 | } | ||
677 | |||
678 | static void wl18xx_boot_soft_reset(struct wl1271 *wl) | ||
679 | { | ||
680 | /* disable Rx/Tx */ | ||
681 | wl1271_write32(wl, WL18XX_ENABLE, 0x0); | ||
682 | |||
683 | /* disable auto calibration on start*/ | ||
684 | wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff); | ||
685 | } | ||
686 | |||
687 | static int wl18xx_pre_boot(struct wl1271 *wl) | ||
688 | { | ||
689 | wl18xx_set_clk(wl); | ||
690 | |||
691 | /* Continue the ELP wake up sequence */ | ||
692 | wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); | ||
693 | udelay(500); | ||
694 | |||
695 | wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); | ||
696 | |||
697 | /* Disable interrupts */ | ||
698 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); | ||
699 | |||
700 | wl18xx_boot_soft_reset(wl); | ||
701 | |||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static void wl18xx_pre_upload(struct wl1271 *wl) | ||
706 | { | ||
707 | u32 tmp; | ||
708 | |||
709 | wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); | ||
710 | |||
711 | /* TODO: check if this is all needed */ | ||
712 | wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); | ||
713 | |||
714 | tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); | ||
715 | |||
716 | wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); | ||
717 | |||
718 | tmp = wl1271_read32(wl, WL18XX_SCR_PAD2); | ||
719 | } | ||
720 | |||
721 | static void wl18xx_set_mac_and_phy(struct wl1271 *wl) | ||
722 | { | ||
723 | struct wl18xx_priv *priv = wl->priv; | ||
724 | size_t len; | ||
725 | |||
726 | /* the parameters struct is smaller for PG1 */ | ||
727 | if (wl->chip.id == CHIP_ID_185x_PG10) | ||
728 | len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1; | ||
729 | else | ||
730 | len = sizeof(struct wl18xx_mac_and_phy_params); | ||
731 | |||
732 | wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); | ||
733 | wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len, | ||
734 | false); | ||
735 | } | ||
736 | |||
737 | static void wl18xx_enable_interrupts(struct wl1271 *wl) | ||
738 | { | ||
739 | u32 event_mask, intr_mask; | ||
740 | |||
741 | if (wl->chip.id == CHIP_ID_185x_PG10) { | ||
742 | event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; | ||
743 | intr_mask = WL18XX_INTR_MASK_PG1; | ||
744 | } else { | ||
745 | event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2; | ||
746 | intr_mask = WL18XX_INTR_MASK_PG2; | ||
747 | } | ||
748 | |||
749 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); | ||
750 | |||
751 | wlcore_enable_interrupts(wl); | ||
752 | wlcore_write_reg(wl, REG_INTERRUPT_MASK, | ||
753 | WL1271_ACX_INTR_ALL & ~intr_mask); | ||
754 | } | ||
755 | |||
756 | static int wl18xx_boot(struct wl1271 *wl) | ||
757 | { | ||
758 | int ret; | ||
759 | |||
760 | ret = wl18xx_pre_boot(wl); | ||
761 | if (ret < 0) | ||
762 | goto out; | ||
763 | |||
764 | wl18xx_pre_upload(wl); | ||
765 | |||
766 | ret = wlcore_boot_upload_firmware(wl); | ||
767 | if (ret < 0) | ||
768 | goto out; | ||
769 | |||
770 | wl18xx_set_mac_and_phy(wl); | ||
771 | |||
772 | ret = wlcore_boot_run_firmware(wl); | ||
773 | if (ret < 0) | ||
774 | goto out; | ||
775 | |||
776 | wl18xx_enable_interrupts(wl); | ||
777 | |||
778 | out: | ||
779 | return ret; | ||
780 | } | ||
781 | |||
782 | static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, | ||
783 | void *buf, size_t len) | ||
784 | { | ||
785 | struct wl18xx_priv *priv = wl->priv; | ||
786 | |||
787 | memcpy(priv->cmd_buf, buf, len); | ||
788 | memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len); | ||
789 | |||
790 | wl1271_write(wl, cmd_box_addr, priv->cmd_buf, WL18XX_CMD_MAX_SIZE, | ||
791 | false); | ||
792 | } | ||
793 | |||
794 | static void wl18xx_ack_event(struct wl1271 *wl) | ||
795 | { | ||
796 | wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); | ||
797 | } | ||
798 | |||
799 | static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) | ||
800 | { | ||
801 | u32 blk_size = WL18XX_TX_HW_BLOCK_SIZE; | ||
802 | return (len + blk_size - 1) / blk_size + spare_blks; | ||
803 | } | ||
804 | |||
805 | static void | ||
806 | wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, | ||
807 | u32 blks, u32 spare_blks) | ||
808 | { | ||
809 | desc->wl18xx_mem.total_mem_blocks = blks; | ||
810 | } | ||
811 | |||
812 | static void | ||
813 | wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, | ||
814 | struct sk_buff *skb) | ||
815 | { | ||
816 | desc->length = cpu_to_le16(skb->len); | ||
817 | |||
818 | /* if only the last frame is to be padded, we unset this bit on Tx */ | ||
819 | if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) | ||
820 | desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED; | ||
821 | else | ||
822 | desc->wl18xx_mem.ctrl = 0; | ||
823 | |||
824 | wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " | ||
825 | "len: %d life: %d mem: %d", desc->hlid, | ||
826 | le16_to_cpu(desc->length), | ||
827 | le16_to_cpu(desc->life_time), | ||
828 | desc->wl18xx_mem.total_mem_blocks); | ||
829 | } | ||
830 | |||
831 | static enum wl_rx_buf_align | ||
832 | wl18xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) | ||
833 | { | ||
834 | if (rx_desc & RX_BUF_PADDED_PAYLOAD) | ||
835 | return WLCORE_RX_BUF_PADDED; | ||
836 | |||
837 | return WLCORE_RX_BUF_ALIGNED; | ||
838 | } | ||
839 | |||
840 | static u32 wl18xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, | ||
841 | u32 data_len) | ||
842 | { | ||
843 | struct wl1271_rx_descriptor *desc = rx_data; | ||
844 | |||
845 | /* invalid packet */ | ||
846 | if (data_len < sizeof(*desc)) | ||
847 | return 0; | ||
848 | |||
849 | return data_len - sizeof(*desc); | ||
850 | } | ||
851 | |||
852 | static void wl18xx_tx_immediate_completion(struct wl1271 *wl) | ||
853 | { | ||
854 | wl18xx_tx_immediate_complete(wl); | ||
855 | } | ||
856 | |||
857 | static int wl18xx_set_host_cfg_bitmap(struct wl1271 *wl, u32 extra_mem_blk) | ||
858 | { | ||
859 | int ret; | ||
860 | u32 sdio_align_size = 0; | ||
861 | u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE | | ||
862 | HOST_IF_CFG_ADD_RX_ALIGNMENT; | ||
863 | |||
864 | /* Enable Tx SDIO padding */ | ||
865 | if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) { | ||
866 | host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; | ||
867 | sdio_align_size = WL12XX_BUS_BLOCK_SIZE; | ||
868 | } | ||
869 | |||
870 | /* Enable Rx SDIO padding */ | ||
871 | if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN) { | ||
872 | host_cfg_bitmap |= HOST_IF_CFG_RX_PAD_TO_SDIO_BLK; | ||
873 | sdio_align_size = WL12XX_BUS_BLOCK_SIZE; | ||
874 | } | ||
875 | |||
876 | ret = wl18xx_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap, | ||
877 | sdio_align_size, extra_mem_blk, | ||
878 | WL18XX_HOST_IF_LEN_SIZE_FIELD); | ||
879 | if (ret < 0) | ||
880 | return ret; | ||
881 | |||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static int wl18xx_hw_init(struct wl1271 *wl) | ||
886 | { | ||
887 | int ret; | ||
888 | struct wl18xx_priv *priv = wl->priv; | ||
889 | |||
890 | /* (re)init private structures. Relevant on recovery as well. */ | ||
891 | priv->last_fw_rls_idx = 0; | ||
892 | priv->extra_spare_vif_count = 0; | ||
893 | |||
894 | /* set the default amount of spare blocks in the bitmap */ | ||
895 | ret = wl18xx_set_host_cfg_bitmap(wl, WL18XX_TX_HW_BLOCK_SPARE); | ||
896 | if (ret < 0) | ||
897 | return ret; | ||
898 | |||
899 | if (checksum_param) { | ||
900 | ret = wl18xx_acx_set_checksum_state(wl); | ||
901 | if (ret != 0) | ||
902 | return ret; | ||
903 | } | ||
904 | |||
905 | return ret; | ||
906 | } | ||
907 | |||
908 | static void wl18xx_set_tx_desc_csum(struct wl1271 *wl, | ||
909 | struct wl1271_tx_hw_descr *desc, | ||
910 | struct sk_buff *skb) | ||
911 | { | ||
912 | u32 ip_hdr_offset; | ||
913 | struct iphdr *ip_hdr; | ||
914 | |||
915 | if (!checksum_param) { | ||
916 | desc->wl18xx_checksum_data = 0; | ||
917 | return; | ||
918 | } | ||
919 | |||
920 | if (skb->ip_summed != CHECKSUM_PARTIAL) { | ||
921 | desc->wl18xx_checksum_data = 0; | ||
922 | return; | ||
923 | } | ||
924 | |||
925 | ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb); | ||
926 | if (WARN_ON(ip_hdr_offset >= (1<<7))) { | ||
927 | desc->wl18xx_checksum_data = 0; | ||
928 | return; | ||
929 | } | ||
930 | |||
931 | desc->wl18xx_checksum_data = ip_hdr_offset << 1; | ||
932 | |||
933 | /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */ | ||
934 | ip_hdr = (void *)skb_network_header(skb); | ||
935 | desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01); | ||
936 | } | ||
937 | |||
938 | static void wl18xx_set_rx_csum(struct wl1271 *wl, | ||
939 | struct wl1271_rx_descriptor *desc, | ||
940 | struct sk_buff *skb) | ||
941 | { | ||
942 | if (desc->status & WL18XX_RX_CHECKSUM_MASK) | ||
943 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
944 | } | ||
945 | |||
946 | /* | ||
947 | * TODO: instead of having these two functions to get the rate mask, | ||
948 | * we should modify the wlvif->rate_set instead | ||
949 | */ | ||
950 | static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, | ||
951 | struct wl12xx_vif *wlvif) | ||
952 | { | ||
953 | u32 hw_rate_set = wlvif->rate_set; | ||
954 | |||
955 | if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || | ||
956 | wlvif->channel_type == NL80211_CHAN_HT40PLUS) { | ||
957 | wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); | ||
958 | hw_rate_set |= CONF_TX_RATE_USE_WIDE_CHAN; | ||
959 | |||
960 | /* we don't support MIMO in wide-channel mode */ | ||
961 | hw_rate_set &= ~CONF_TX_MIMO_RATES; | ||
962 | } | ||
963 | |||
964 | return hw_rate_set; | ||
965 | } | ||
966 | |||
967 | static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, | ||
968 | struct wl12xx_vif *wlvif) | ||
969 | { | ||
970 | if ((wlvif->channel_type == NL80211_CHAN_HT40MINUS || | ||
971 | wlvif->channel_type == NL80211_CHAN_HT40PLUS) && | ||
972 | !strcmp(ht_mode_param, "wide")) { | ||
973 | wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); | ||
974 | return CONF_TX_RATE_USE_WIDE_CHAN; | ||
975 | } else if (!strcmp(ht_mode_param, "mimo")) { | ||
976 | wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); | ||
977 | |||
978 | /* | ||
979 | * PG 1.0 has some problems with MCS_13, so disable it | ||
980 | * | ||
981 | * TODO: instead of hacking this in here, we should | ||
982 | * make it more general and change a bit in the | ||
983 | * wlvif->rate_set instead. | ||
984 | */ | ||
985 | if (wl->chip.id == CHIP_ID_185x_PG10) | ||
986 | return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13; | ||
987 | |||
988 | return CONF_TX_MIMO_RATES; | ||
989 | } else { | ||
990 | return 0; | ||
991 | } | ||
992 | } | ||
993 | |||
994 | static s8 wl18xx_get_pg_ver(struct wl1271 *wl) | ||
995 | { | ||
996 | u32 fuse; | ||
997 | |||
998 | wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); | ||
999 | |||
1000 | fuse = wl1271_read32(wl, WL18XX_REG_FUSE_DATA_1_3); | ||
1001 | fuse = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; | ||
1002 | |||
1003 | wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); | ||
1004 | |||
1005 | return (s8)fuse; | ||
1006 | } | ||
1007 | |||
1008 | #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" | ||
1009 | static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) | ||
1010 | { | ||
1011 | struct wl18xx_priv *priv = wl->priv; | ||
1012 | struct wlcore_conf_file *conf_file; | ||
1013 | const struct firmware *fw; | ||
1014 | int ret; | ||
1015 | |||
1016 | ret = request_firmware(&fw, WL18XX_CONF_FILE_NAME, dev); | ||
1017 | if (ret < 0) { | ||
1018 | wl1271_error("could not get configuration binary %s: %d", | ||
1019 | WL18XX_CONF_FILE_NAME, ret); | ||
1020 | goto out_fallback; | ||
1021 | } | ||
1022 | |||
1023 | if (fw->size != WL18XX_CONF_SIZE) { | ||
1024 | wl1271_error("configuration binary file size is wrong, " | ||
1025 | "expected %ld got %zd", | ||
1026 | WL18XX_CONF_SIZE, fw->size); | ||
1027 | ret = -EINVAL; | ||
1028 | goto out; | ||
1029 | } | ||
1030 | |||
1031 | conf_file = (struct wlcore_conf_file *) fw->data; | ||
1032 | |||
1033 | if (conf_file->header.magic != cpu_to_le32(WL18XX_CONF_MAGIC)) { | ||
1034 | wl1271_error("configuration binary file magic number mismatch, " | ||
1035 | "expected 0x%0x got 0x%0x", WL18XX_CONF_MAGIC, | ||
1036 | conf_file->header.magic); | ||
1037 | ret = -EINVAL; | ||
1038 | goto out; | ||
1039 | } | ||
1040 | |||
1041 | if (conf_file->header.version != cpu_to_le32(WL18XX_CONF_VERSION)) { | ||
1042 | wl1271_error("configuration binary file version not supported, " | ||
1043 | "expected 0x%08x got 0x%08x", | ||
1044 | WL18XX_CONF_VERSION, conf_file->header.version); | ||
1045 | ret = -EINVAL; | ||
1046 | goto out; | ||
1047 | } | ||
1048 | |||
1049 | memcpy(&wl->conf, &conf_file->core, sizeof(wl18xx_conf)); | ||
1050 | memcpy(&priv->conf, &conf_file->priv, sizeof(priv->conf)); | ||
1051 | |||
1052 | goto out; | ||
1053 | |||
1054 | out_fallback: | ||
1055 | wl1271_warning("falling back to default config"); | ||
1056 | |||
1057 | /* apply driver default configuration */ | ||
1058 | memcpy(&wl->conf, &wl18xx_conf, sizeof(wl18xx_conf)); | ||
1059 | /* apply default private configuration */ | ||
1060 | memcpy(&priv->conf, &wl18xx_default_priv_conf, sizeof(priv->conf)); | ||
1061 | |||
1062 | /* For now we just fallback */ | ||
1063 | return 0; | ||
1064 | |||
1065 | out: | ||
1066 | release_firmware(fw); | ||
1067 | return ret; | ||
1068 | } | ||
1069 | |||
1070 | static int wl18xx_plt_init(struct wl1271 *wl) | ||
1071 | { | ||
1072 | wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); | ||
1073 | |||
1074 | return wl->ops->boot(wl); | ||
1075 | } | ||
1076 | |||
1077 | static void wl18xx_get_mac(struct wl1271 *wl) | ||
1078 | { | ||
1079 | u32 mac1, mac2; | ||
1080 | |||
1081 | wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); | ||
1082 | |||
1083 | mac1 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1); | ||
1084 | mac2 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2); | ||
1085 | |||
1086 | /* these are the two parts of the BD_ADDR */ | ||
1087 | wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + | ||
1088 | ((mac1 & 0xff000000) >> 24); | ||
1089 | wl->fuse_nic_addr = (mac1 & 0xffffff); | ||
1090 | |||
1091 | wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); | ||
1092 | } | ||
1093 | |||
1094 | static int wl18xx_handle_static_data(struct wl1271 *wl, | ||
1095 | struct wl1271_static_data *static_data) | ||
1096 | { | ||
1097 | struct wl18xx_static_data_priv *static_data_priv = | ||
1098 | (struct wl18xx_static_data_priv *) static_data->priv; | ||
1099 | |||
1100 | wl1271_info("PHY firmware version: %s", static_data_priv->phy_version); | ||
1101 | |||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1105 | static int wl18xx_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
1106 | { | ||
1107 | struct wl18xx_priv *priv = wl->priv; | ||
1108 | |||
1109 | /* If we have VIFs requiring extra spare, indulge them */ | ||
1110 | if (priv->extra_spare_vif_count) | ||
1111 | return WL18XX_TX_HW_EXTRA_BLOCK_SPARE; | ||
1112 | |||
1113 | return WL18XX_TX_HW_BLOCK_SPARE; | ||
1114 | } | ||
1115 | |||
1116 | static int wl18xx_set_key(struct wl1271 *wl, enum set_key_cmd cmd, | ||
1117 | struct ieee80211_vif *vif, | ||
1118 | struct ieee80211_sta *sta, | ||
1119 | struct ieee80211_key_conf *key_conf) | ||
1120 | { | ||
1121 | struct wl18xx_priv *priv = wl->priv; | ||
1122 | bool change_spare = false; | ||
1123 | int ret; | ||
1124 | |||
1125 | /* | ||
1126 | * when adding the first or removing the last GEM/TKIP interface, | ||
1127 | * we have to adjust the number of spare blocks. | ||
1128 | */ | ||
1129 | change_spare = (key_conf->cipher == WL1271_CIPHER_SUITE_GEM || | ||
1130 | key_conf->cipher == WLAN_CIPHER_SUITE_TKIP) && | ||
1131 | ((priv->extra_spare_vif_count == 0 && cmd == SET_KEY) || | ||
1132 | (priv->extra_spare_vif_count == 1 && cmd == DISABLE_KEY)); | ||
1133 | |||
1134 | /* no need to change spare - just regular set_key */ | ||
1135 | if (!change_spare) | ||
1136 | return wlcore_set_key(wl, cmd, vif, sta, key_conf); | ||
1137 | |||
1138 | /* | ||
1139 | * stop the queues and flush to ensure the next packets are | ||
1140 | * in sync with FW spare block accounting | ||
1141 | */ | ||
1142 | wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); | ||
1143 | wl1271_tx_flush(wl); | ||
1144 | |||
1145 | ret = wlcore_set_key(wl, cmd, vif, sta, key_conf); | ||
1146 | if (ret < 0) | ||
1147 | goto out; | ||
1148 | |||
1149 | /* key is now set, change the spare blocks */ | ||
1150 | if (cmd == SET_KEY) { | ||
1151 | ret = wl18xx_set_host_cfg_bitmap(wl, | ||
1152 | WL18XX_TX_HW_EXTRA_BLOCK_SPARE); | ||
1153 | if (ret < 0) | ||
1154 | goto out; | ||
1155 | |||
1156 | priv->extra_spare_vif_count++; | ||
1157 | } else { | ||
1158 | ret = wl18xx_set_host_cfg_bitmap(wl, | ||
1159 | WL18XX_TX_HW_BLOCK_SPARE); | ||
1160 | if (ret < 0) | ||
1161 | goto out; | ||
1162 | |||
1163 | priv->extra_spare_vif_count--; | ||
1164 | } | ||
1165 | |||
1166 | out: | ||
1167 | wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK); | ||
1168 | return ret; | ||
1169 | } | ||
1170 | |||
1171 | static u32 wl18xx_pre_pkt_send(struct wl1271 *wl, | ||
1172 | u32 buf_offset, u32 last_len) | ||
1173 | { | ||
1174 | if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) { | ||
1175 | struct wl1271_tx_hw_descr *last_desc; | ||
1176 | |||
1177 | /* get the last TX HW descriptor written to the aggr buf */ | ||
1178 | last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf + | ||
1179 | buf_offset - last_len); | ||
1180 | |||
1181 | /* the last frame is padded up to an SDIO block */ | ||
1182 | last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED; | ||
1183 | return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE); | ||
1184 | } | ||
1185 | |||
1186 | /* no modifications */ | ||
1187 | return buf_offset; | ||
1188 | } | ||
1189 | |||
1190 | static struct wlcore_ops wl18xx_ops = { | ||
1191 | .identify_chip = wl18xx_identify_chip, | ||
1192 | .boot = wl18xx_boot, | ||
1193 | .plt_init = wl18xx_plt_init, | ||
1194 | .trigger_cmd = wl18xx_trigger_cmd, | ||
1195 | .ack_event = wl18xx_ack_event, | ||
1196 | .calc_tx_blocks = wl18xx_calc_tx_blocks, | ||
1197 | .set_tx_desc_blocks = wl18xx_set_tx_desc_blocks, | ||
1198 | .set_tx_desc_data_len = wl18xx_set_tx_desc_data_len, | ||
1199 | .get_rx_buf_align = wl18xx_get_rx_buf_align, | ||
1200 | .get_rx_packet_len = wl18xx_get_rx_packet_len, | ||
1201 | .tx_immediate_compl = wl18xx_tx_immediate_completion, | ||
1202 | .tx_delayed_compl = NULL, | ||
1203 | .hw_init = wl18xx_hw_init, | ||
1204 | .set_tx_desc_csum = wl18xx_set_tx_desc_csum, | ||
1205 | .get_pg_ver = wl18xx_get_pg_ver, | ||
1206 | .set_rx_csum = wl18xx_set_rx_csum, | ||
1207 | .sta_get_ap_rate_mask = wl18xx_sta_get_ap_rate_mask, | ||
1208 | .ap_get_mimo_wide_rate_mask = wl18xx_ap_get_mimo_wide_rate_mask, | ||
1209 | .get_mac = wl18xx_get_mac, | ||
1210 | .debugfs_init = wl18xx_debugfs_add_files, | ||
1211 | .handle_static_data = wl18xx_handle_static_data, | ||
1212 | .get_spare_blocks = wl18xx_get_spare_blocks, | ||
1213 | .set_key = wl18xx_set_key, | ||
1214 | .pre_pkt_send = wl18xx_pre_pkt_send, | ||
1215 | }; | ||
1216 | |||
1217 | /* HT cap appropriate for wide channels */ | ||
1218 | static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = { | ||
1219 | .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | | ||
1220 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, | ||
1221 | .ht_supported = true, | ||
1222 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, | ||
1223 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, | ||
1224 | .mcs = { | ||
1225 | .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, | ||
1226 | .rx_highest = cpu_to_le16(150), | ||
1227 | .tx_params = IEEE80211_HT_MCS_TX_DEFINED, | ||
1228 | }, | ||
1229 | }; | ||
1230 | |||
1231 | /* HT cap appropriate for SISO 20 */ | ||
1232 | static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { | ||
1233 | .cap = IEEE80211_HT_CAP_SGI_20, | ||
1234 | .ht_supported = true, | ||
1235 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, | ||
1236 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, | ||
1237 | .mcs = { | ||
1238 | .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, | ||
1239 | .rx_highest = cpu_to_le16(72), | ||
1240 | .tx_params = IEEE80211_HT_MCS_TX_DEFINED, | ||
1241 | }, | ||
1242 | }; | ||
1243 | |||
1244 | /* HT cap appropriate for MIMO rates in 20mhz channel */ | ||
1245 | static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { | ||
1246 | .cap = IEEE80211_HT_CAP_SGI_20, | ||
1247 | .ht_supported = true, | ||
1248 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, | ||
1249 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, | ||
1250 | .mcs = { | ||
1251 | .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, }, | ||
1252 | .rx_highest = cpu_to_le16(144), | ||
1253 | .tx_params = IEEE80211_HT_MCS_TX_DEFINED, | ||
1254 | }, | ||
1255 | }; | ||
1256 | |||
1257 | static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = { | ||
1258 | .cap = IEEE80211_HT_CAP_SGI_20, | ||
1259 | .ht_supported = true, | ||
1260 | .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, | ||
1261 | .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, | ||
1262 | .mcs = { | ||
1263 | .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, | ||
1264 | .rx_highest = cpu_to_le16(72), | ||
1265 | .tx_params = IEEE80211_HT_MCS_TX_DEFINED, | ||
1266 | }, | ||
1267 | }; | ||
1268 | |||
1269 | static int __devinit wl18xx_probe(struct platform_device *pdev) | ||
1270 | { | ||
1271 | struct wl1271 *wl; | ||
1272 | struct ieee80211_hw *hw; | ||
1273 | struct wl18xx_priv *priv; | ||
1274 | int ret; | ||
1275 | |||
1276 | hw = wlcore_alloc_hw(sizeof(*priv)); | ||
1277 | if (IS_ERR(hw)) { | ||
1278 | wl1271_error("can't allocate hw"); | ||
1279 | ret = PTR_ERR(hw); | ||
1280 | goto out; | ||
1281 | } | ||
1282 | |||
1283 | wl = hw->priv; | ||
1284 | priv = wl->priv; | ||
1285 | wl->ops = &wl18xx_ops; | ||
1286 | wl->ptable = wl18xx_ptable; | ||
1287 | wl->rtable = wl18xx_rtable; | ||
1288 | wl->num_tx_desc = 32; | ||
1289 | wl->num_rx_desc = 16; | ||
1290 | wl->band_rate_to_idx = wl18xx_band_rate_to_idx; | ||
1291 | wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; | ||
1292 | wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; | ||
1293 | wl->fw_status_priv_len = sizeof(struct wl18xx_fw_status_priv); | ||
1294 | wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); | ||
1295 | wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); | ||
1296 | |||
1297 | if (!strcmp(ht_mode_param, "wide")) { | ||
1298 | memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], | ||
1299 | &wl18xx_siso40_ht_cap, | ||
1300 | sizeof(wl18xx_siso40_ht_cap)); | ||
1301 | memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], | ||
1302 | &wl18xx_siso40_ht_cap, | ||
1303 | sizeof(wl18xx_siso40_ht_cap)); | ||
1304 | } else if (!strcmp(ht_mode_param, "mimo")) { | ||
1305 | memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], | ||
1306 | &wl18xx_mimo_ht_cap_2ghz, | ||
1307 | sizeof(wl18xx_mimo_ht_cap_2ghz)); | ||
1308 | memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], | ||
1309 | &wl18xx_mimo_ht_cap_5ghz, | ||
1310 | sizeof(wl18xx_mimo_ht_cap_5ghz)); | ||
1311 | } else if (!strcmp(ht_mode_param, "siso20")) { | ||
1312 | memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], | ||
1313 | &wl18xx_siso20_ht_cap, | ||
1314 | sizeof(wl18xx_siso20_ht_cap)); | ||
1315 | memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], | ||
1316 | &wl18xx_siso20_ht_cap, | ||
1317 | sizeof(wl18xx_siso20_ht_cap)); | ||
1318 | } else { | ||
1319 | wl1271_error("invalid ht_mode '%s'", ht_mode_param); | ||
1320 | ret = -EINVAL; | ||
1321 | goto out_free; | ||
1322 | } | ||
1323 | |||
1324 | ret = wl18xx_conf_init(wl, &pdev->dev); | ||
1325 | if (ret < 0) | ||
1326 | goto out_free; | ||
1327 | |||
1328 | if (!strcmp(board_type_param, "fpga")) { | ||
1329 | priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX; | ||
1330 | } else if (!strcmp(board_type_param, "hdk")) { | ||
1331 | priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX; | ||
1332 | /* HACK! Just for now we hardcode HDK to 0x06 */ | ||
1333 | priv->conf.phy.low_band_component_type = 0x06; | ||
1334 | } else if (!strcmp(board_type_param, "dvp")) { | ||
1335 | priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX; | ||
1336 | } else if (!strcmp(board_type_param, "evb")) { | ||
1337 | priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX; | ||
1338 | } else if (!strcmp(board_type_param, "com8")) { | ||
1339 | priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX; | ||
1340 | /* HACK! Just for now we hardcode COM8 to 0x06 */ | ||
1341 | priv->conf.phy.low_band_component_type = 0x06; | ||
1342 | } else { | ||
1343 | wl1271_error("invalid board type '%s'", board_type_param); | ||
1344 | ret = -EINVAL; | ||
1345 | goto out_free; | ||
1346 | } | ||
1347 | |||
1348 | /* If the module param is set, update it in conf */ | ||
1349 | if (low_band_component_param != -1) | ||
1350 | priv->conf.phy.low_band_component = low_band_component_param; | ||
1351 | if (low_band_component_type_param != -1) | ||
1352 | priv->conf.phy.low_band_component_type = | ||
1353 | low_band_component_type_param; | ||
1354 | if (high_band_component_param != -1) | ||
1355 | priv->conf.phy.high_band_component = high_band_component_param; | ||
1356 | if (high_band_component_type_param != -1) | ||
1357 | priv->conf.phy.high_band_component_type = | ||
1358 | high_band_component_type_param; | ||
1359 | if (pwr_limit_reference_11_abg_param != -1) | ||
1360 | priv->conf.phy.pwr_limit_reference_11_abg = | ||
1361 | pwr_limit_reference_11_abg_param; | ||
1362 | if (n_antennas_2_param != -1) | ||
1363 | priv->conf.phy.number_of_assembled_ant2_4 = n_antennas_2_param; | ||
1364 | if (n_antennas_5_param != -1) | ||
1365 | priv->conf.phy.number_of_assembled_ant5 = n_antennas_5_param; | ||
1366 | if (dc2dc_param != -1) | ||
1367 | priv->conf.phy.external_pa_dc2dc = dc2dc_param; | ||
1368 | |||
1369 | if (!checksum_param) { | ||
1370 | wl18xx_ops.set_rx_csum = NULL; | ||
1371 | wl18xx_ops.init_vif = NULL; | ||
1372 | } | ||
1373 | |||
1374 | wl->enable_11a = enable_11a_param; | ||
1375 | |||
1376 | return wlcore_probe(wl, pdev); | ||
1377 | |||
1378 | out_free: | ||
1379 | wlcore_free_hw(wl); | ||
1380 | out: | ||
1381 | return ret; | ||
1382 | } | ||
1383 | |||
1384 | static const struct platform_device_id wl18xx_id_table[] __devinitconst = { | ||
1385 | { "wl18xx", 0 }, | ||
1386 | { } /* Terminating Entry */ | ||
1387 | }; | ||
1388 | MODULE_DEVICE_TABLE(platform, wl18xx_id_table); | ||
1389 | |||
1390 | static struct platform_driver wl18xx_driver = { | ||
1391 | .probe = wl18xx_probe, | ||
1392 | .remove = __devexit_p(wlcore_remove), | ||
1393 | .id_table = wl18xx_id_table, | ||
1394 | .driver = { | ||
1395 | .name = "wl18xx_driver", | ||
1396 | .owner = THIS_MODULE, | ||
1397 | } | ||
1398 | }; | ||
1399 | |||
1400 | static int __init wl18xx_init(void) | ||
1401 | { | ||
1402 | return platform_driver_register(&wl18xx_driver); | ||
1403 | } | ||
1404 | module_init(wl18xx_init); | ||
1405 | |||
1406 | static void __exit wl18xx_exit(void) | ||
1407 | { | ||
1408 | platform_driver_unregister(&wl18xx_driver); | ||
1409 | } | ||
1410 | module_exit(wl18xx_exit); | ||
1411 | |||
1412 | module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); | ||
1413 | MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20"); | ||
1414 | |||
1415 | module_param_named(board_type, board_type_param, charp, S_IRUSR); | ||
1416 | MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " | ||
1417 | "dvp"); | ||
1418 | |||
1419 | module_param_named(checksum, checksum_param, bool, S_IRUSR); | ||
1420 | MODULE_PARM_DESC(checksum, "Enable TCP checksum: boolean (defaults to false)"); | ||
1421 | |||
1422 | module_param_named(enable_11a, enable_11a_param, bool, S_IRUSR); | ||
1423 | MODULE_PARM_DESC(enable_11a, "Enable 11a (5GHz): boolean (defaults to true)"); | ||
1424 | |||
1425 | module_param_named(dc2dc, dc2dc_param, int, S_IRUSR); | ||
1426 | MODULE_PARM_DESC(dc2dc, "External DC2DC: u8 (defaults to 0)"); | ||
1427 | |||
1428 | module_param_named(n_antennas_2, n_antennas_2_param, int, S_IRUSR); | ||
1429 | MODULE_PARM_DESC(n_antennas_2, | ||
1430 | "Number of installed 2.4GHz antennas: 1 (default) or 2"); | ||
1431 | |||
1432 | module_param_named(n_antennas_5, n_antennas_5_param, int, S_IRUSR); | ||
1433 | MODULE_PARM_DESC(n_antennas_5, | ||
1434 | "Number of installed 5GHz antennas: 1 (default) or 2"); | ||
1435 | |||
1436 | module_param_named(low_band_component, low_band_component_param, int, | ||
1437 | S_IRUSR); | ||
1438 | MODULE_PARM_DESC(low_band_component, "Low band component: u8 " | ||
1439 | "(default is 0x01)"); | ||
1440 | |||
1441 | module_param_named(low_band_component_type, low_band_component_type_param, | ||
1442 | int, S_IRUSR); | ||
1443 | MODULE_PARM_DESC(low_band_component_type, "Low band component type: u8 " | ||
1444 | "(default is 0x05 or 0x06 depending on the board_type)"); | ||
1445 | |||
1446 | module_param_named(high_band_component, high_band_component_param, int, | ||
1447 | S_IRUSR); | ||
1448 | MODULE_PARM_DESC(high_band_component, "High band component: u8, " | ||
1449 | "(default is 0x01)"); | ||
1450 | |||
1451 | module_param_named(high_band_component_type, high_band_component_type_param, | ||
1452 | int, S_IRUSR); | ||
1453 | MODULE_PARM_DESC(high_band_component_type, "High band component type: u8 " | ||
1454 | "(default is 0x09)"); | ||
1455 | |||
1456 | module_param_named(pwr_limit_reference_11_abg, | ||
1457 | pwr_limit_reference_11_abg_param, int, S_IRUSR); | ||
1458 | MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " | ||
1459 | "(default is 0xc8)"); | ||
1460 | |||
1461 | MODULE_LICENSE("GPL v2"); | ||
1462 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | ||
1463 | MODULE_FIRMWARE(WL18XX_FW_NAME); | ||
diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h new file mode 100644 index 000000000000..937b71d8783f --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/reg.h | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * This file is part of wlcore | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __REG_H__ | ||
23 | #define __REG_H__ | ||
24 | |||
25 | #define WL18XX_REGISTERS_BASE 0x00800000 | ||
26 | #define WL18XX_CODE_BASE 0x00000000 | ||
27 | #define WL18XX_DATA_BASE 0x00400000 | ||
28 | #define WL18XX_DOUBLE_BUFFER_BASE 0x00600000 | ||
29 | #define WL18XX_MCU_KEY_SEARCH_BASE 0x00700000 | ||
30 | #define WL18XX_PHY_BASE 0x00900000 | ||
31 | #define WL18XX_TOP_OCP_BASE 0x00A00000 | ||
32 | #define WL18XX_PACKET_RAM_BASE 0x00B00000 | ||
33 | #define WL18XX_HOST_BASE 0x00C00000 | ||
34 | |||
35 | #define WL18XX_REGISTERS_DOWN_SIZE 0x0000B000 | ||
36 | |||
37 | #define WL18XX_REG_BOOT_PART_START 0x00802000 | ||
38 | #define WL18XX_REG_BOOT_PART_SIZE 0x00014578 | ||
39 | |||
40 | #define WL18XX_PHY_INIT_MEM_ADDR 0x80926000 | ||
41 | |||
42 | #define WL18XX_SDIO_WSPI_BASE (WL18XX_REGISTERS_BASE) | ||
43 | #define WL18XX_REG_CONFIG_BASE (WL18XX_REGISTERS_BASE + 0x02000) | ||
44 | #define WL18XX_WGCM_REGS_BASE (WL18XX_REGISTERS_BASE + 0x03000) | ||
45 | #define WL18XX_ENC_BASE (WL18XX_REGISTERS_BASE + 0x04000) | ||
46 | #define WL18XX_INTERRUPT_BASE (WL18XX_REGISTERS_BASE + 0x05000) | ||
47 | #define WL18XX_UART_BASE (WL18XX_REGISTERS_BASE + 0x06000) | ||
48 | #define WL18XX_WELP_BASE (WL18XX_REGISTERS_BASE + 0x07000) | ||
49 | #define WL18XX_TCP_CKSM_BASE (WL18XX_REGISTERS_BASE + 0x08000) | ||
50 | #define WL18XX_FIFO_BASE (WL18XX_REGISTERS_BASE + 0x09000) | ||
51 | #define WL18XX_OCP_BRIDGE_BASE (WL18XX_REGISTERS_BASE + 0x0A000) | ||
52 | #define WL18XX_PMAC_RX_BASE (WL18XX_REGISTERS_BASE + 0x14800) | ||
53 | #define WL18XX_PMAC_ACM_BASE (WL18XX_REGISTERS_BASE + 0x14C00) | ||
54 | #define WL18XX_PMAC_TX_BASE (WL18XX_REGISTERS_BASE + 0x15000) | ||
55 | #define WL18XX_PMAC_CSR_BASE (WL18XX_REGISTERS_BASE + 0x15400) | ||
56 | |||
57 | #define WL18XX_REG_ECPU_CONTROL (WL18XX_REGISTERS_BASE + 0x02004) | ||
58 | #define WL18XX_REG_INTERRUPT_NO_CLEAR (WL18XX_REGISTERS_BASE + 0x050E8) | ||
59 | #define WL18XX_REG_INTERRUPT_ACK (WL18XX_REGISTERS_BASE + 0x050F0) | ||
60 | #define WL18XX_REG_INTERRUPT_TRIG (WL18XX_REGISTERS_BASE + 0x5074) | ||
61 | #define WL18XX_REG_INTERRUPT_TRIG_H (WL18XX_REGISTERS_BASE + 0x5078) | ||
62 | #define WL18XX_REG_INTERRUPT_MASK (WL18XX_REGISTERS_BASE + 0x0050DC) | ||
63 | |||
64 | #define WL18XX_REG_CHIP_ID_B (WL18XX_REGISTERS_BASE + 0x01542C) | ||
65 | |||
66 | #define WL18XX_SLV_MEM_DATA (WL18XX_HOST_BASE + 0x0018) | ||
67 | #define WL18XX_SLV_REG_DATA (WL18XX_HOST_BASE + 0x0008) | ||
68 | |||
69 | /* Scratch Pad registers*/ | ||
70 | #define WL18XX_SCR_PAD0 (WL18XX_REGISTERS_BASE + 0x0154EC) | ||
71 | #define WL18XX_SCR_PAD1 (WL18XX_REGISTERS_BASE + 0x0154F0) | ||
72 | #define WL18XX_SCR_PAD2 (WL18XX_REGISTERS_BASE + 0x0154F4) | ||
73 | #define WL18XX_SCR_PAD3 (WL18XX_REGISTERS_BASE + 0x0154F8) | ||
74 | #define WL18XX_SCR_PAD4 (WL18XX_REGISTERS_BASE + 0x0154FC) | ||
75 | #define WL18XX_SCR_PAD4_SET (WL18XX_REGISTERS_BASE + 0x015504) | ||
76 | #define WL18XX_SCR_PAD4_CLR (WL18XX_REGISTERS_BASE + 0x015500) | ||
77 | #define WL18XX_SCR_PAD5 (WL18XX_REGISTERS_BASE + 0x015508) | ||
78 | #define WL18XX_SCR_PAD5_SET (WL18XX_REGISTERS_BASE + 0x015510) | ||
79 | #define WL18XX_SCR_PAD5_CLR (WL18XX_REGISTERS_BASE + 0x01550C) | ||
80 | #define WL18XX_SCR_PAD6 (WL18XX_REGISTERS_BASE + 0x015514) | ||
81 | #define WL18XX_SCR_PAD7 (WL18XX_REGISTERS_BASE + 0x015518) | ||
82 | #define WL18XX_SCR_PAD8 (WL18XX_REGISTERS_BASE + 0x01551C) | ||
83 | #define WL18XX_SCR_PAD9 (WL18XX_REGISTERS_BASE + 0x015520) | ||
84 | |||
85 | /* Spare registers*/ | ||
86 | #define WL18XX_SPARE_A1 (WL18XX_REGISTERS_BASE + 0x002194) | ||
87 | #define WL18XX_SPARE_A2 (WL18XX_REGISTERS_BASE + 0x002198) | ||
88 | #define WL18XX_SPARE_A3 (WL18XX_REGISTERS_BASE + 0x00219C) | ||
89 | #define WL18XX_SPARE_A4 (WL18XX_REGISTERS_BASE + 0x0021A0) | ||
90 | #define WL18XX_SPARE_A5 (WL18XX_REGISTERS_BASE + 0x0021A4) | ||
91 | #define WL18XX_SPARE_A6 (WL18XX_REGISTERS_BASE + 0x0021A8) | ||
92 | #define WL18XX_SPARE_A7 (WL18XX_REGISTERS_BASE + 0x0021AC) | ||
93 | #define WL18XX_SPARE_A8 (WL18XX_REGISTERS_BASE + 0x0021B0) | ||
94 | #define WL18XX_SPARE_B1 (WL18XX_REGISTERS_BASE + 0x015524) | ||
95 | #define WL18XX_SPARE_B2 (WL18XX_REGISTERS_BASE + 0x015528) | ||
96 | #define WL18XX_SPARE_B3 (WL18XX_REGISTERS_BASE + 0x01552C) | ||
97 | #define WL18XX_SPARE_B4 (WL18XX_REGISTERS_BASE + 0x015530) | ||
98 | #define WL18XX_SPARE_B5 (WL18XX_REGISTERS_BASE + 0x015534) | ||
99 | #define WL18XX_SPARE_B6 (WL18XX_REGISTERS_BASE + 0x015538) | ||
100 | #define WL18XX_SPARE_B7 (WL18XX_REGISTERS_BASE + 0x01553C) | ||
101 | #define WL18XX_SPARE_B8 (WL18XX_REGISTERS_BASE + 0x015540) | ||
102 | |||
103 | #define WL18XX_REG_COMMAND_MAILBOX_PTR (WL18XX_SCR_PAD0) | ||
104 | #define WL18XX_REG_EVENT_MAILBOX_PTR (WL18XX_SCR_PAD1) | ||
105 | #define WL18XX_EEPROMLESS_IND (WL18XX_SCR_PAD4) | ||
106 | |||
107 | #define WL18XX_WELP_ARM_COMMAND (WL18XX_REGISTERS_BASE + 0x7100) | ||
108 | #define WL18XX_ENABLE (WL18XX_REGISTERS_BASE + 0x01543C) | ||
109 | |||
110 | /* PRCM registers */ | ||
111 | #define PLATFORM_DETECTION 0xA0E3E0 | ||
112 | #define OCS_EN 0xA02080 | ||
113 | #define PRIMARY_CLK_DETECT 0xA020A6 | ||
114 | #define PLLSH_WCS_PLL_N 0xA02362 | ||
115 | #define PLLSH_WCS_PLL_M 0xA02360 | ||
116 | #define PLLSH_WCS_PLL_Q_FACTOR_CFG_1 0xA02364 | ||
117 | #define PLLSH_WCS_PLL_Q_FACTOR_CFG_2 0xA02366 | ||
118 | #define PLLSH_WCS_PLL_P_FACTOR_CFG_1 0xA02368 | ||
119 | #define PLLSH_WCS_PLL_P_FACTOR_CFG_2 0xA0236A | ||
120 | #define PLLSH_WCS_PLL_SWALLOW_EN 0xA0236C | ||
121 | #define PLLSH_WL_PLL_EN 0xA02392 | ||
122 | |||
123 | #define PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK 0xFFFF | ||
124 | #define PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK 0x007F | ||
125 | #define PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK 0xFFFF | ||
126 | #define PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK 0x000F | ||
127 | |||
128 | #define PLLSH_WCS_PLL_SWALLOW_EN_VAL1 0x1 | ||
129 | #define PLLSH_WCS_PLL_SWALLOW_EN_VAL2 0x12 | ||
130 | |||
131 | #define WL18XX_REG_FUSE_DATA_1_3 0xA0260C | ||
132 | #define WL18XX_PG_VER_MASK 0x70 | ||
133 | #define WL18XX_PG_VER_OFFSET 4 | ||
134 | |||
135 | #define WL18XX_REG_FUSE_BD_ADDR_1 0xA02602 | ||
136 | #define WL18XX_REG_FUSE_BD_ADDR_2 0xA02606 | ||
137 | |||
138 | #define WL18XX_CMD_MBOX_ADDRESS 0xB007B4 | ||
139 | |||
140 | #define WL18XX_FW_STATUS_ADDR 0x50F8 | ||
141 | |||
142 | #define CHIP_ID_185x_PG10 (0x06030101) | ||
143 | #define CHIP_ID_185x_PG20 (0x06030111) | ||
144 | |||
145 | /* | ||
146 | * Host Command Interrupt. Setting this bit masks | ||
147 | * the interrupt that the host issues to inform | ||
148 | * the FW that it has sent a command | ||
149 | * to the Wlan hardware Command Mailbox. | ||
150 | */ | ||
151 | #define WL18XX_INTR_TRIG_CMD BIT(28) | ||
152 | |||
153 | /* | ||
154 | * Host Event Acknowlegde Interrupt. The host | ||
155 | * sets this bit to acknowledge that it received | ||
156 | * the unsolicited information from the event | ||
157 | * mailbox. | ||
158 | */ | ||
159 | #define WL18XX_INTR_TRIG_EVENT_ACK BIT(29) | ||
160 | |||
161 | /* | ||
162 | * To boot the firmware in PLT mode we need to write this value in | ||
163 | * SCR_PAD8 before starting. | ||
164 | */ | ||
165 | #define WL18XX_SCR_PAD8_PLT 0xBABABEBE | ||
166 | |||
167 | enum { | ||
168 | COMPONENT_NO_SWITCH = 0x0, | ||
169 | COMPONENT_2_WAY_SWITCH = 0x1, | ||
170 | COMPONENT_3_WAY_SWITCH = 0x2, | ||
171 | COMPONENT_MATCHING = 0x3, | ||
172 | }; | ||
173 | |||
174 | enum { | ||
175 | FEM_NONE = 0x0, | ||
176 | FEM_VENDOR_1 = 0x1, | ||
177 | FEM_VENDOR_2 = 0x2, | ||
178 | FEM_VENDOR_3 = 0x3, | ||
179 | }; | ||
180 | |||
181 | enum { | ||
182 | BOARD_TYPE_EVB_18XX = 0, | ||
183 | BOARD_TYPE_DVP_18XX = 1, | ||
184 | BOARD_TYPE_HDK_18XX = 2, | ||
185 | BOARD_TYPE_FPGA_18XX = 3, | ||
186 | BOARD_TYPE_COM8_18XX = 4, | ||
187 | |||
188 | NUM_BOARD_TYPES, | ||
189 | }; | ||
190 | |||
191 | #endif /* __REG_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/tx.c b/drivers/net/wireless/ti/wl18xx/tx.c new file mode 100644 index 000000000000..5b1fb10d9fd7 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/tx.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include "../wlcore/wlcore.h" | ||
23 | #include "../wlcore/cmd.h" | ||
24 | #include "../wlcore/debug.h" | ||
25 | #include "../wlcore/acx.h" | ||
26 | #include "../wlcore/tx.h" | ||
27 | |||
28 | #include "wl18xx.h" | ||
29 | #include "tx.h" | ||
30 | |||
31 | static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte) | ||
32 | { | ||
33 | struct ieee80211_tx_info *info; | ||
34 | struct sk_buff *skb; | ||
35 | int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK; | ||
36 | bool tx_success; | ||
37 | |||
38 | /* check for id legality */ | ||
39 | if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) { | ||
40 | wl1271_warning("illegal id in tx completion: %d", id); | ||
41 | return; | ||
42 | } | ||
43 | |||
44 | /* a zero bit indicates Tx success */ | ||
45 | tx_success = !(tx_stat_byte & BIT(WL18XX_TX_STATUS_STAT_BIT_IDX)); | ||
46 | |||
47 | |||
48 | skb = wl->tx_frames[id]; | ||
49 | info = IEEE80211_SKB_CB(skb); | ||
50 | |||
51 | if (wl12xx_is_dummy_packet(wl, skb)) { | ||
52 | wl1271_free_tx_id(wl, id); | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | /* update the TX status info */ | ||
57 | if (tx_success && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) | ||
58 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
59 | |||
60 | /* no real data about Tx completion */ | ||
61 | info->status.rates[0].idx = -1; | ||
62 | info->status.rates[0].count = 0; | ||
63 | info->status.rates[0].flags = 0; | ||
64 | info->status.ack_signal = -1; | ||
65 | |||
66 | if (!tx_success) | ||
67 | wl->stats.retry_count++; | ||
68 | |||
69 | /* | ||
70 | * TODO: update sequence number for encryption? seems to be | ||
71 | * unsupported for now. needed for recovery with encryption. | ||
72 | */ | ||
73 | |||
74 | /* remove private header from packet */ | ||
75 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | ||
76 | |||
77 | /* remove TKIP header space if present */ | ||
78 | if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && | ||
79 | info->control.hw_key && | ||
80 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
81 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
82 | memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen); | ||
83 | skb_pull(skb, WL1271_EXTRA_SPACE_TKIP); | ||
84 | } | ||
85 | |||
86 | wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p success %d", | ||
87 | id, skb, tx_success); | ||
88 | |||
89 | /* return the packet to the stack */ | ||
90 | skb_queue_tail(&wl->deferred_tx_queue, skb); | ||
91 | queue_work(wl->freezable_wq, &wl->netstack_work); | ||
92 | wl1271_free_tx_id(wl, id); | ||
93 | } | ||
94 | |||
95 | void wl18xx_tx_immediate_complete(struct wl1271 *wl) | ||
96 | { | ||
97 | struct wl18xx_fw_status_priv *status_priv = | ||
98 | (struct wl18xx_fw_status_priv *)wl->fw_status_2->priv; | ||
99 | struct wl18xx_priv *priv = wl->priv; | ||
100 | u8 i; | ||
101 | |||
102 | /* nothing to do here */ | ||
103 | if (priv->last_fw_rls_idx == status_priv->fw_release_idx) | ||
104 | return; | ||
105 | |||
106 | /* freed Tx descriptors */ | ||
107 | wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d", | ||
108 | priv->last_fw_rls_idx, status_priv->fw_release_idx); | ||
109 | |||
110 | if (status_priv->fw_release_idx >= WL18XX_FW_MAX_TX_STATUS_DESC) { | ||
111 | wl1271_error("invalid desc release index %d", | ||
112 | status_priv->fw_release_idx); | ||
113 | WARN_ON(1); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | for (i = priv->last_fw_rls_idx; | ||
118 | i != status_priv->fw_release_idx; | ||
119 | i = (i + 1) % WL18XX_FW_MAX_TX_STATUS_DESC) { | ||
120 | wl18xx_tx_complete_packet(wl, | ||
121 | status_priv->released_tx_desc[i]); | ||
122 | |||
123 | wl->tx_results_count++; | ||
124 | } | ||
125 | |||
126 | priv->last_fw_rls_idx = status_priv->fw_release_idx; | ||
127 | } | ||
diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h new file mode 100644 index 000000000000..ccddc548e44a --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/tx.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_TX_H__ | ||
23 | #define __WL18XX_TX_H__ | ||
24 | |||
25 | #include "../wlcore/wlcore.h" | ||
26 | |||
27 | #define WL18XX_TX_HW_BLOCK_SPARE 1 | ||
28 | /* for special cases - namely, TKIP and GEM */ | ||
29 | #define WL18XX_TX_HW_EXTRA_BLOCK_SPARE 2 | ||
30 | #define WL18XX_TX_HW_BLOCK_SIZE 268 | ||
31 | |||
32 | #define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F | ||
33 | #define WL18XX_TX_STATUS_STAT_BIT_IDX 7 | ||
34 | |||
35 | /* Indicates this TX HW frame is not padded to SDIO block size */ | ||
36 | #define WL18XX_TX_CTRL_NOT_PADDED BIT(7) | ||
37 | |||
38 | /* | ||
39 | * The FW uses a special bit to indicate a wide channel should be used in | ||
40 | * the rate policy. | ||
41 | */ | ||
42 | #define CONF_TX_RATE_USE_WIDE_CHAN BIT(31) | ||
43 | |||
44 | void wl18xx_tx_immediate_complete(struct wl1271 *wl); | ||
45 | |||
46 | #endif /* __WL12XX_TX_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h new file mode 100644 index 000000000000..bc67a4750615 --- /dev/null +++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * This file is part of wl18xx | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __WL18XX_PRIV_H__ | ||
23 | #define __WL18XX_PRIV_H__ | ||
24 | |||
25 | #include "conf.h" | ||
26 | |||
27 | #define WL18XX_CMD_MAX_SIZE 740 | ||
28 | |||
29 | struct wl18xx_priv { | ||
30 | /* buffer for sending commands to FW */ | ||
31 | u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; | ||
32 | |||
33 | struct wl18xx_priv_conf conf; | ||
34 | |||
35 | /* Index of last released Tx desc in FW */ | ||
36 | u8 last_fw_rls_idx; | ||
37 | |||
38 | /* number of VIFs requiring extra spare mem-blocks */ | ||
39 | int extra_spare_vif_count; | ||
40 | }; | ||
41 | |||
42 | #define WL18XX_FW_MAX_TX_STATUS_DESC 33 | ||
43 | |||
44 | struct wl18xx_fw_status_priv { | ||
45 | /* | ||
46 | * Index in released_tx_desc for first byte that holds | ||
47 | * released tx host desc | ||
48 | */ | ||
49 | u8 fw_release_idx; | ||
50 | |||
51 | /* | ||
52 | * Array of host Tx descriptors, where fw_release_idx | ||
53 | * indicated the first released idx. | ||
54 | */ | ||
55 | u8 released_tx_desc[WL18XX_FW_MAX_TX_STATUS_DESC]; | ||
56 | |||
57 | u8 padding[2]; | ||
58 | }; | ||
59 | |||
60 | #define WL18XX_PHY_VERSION_MAX_LEN 20 | ||
61 | |||
62 | struct wl18xx_static_data_priv { | ||
63 | char phy_version[WL18XX_PHY_VERSION_MAX_LEN]; | ||
64 | }; | ||
65 | |||
66 | struct wl18xx_clk_cfg { | ||
67 | u32 n; | ||
68 | u32 m; | ||
69 | u32 p; | ||
70 | u32 q; | ||
71 | bool swallow; | ||
72 | }; | ||
73 | |||
74 | enum { | ||
75 | CLOCK_CONFIG_16_2_M = 1, | ||
76 | CLOCK_CONFIG_16_368_M, | ||
77 | CLOCK_CONFIG_16_8_M, | ||
78 | CLOCK_CONFIG_19_2_M, | ||
79 | CLOCK_CONFIG_26_M, | ||
80 | CLOCK_CONFIG_32_736_M, | ||
81 | CLOCK_CONFIG_33_6_M, | ||
82 | CLOCK_CONFIG_38_468_M, | ||
83 | CLOCK_CONFIG_52_M, | ||
84 | |||
85 | NUM_CLOCK_CONFIGS, | ||
86 | }; | ||
87 | |||
88 | #endif /* __WL18XX_PRIV_H__ */ | ||
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index f3d6fa508269..b9ec42c83757 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c | |||
@@ -86,6 +86,7 @@ out: | |||
86 | kfree(auth); | 86 | kfree(auth); |
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
89 | EXPORT_SYMBOL_GPL(wl1271_acx_sleep_auth); | ||
89 | 90 | ||
90 | int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 91 | int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
91 | int power) | 92 | int power) |
@@ -708,14 +709,14 @@ out: | |||
708 | return ret; | 709 | return ret; |
709 | } | 710 | } |
710 | 711 | ||
711 | int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats) | 712 | int wl1271_acx_statistics(struct wl1271 *wl, void *stats) |
712 | { | 713 | { |
713 | int ret; | 714 | int ret; |
714 | 715 | ||
715 | wl1271_debug(DEBUG_ACX, "acx statistics"); | 716 | wl1271_debug(DEBUG_ACX, "acx statistics"); |
716 | 717 | ||
717 | ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, | 718 | ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, |
718 | sizeof(*stats)); | 719 | wl->stats.fw_stats_len); |
719 | if (ret < 0) { | 720 | if (ret < 0) { |
720 | wl1271_warning("acx statistics failed: %d", ret); | 721 | wl1271_warning("acx statistics failed: %d", ret); |
721 | return -ENOMEM; | 722 | return -ENOMEM; |
@@ -997,6 +998,7 @@ out: | |||
997 | kfree(mem_conf); | 998 | kfree(mem_conf); |
998 | return ret; | 999 | return ret; |
999 | } | 1000 | } |
1001 | EXPORT_SYMBOL_GPL(wl12xx_acx_mem_cfg); | ||
1000 | 1002 | ||
1001 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | 1003 | int wl1271_acx_init_mem_config(struct wl1271 *wl) |
1002 | { | 1004 | { |
@@ -1027,6 +1029,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl) | |||
1027 | 1029 | ||
1028 | return 0; | 1030 | return 0; |
1029 | } | 1031 | } |
1032 | EXPORT_SYMBOL_GPL(wl1271_acx_init_mem_config); | ||
1030 | 1033 | ||
1031 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) | 1034 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) |
1032 | { | 1035 | { |
@@ -1150,6 +1153,7 @@ out: | |||
1150 | kfree(acx); | 1153 | kfree(acx); |
1151 | return ret; | 1154 | return ret; |
1152 | } | 1155 | } |
1156 | EXPORT_SYMBOL_GPL(wl1271_acx_pm_config); | ||
1153 | 1157 | ||
1154 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 1158 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
1155 | bool enable) | 1159 | bool enable) |
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h index e6a74869a5ff..c0181258b722 100644 --- a/drivers/net/wireless/ti/wlcore/acx.h +++ b/drivers/net/wireless/ti/wlcore/acx.h | |||
@@ -51,21 +51,18 @@ | |||
51 | #define WL1271_ACX_INTR_TRACE_A BIT(7) | 51 | #define WL1271_ACX_INTR_TRACE_A BIT(7) |
52 | /* Trace message on MBOX #B */ | 52 | /* Trace message on MBOX #B */ |
53 | #define WL1271_ACX_INTR_TRACE_B BIT(8) | 53 | #define WL1271_ACX_INTR_TRACE_B BIT(8) |
54 | /* SW FW Initiated interrupt Watchdog timer expiration */ | ||
55 | #define WL1271_ACX_SW_INTR_WATCHDOG BIT(9) | ||
54 | 56 | ||
55 | #define WL1271_ACX_INTR_ALL 0xFFFFFFFF | 57 | #define WL1271_ACX_INTR_ALL 0xFFFFFFFF |
56 | #define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ | 58 | |
57 | WL1271_ACX_INTR_INIT_COMPLETE | \ | 59 | /* all possible interrupts - only appropriate ones will be masked in */ |
58 | WL1271_ACX_INTR_EVENT_A | \ | 60 | #define WLCORE_ALL_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ |
59 | WL1271_ACX_INTR_EVENT_B | \ | 61 | WL1271_ACX_INTR_EVENT_A | \ |
60 | WL1271_ACX_INTR_CMD_COMPLETE | \ | 62 | WL1271_ACX_INTR_EVENT_B | \ |
61 | WL1271_ACX_INTR_HW_AVAILABLE | \ | 63 | WL1271_ACX_INTR_HW_AVAILABLE | \ |
62 | WL1271_ACX_INTR_DATA) | 64 | WL1271_ACX_INTR_DATA | \ |
63 | 65 | WL1271_ACX_SW_INTR_WATCHDOG) | |
64 | #define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ | ||
65 | WL1271_ACX_INTR_EVENT_A | \ | ||
66 | WL1271_ACX_INTR_EVENT_B | \ | ||
67 | WL1271_ACX_INTR_HW_AVAILABLE | \ | ||
68 | WL1271_ACX_INTR_DATA) | ||
69 | 66 | ||
70 | /* Target's information element */ | 67 | /* Target's information element */ |
71 | struct acx_header { | 68 | struct acx_header { |
@@ -417,228 +414,6 @@ struct acx_ctsprotect { | |||
417 | u8 padding[2]; | 414 | u8 padding[2]; |
418 | } __packed; | 415 | } __packed; |
419 | 416 | ||
420 | struct acx_tx_statistics { | ||
421 | __le32 internal_desc_overflow; | ||
422 | } __packed; | ||
423 | |||
424 | struct acx_rx_statistics { | ||
425 | __le32 out_of_mem; | ||
426 | __le32 hdr_overflow; | ||
427 | __le32 hw_stuck; | ||
428 | __le32 dropped; | ||
429 | __le32 fcs_err; | ||
430 | __le32 xfr_hint_trig; | ||
431 | __le32 path_reset; | ||
432 | __le32 reset_counter; | ||
433 | } __packed; | ||
434 | |||
435 | struct acx_dma_statistics { | ||
436 | __le32 rx_requested; | ||
437 | __le32 rx_errors; | ||
438 | __le32 tx_requested; | ||
439 | __le32 tx_errors; | ||
440 | } __packed; | ||
441 | |||
442 | struct acx_isr_statistics { | ||
443 | /* host command complete */ | ||
444 | __le32 cmd_cmplt; | ||
445 | |||
446 | /* fiqisr() */ | ||
447 | __le32 fiqs; | ||
448 | |||
449 | /* (INT_STS_ND & INT_TRIG_RX_HEADER) */ | ||
450 | __le32 rx_headers; | ||
451 | |||
452 | /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */ | ||
453 | __le32 rx_completes; | ||
454 | |||
455 | /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */ | ||
456 | __le32 rx_mem_overflow; | ||
457 | |||
458 | /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */ | ||
459 | __le32 rx_rdys; | ||
460 | |||
461 | /* irqisr() */ | ||
462 | __le32 irqs; | ||
463 | |||
464 | /* (INT_STS_ND & INT_TRIG_TX_PROC) */ | ||
465 | __le32 tx_procs; | ||
466 | |||
467 | /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */ | ||
468 | __le32 decrypt_done; | ||
469 | |||
470 | /* (INT_STS_ND & INT_TRIG_DMA0) */ | ||
471 | __le32 dma0_done; | ||
472 | |||
473 | /* (INT_STS_ND & INT_TRIG_DMA1) */ | ||
474 | __le32 dma1_done; | ||
475 | |||
476 | /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */ | ||
477 | __le32 tx_exch_complete; | ||
478 | |||
479 | /* (INT_STS_ND & INT_TRIG_COMMAND) */ | ||
480 | __le32 commands; | ||
481 | |||
482 | /* (INT_STS_ND & INT_TRIG_RX_PROC) */ | ||
483 | __le32 rx_procs; | ||
484 | |||
485 | /* (INT_STS_ND & INT_TRIG_PM_802) */ | ||
486 | __le32 hw_pm_mode_changes; | ||
487 | |||
488 | /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */ | ||
489 | __le32 host_acknowledges; | ||
490 | |||
491 | /* (INT_STS_ND & INT_TRIG_PM_PCI) */ | ||
492 | __le32 pci_pm; | ||
493 | |||
494 | /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */ | ||
495 | __le32 wakeups; | ||
496 | |||
497 | /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */ | ||
498 | __le32 low_rssi; | ||
499 | } __packed; | ||
500 | |||
501 | struct acx_wep_statistics { | ||
502 | /* WEP address keys configured */ | ||
503 | __le32 addr_key_count; | ||
504 | |||
505 | /* default keys configured */ | ||
506 | __le32 default_key_count; | ||
507 | |||
508 | __le32 reserved; | ||
509 | |||
510 | /* number of times that WEP key not found on lookup */ | ||
511 | __le32 key_not_found; | ||
512 | |||
513 | /* number of times that WEP key decryption failed */ | ||
514 | __le32 decrypt_fail; | ||
515 | |||
516 | /* WEP packets decrypted */ | ||
517 | __le32 packets; | ||
518 | |||
519 | /* WEP decrypt interrupts */ | ||
520 | __le32 interrupt; | ||
521 | } __packed; | ||
522 | |||
523 | #define ACX_MISSED_BEACONS_SPREAD 10 | ||
524 | |||
525 | struct acx_pwr_statistics { | ||
526 | /* the amount of enters into power save mode (both PD & ELP) */ | ||
527 | __le32 ps_enter; | ||
528 | |||
529 | /* the amount of enters into ELP mode */ | ||
530 | __le32 elp_enter; | ||
531 | |||
532 | /* the amount of missing beacon interrupts to the host */ | ||
533 | __le32 missing_bcns; | ||
534 | |||
535 | /* the amount of wake on host-access times */ | ||
536 | __le32 wake_on_host; | ||
537 | |||
538 | /* the amount of wake on timer-expire */ | ||
539 | __le32 wake_on_timer_exp; | ||
540 | |||
541 | /* the number of packets that were transmitted with PS bit set */ | ||
542 | __le32 tx_with_ps; | ||
543 | |||
544 | /* the number of packets that were transmitted with PS bit clear */ | ||
545 | __le32 tx_without_ps; | ||
546 | |||
547 | /* the number of received beacons */ | ||
548 | __le32 rcvd_beacons; | ||
549 | |||
550 | /* the number of entering into PowerOn (power save off) */ | ||
551 | __le32 power_save_off; | ||
552 | |||
553 | /* the number of entries into power save mode */ | ||
554 | __le16 enable_ps; | ||
555 | |||
556 | /* | ||
557 | * the number of exits from power save, not including failed PS | ||
558 | * transitions | ||
559 | */ | ||
560 | __le16 disable_ps; | ||
561 | |||
562 | /* | ||
563 | * the number of times the TSF counter was adjusted because | ||
564 | * of drift | ||
565 | */ | ||
566 | __le32 fix_tsf_ps; | ||
567 | |||
568 | /* Gives statistics about the spread continuous missed beacons. | ||
569 | * The 16 LSB are dedicated for the PS mode. | ||
570 | * The 16 MSB are dedicated for the PS mode. | ||
571 | * cont_miss_bcns_spread[0] - single missed beacon. | ||
572 | * cont_miss_bcns_spread[1] - two continuous missed beacons. | ||
573 | * cont_miss_bcns_spread[2] - three continuous missed beacons. | ||
574 | * ... | ||
575 | * cont_miss_bcns_spread[9] - ten and more continuous missed beacons. | ||
576 | */ | ||
577 | __le32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD]; | ||
578 | |||
579 | /* the number of beacons in awake mode */ | ||
580 | __le32 rcvd_awake_beacons; | ||
581 | } __packed; | ||
582 | |||
583 | struct acx_mic_statistics { | ||
584 | __le32 rx_pkts; | ||
585 | __le32 calc_failure; | ||
586 | } __packed; | ||
587 | |||
588 | struct acx_aes_statistics { | ||
589 | __le32 encrypt_fail; | ||
590 | __le32 decrypt_fail; | ||
591 | __le32 encrypt_packets; | ||
592 | __le32 decrypt_packets; | ||
593 | __le32 encrypt_interrupt; | ||
594 | __le32 decrypt_interrupt; | ||
595 | } __packed; | ||
596 | |||
597 | struct acx_event_statistics { | ||
598 | __le32 heart_beat; | ||
599 | __le32 calibration; | ||
600 | __le32 rx_mismatch; | ||
601 | __le32 rx_mem_empty; | ||
602 | __le32 rx_pool; | ||
603 | __le32 oom_late; | ||
604 | __le32 phy_transmit_error; | ||
605 | __le32 tx_stuck; | ||
606 | } __packed; | ||
607 | |||
608 | struct acx_ps_statistics { | ||
609 | __le32 pspoll_timeouts; | ||
610 | __le32 upsd_timeouts; | ||
611 | __le32 upsd_max_sptime; | ||
612 | __le32 upsd_max_apturn; | ||
613 | __le32 pspoll_max_apturn; | ||
614 | __le32 pspoll_utilization; | ||
615 | __le32 upsd_utilization; | ||
616 | } __packed; | ||
617 | |||
618 | struct acx_rxpipe_statistics { | ||
619 | __le32 rx_prep_beacon_drop; | ||
620 | __le32 descr_host_int_trig_rx_data; | ||
621 | __le32 beacon_buffer_thres_host_int_trig_rx_data; | ||
622 | __le32 missed_beacon_host_int_trig_rx_data; | ||
623 | __le32 tx_xfr_host_int_trig_rx_data; | ||
624 | } __packed; | ||
625 | |||
626 | struct acx_statistics { | ||
627 | struct acx_header header; | ||
628 | |||
629 | struct acx_tx_statistics tx; | ||
630 | struct acx_rx_statistics rx; | ||
631 | struct acx_dma_statistics dma; | ||
632 | struct acx_isr_statistics isr; | ||
633 | struct acx_wep_statistics wep; | ||
634 | struct acx_pwr_statistics pwr; | ||
635 | struct acx_aes_statistics aes; | ||
636 | struct acx_mic_statistics mic; | ||
637 | struct acx_event_statistics event; | ||
638 | struct acx_ps_statistics ps; | ||
639 | struct acx_rxpipe_statistics rxpipe; | ||
640 | } __packed; | ||
641 | |||
642 | struct acx_rate_class { | 417 | struct acx_rate_class { |
643 | __le32 enabled_rates; | 418 | __le32 enabled_rates; |
644 | u8 short_retry_limit; | 419 | u8 short_retry_limit; |
@@ -828,6 +603,8 @@ struct wl1271_acx_keep_alive_config { | |||
828 | #define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) | 603 | #define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) |
829 | #define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) | 604 | #define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) |
830 | #define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) | 605 | #define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) |
606 | #define HOST_IF_CFG_RX_PAD_TO_SDIO_BLK BIT(4) | ||
607 | #define HOST_IF_CFG_ADD_RX_ALIGNMENT BIT(6) | ||
831 | 608 | ||
832 | enum { | 609 | enum { |
833 | WL1271_ACX_TRIG_TYPE_LEVEL = 0, | 610 | WL1271_ACX_TRIG_TYPE_LEVEL = 0, |
@@ -946,7 +723,7 @@ struct wl1271_acx_ht_information { | |||
946 | u8 padding[2]; | 723 | u8 padding[2]; |
947 | } __packed; | 724 | } __packed; |
948 | 725 | ||
949 | #define RX_BA_MAX_SESSIONS 2 | 726 | #define RX_BA_MAX_SESSIONS 3 |
950 | 727 | ||
951 | struct wl1271_acx_ba_initiator_policy { | 728 | struct wl1271_acx_ba_initiator_policy { |
952 | struct acx_header header; | 729 | struct acx_header header; |
@@ -1243,6 +1020,7 @@ enum { | |||
1243 | ACX_CONFIG_HANGOVER = 0x0042, | 1020 | ACX_CONFIG_HANGOVER = 0x0042, |
1244 | ACX_FEATURE_CFG = 0x0043, | 1021 | ACX_FEATURE_CFG = 0x0043, |
1245 | ACX_PROTECTION_CFG = 0x0044, | 1022 | ACX_PROTECTION_CFG = 0x0044, |
1023 | ACX_CHECKSUM_CONFIG = 0x0045, | ||
1246 | }; | 1024 | }; |
1247 | 1025 | ||
1248 | 1026 | ||
@@ -1281,7 +1059,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
1281 | enum acx_preamble_type preamble); | 1059 | enum acx_preamble_type preamble); |
1282 | int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 1060 | int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
1283 | enum acx_ctsprotect_type ctsprotect); | 1061 | enum acx_ctsprotect_type ctsprotect); |
1284 | int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); | 1062 | int wl1271_acx_statistics(struct wl1271 *wl, void *stats); |
1285 | int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 1063 | int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
1286 | int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, | 1064 | int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, |
1287 | u8 idx); | 1065 | u8 idx); |
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c index 9b98230f84ce..0fda500c01c9 100644 --- a/drivers/net/wireless/ti/wlcore/boot.c +++ b/drivers/net/wireless/ti/wlcore/boot.c | |||
@@ -45,10 +45,17 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) | |||
45 | wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); | 45 | wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); |
46 | } | 46 | } |
47 | 47 | ||
48 | static int wlcore_parse_fw_ver(struct wl1271 *wl) | 48 | static int wlcore_boot_parse_fw_ver(struct wl1271 *wl, |
49 | struct wl1271_static_data *static_data) | ||
49 | { | 50 | { |
50 | int ret; | 51 | int ret; |
51 | 52 | ||
53 | strncpy(wl->chip.fw_ver_str, static_data->fw_version, | ||
54 | sizeof(wl->chip.fw_ver_str)); | ||
55 | |||
56 | /* make sure the string is NULL-terminated */ | ||
57 | wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0'; | ||
58 | |||
52 | ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u", | 59 | ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u", |
53 | &wl->chip.fw_ver[0], &wl->chip.fw_ver[1], | 60 | &wl->chip.fw_ver[0], &wl->chip.fw_ver[1], |
54 | &wl->chip.fw_ver[2], &wl->chip.fw_ver[3], | 61 | &wl->chip.fw_ver[2], &wl->chip.fw_ver[3], |
@@ -57,43 +64,43 @@ static int wlcore_parse_fw_ver(struct wl1271 *wl) | |||
57 | if (ret != 5) { | 64 | if (ret != 5) { |
58 | wl1271_warning("fw version incorrect value"); | 65 | wl1271_warning("fw version incorrect value"); |
59 | memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); | 66 | memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver)); |
60 | return -EINVAL; | 67 | ret = -EINVAL; |
68 | goto out; | ||
61 | } | 69 | } |
62 | 70 | ||
63 | ret = wlcore_identify_fw(wl); | 71 | ret = wlcore_identify_fw(wl); |
64 | if (ret < 0) | 72 | if (ret < 0) |
65 | return ret; | 73 | goto out; |
66 | 74 | out: | |
67 | return 0; | 75 | return ret; |
68 | } | 76 | } |
69 | 77 | ||
70 | static int wlcore_boot_fw_version(struct wl1271 *wl) | 78 | static int wlcore_boot_static_data(struct wl1271 *wl) |
71 | { | 79 | { |
72 | struct wl1271_static_data *static_data; | 80 | struct wl1271_static_data *static_data; |
81 | size_t len = sizeof(*static_data) + wl->static_data_priv_len; | ||
73 | int ret; | 82 | int ret; |
74 | 83 | ||
75 | static_data = kmalloc(sizeof(*static_data), GFP_KERNEL | GFP_DMA); | 84 | static_data = kmalloc(len, GFP_KERNEL); |
76 | if (!static_data) { | 85 | if (!static_data) { |
77 | wl1271_error("Couldn't allocate memory for static data!"); | 86 | ret = -ENOMEM; |
78 | return -ENOMEM; | 87 | goto out; |
79 | } | 88 | } |
80 | 89 | ||
81 | wl1271_read(wl, wl->cmd_box_addr, static_data, sizeof(*static_data), | 90 | wl1271_read(wl, wl->cmd_box_addr, static_data, len, false); |
82 | false); | ||
83 | |||
84 | strncpy(wl->chip.fw_ver_str, static_data->fw_version, | ||
85 | sizeof(wl->chip.fw_ver_str)); | ||
86 | |||
87 | kfree(static_data); | ||
88 | 91 | ||
89 | /* make sure the string is NULL-terminated */ | 92 | ret = wlcore_boot_parse_fw_ver(wl, static_data); |
90 | wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0'; | 93 | if (ret < 0) |
94 | goto out_free; | ||
91 | 95 | ||
92 | ret = wlcore_parse_fw_ver(wl); | 96 | ret = wlcore_handle_static_data(wl, static_data); |
93 | if (ret < 0) | 97 | if (ret < 0) |
94 | return ret; | 98 | goto out_free; |
95 | 99 | ||
96 | return 0; | 100 | out_free: |
101 | kfree(static_data); | ||
102 | out: | ||
103 | return ret; | ||
97 | } | 104 | } |
98 | 105 | ||
99 | static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, | 106 | static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, |
@@ -204,8 +211,10 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) | |||
204 | u32 dest_addr, val; | 211 | u32 dest_addr, val; |
205 | u8 *nvs_ptr, *nvs_aligned; | 212 | u8 *nvs_ptr, *nvs_aligned; |
206 | 213 | ||
207 | if (wl->nvs == NULL) | 214 | if (wl->nvs == NULL) { |
215 | wl1271_error("NVS file is needed during boot"); | ||
208 | return -ENODEV; | 216 | return -ENODEV; |
217 | } | ||
209 | 218 | ||
210 | if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) { | 219 | if (wl->quirks & WLCORE_QUIRK_LEGACY_NVS) { |
211 | struct wl1271_nvs_file *nvs = | 220 | struct wl1271_nvs_file *nvs = |
@@ -400,9 +409,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) | |||
400 | wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", | 409 | wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", |
401 | wl->mbox_ptr[0], wl->mbox_ptr[1]); | 410 | wl->mbox_ptr[0], wl->mbox_ptr[1]); |
402 | 411 | ||
403 | ret = wlcore_boot_fw_version(wl); | 412 | ret = wlcore_boot_static_data(wl); |
404 | if (ret < 0) { | 413 | if (ret < 0) { |
405 | wl1271_error("couldn't boot firmware"); | 414 | wl1271_error("error getting static data"); |
406 | return ret; | 415 | return ret; |
407 | } | 416 | } |
408 | 417 | ||
diff --git a/drivers/net/wireless/ti/wlcore/boot.h b/drivers/net/wireless/ti/wlcore/boot.h index 094981dd2227..a525225f990c 100644 --- a/drivers/net/wireless/ti/wlcore/boot.h +++ b/drivers/net/wireless/ti/wlcore/boot.h | |||
@@ -40,6 +40,7 @@ struct wl1271_static_data { | |||
40 | u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; | 40 | u8 fw_version[WL1271_FW_VERSION_MAX_LEN]; |
41 | u32 hw_version; | 41 | u32 hw_version; |
42 | u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; | 42 | u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS]; |
43 | u8 priv[0]; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | /* number of times we try to read the INIT interrupt */ | 46 | /* number of times we try to read the INIT interrupt */ |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 5b128a971449..885364ca4344 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "cmd.h" | 36 | #include "cmd.h" |
37 | #include "event.h" | 37 | #include "event.h" |
38 | #include "tx.h" | 38 | #include "tx.h" |
39 | #include "hw_ops.h" | ||
39 | 40 | ||
40 | #define WL1271_CMD_FAST_POLL_COUNT 50 | 41 | #define WL1271_CMD_FAST_POLL_COUNT 50 |
41 | 42 | ||
@@ -291,6 +292,23 @@ static int wl12xx_get_new_session_id(struct wl1271 *wl, | |||
291 | return wlvif->session_counter; | 292 | return wlvif->session_counter; |
292 | } | 293 | } |
293 | 294 | ||
295 | static u8 wlcore_get_native_channel_type(u8 nl_channel_type) | ||
296 | { | ||
297 | switch (nl_channel_type) { | ||
298 | case NL80211_CHAN_NO_HT: | ||
299 | return WLCORE_CHAN_NO_HT; | ||
300 | case NL80211_CHAN_HT20: | ||
301 | return WLCORE_CHAN_HT20; | ||
302 | case NL80211_CHAN_HT40MINUS: | ||
303 | return WLCORE_CHAN_HT40MINUS; | ||
304 | case NL80211_CHAN_HT40PLUS: | ||
305 | return WLCORE_CHAN_HT40PLUS; | ||
306 | default: | ||
307 | WARN_ON(1); | ||
308 | return WLCORE_CHAN_NO_HT; | ||
309 | } | ||
310 | } | ||
311 | |||
294 | static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, | 312 | static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, |
295 | struct wl12xx_vif *wlvif) | 313 | struct wl12xx_vif *wlvif) |
296 | { | 314 | { |
@@ -407,6 +425,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
407 | memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len); | 425 | memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len); |
408 | memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN); | 426 | memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN); |
409 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); | 427 | cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set); |
428 | cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); | ||
410 | 429 | ||
411 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { | 430 | if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) { |
412 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); | 431 | ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid); |
@@ -482,6 +501,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
482 | struct wl12xx_cmd_role_start *cmd; | 501 | struct wl12xx_cmd_role_start *cmd; |
483 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | 502 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); |
484 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 503 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
504 | u32 supported_rates; | ||
485 | int ret; | 505 | int ret; |
486 | 506 | ||
487 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); | 507 | wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id); |
@@ -519,6 +539,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
519 | /* FIXME: Change when adding DFS */ | 539 | /* FIXME: Change when adding DFS */ |
520 | cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ | 540 | cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ |
521 | cmd->channel = wlvif->channel; | 541 | cmd->channel = wlvif->channel; |
542 | cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type); | ||
522 | 543 | ||
523 | if (!bss_conf->hidden_ssid) { | 544 | if (!bss_conf->hidden_ssid) { |
524 | /* take the SSID from the beacon for backward compatibility */ | 545 | /* take the SSID from the beacon for backward compatibility */ |
@@ -531,7 +552,13 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
531 | memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); | 552 | memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len); |
532 | } | 553 | } |
533 | 554 | ||
534 | cmd->ap.local_rates = cpu_to_le32(0xffffffff); | 555 | supported_rates = CONF_TX_AP_ENABLED_RATES | CONF_TX_MCS_RATES | |
556 | wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); | ||
557 | |||
558 | wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x", | ||
559 | supported_rates); | ||
560 | |||
561 | cmd->ap.local_rates = cpu_to_le32(supported_rates); | ||
535 | 562 | ||
536 | switch (wlvif->band) { | 563 | switch (wlvif->band) { |
537 | case IEEE80211_BAND_2GHZ: | 564 | case IEEE80211_BAND_2GHZ: |
@@ -797,6 +824,7 @@ out: | |||
797 | kfree(cmd); | 824 | kfree(cmd); |
798 | return ret; | 825 | return ret; |
799 | } | 826 | } |
827 | EXPORT_SYMBOL_GPL(wl1271_cmd_data_path); | ||
800 | 828 | ||
801 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 829 | int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
802 | u8 ps_mode, u16 auto_ps_timeout) | 830 | u8 ps_mode, u16 auto_ps_timeout) |
@@ -1018,7 +1046,7 @@ out: | |||
1018 | 1046 | ||
1019 | int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) | 1047 | int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) |
1020 | { | 1048 | { |
1021 | int ret, extra; | 1049 | int ret, extra = 0; |
1022 | u16 fc; | 1050 | u16 fc; |
1023 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | 1051 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); |
1024 | struct sk_buff *skb; | 1052 | struct sk_buff *skb; |
@@ -1057,7 +1085,8 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
1057 | /* encryption space */ | 1085 | /* encryption space */ |
1058 | switch (wlvif->encryption_type) { | 1086 | switch (wlvif->encryption_type) { |
1059 | case KEY_TKIP: | 1087 | case KEY_TKIP: |
1060 | extra = WL1271_EXTRA_SPACE_TKIP; | 1088 | if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) |
1089 | extra = WL1271_EXTRA_SPACE_TKIP; | ||
1061 | break; | 1090 | break; |
1062 | case KEY_AES: | 1091 | case KEY_AES: |
1063 | extra = WL1271_EXTRA_SPACE_AES; | 1092 | extra = WL1271_EXTRA_SPACE_AES; |
@@ -1346,13 +1375,18 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
1346 | 1375 | ||
1347 | for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) | 1376 | for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++) |
1348 | if (sta->wme && (sta->uapsd_queues & BIT(i))) | 1377 | if (sta->wme && (sta->uapsd_queues & BIT(i))) |
1349 | cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER; | 1378 | cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = |
1379 | WL1271_PSD_UPSD_TRIGGER; | ||
1350 | else | 1380 | else |
1351 | cmd->psd_type[i] = WL1271_PSD_LEGACY; | 1381 | cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] = |
1382 | WL1271_PSD_LEGACY; | ||
1383 | |||
1352 | 1384 | ||
1353 | sta_rates = sta->supp_rates[wlvif->band]; | 1385 | sta_rates = sta->supp_rates[wlvif->band]; |
1354 | if (sta->ht_cap.ht_supported) | 1386 | if (sta->ht_cap.ht_supported) |
1355 | sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET; | 1387 | sta_rates |= |
1388 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | | ||
1389 | (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); | ||
1356 | 1390 | ||
1357 | cmd->supported_rates = | 1391 | cmd->supported_rates = |
1358 | cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, | 1392 | cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates, |
@@ -1573,19 +1607,25 @@ out: | |||
1573 | int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id) | 1607 | int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id) |
1574 | { | 1608 | { |
1575 | int ret = 0; | 1609 | int ret = 0; |
1610 | bool is_first_roc; | ||
1576 | 1611 | ||
1577 | if (WARN_ON(test_bit(role_id, wl->roc_map))) | 1612 | if (WARN_ON(test_bit(role_id, wl->roc_map))) |
1578 | return 0; | 1613 | return 0; |
1579 | 1614 | ||
1615 | is_first_roc = (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= | ||
1616 | WL12XX_MAX_ROLES); | ||
1617 | |||
1580 | ret = wl12xx_cmd_roc(wl, wlvif, role_id); | 1618 | ret = wl12xx_cmd_roc(wl, wlvif, role_id); |
1581 | if (ret < 0) | 1619 | if (ret < 0) |
1582 | goto out; | 1620 | goto out; |
1583 | 1621 | ||
1584 | ret = wl1271_cmd_wait_for_event(wl, | 1622 | if (is_first_roc) { |
1585 | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID); | 1623 | ret = wl1271_cmd_wait_for_event(wl, |
1586 | if (ret < 0) { | 1624 | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID); |
1587 | wl1271_error("cmd roc event completion error"); | 1625 | if (ret < 0) { |
1588 | goto out; | 1626 | wl1271_error("cmd roc event completion error"); |
1627 | goto out; | ||
1628 | } | ||
1589 | } | 1629 | } |
1590 | 1630 | ||
1591 | __set_bit(role_id, wl->roc_map); | 1631 | __set_bit(role_id, wl->roc_map); |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index a46ae07cb77e..85171f2bf68e 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h | |||
@@ -192,7 +192,7 @@ enum cmd_templ { | |||
192 | #define WL1271_COMMAND_TIMEOUT 2000 | 192 | #define WL1271_COMMAND_TIMEOUT 2000 |
193 | #define WL1271_CMD_TEMPL_DFLT_SIZE 252 | 193 | #define WL1271_CMD_TEMPL_DFLT_SIZE 252 |
194 | #define WL1271_CMD_TEMPL_MAX_SIZE 512 | 194 | #define WL1271_CMD_TEMPL_MAX_SIZE 512 |
195 | #define WL1271_EVENT_TIMEOUT 750 | 195 | #define WL1271_EVENT_TIMEOUT 1000 |
196 | 196 | ||
197 | struct wl1271_cmd_header { | 197 | struct wl1271_cmd_header { |
198 | __le16 id; | 198 | __le16 id; |
@@ -266,13 +266,22 @@ enum wlcore_band { | |||
266 | WLCORE_BAND_MAX_RADIO = 0x7F, | 266 | WLCORE_BAND_MAX_RADIO = 0x7F, |
267 | }; | 267 | }; |
268 | 268 | ||
269 | enum wlcore_channel_type { | ||
270 | WLCORE_CHAN_NO_HT, | ||
271 | WLCORE_CHAN_HT20, | ||
272 | WLCORE_CHAN_HT40MINUS, | ||
273 | WLCORE_CHAN_HT40PLUS | ||
274 | }; | ||
275 | |||
269 | struct wl12xx_cmd_role_start { | 276 | struct wl12xx_cmd_role_start { |
270 | struct wl1271_cmd_header header; | 277 | struct wl1271_cmd_header header; |
271 | 278 | ||
272 | u8 role_id; | 279 | u8 role_id; |
273 | u8 band; | 280 | u8 band; |
274 | u8 channel; | 281 | u8 channel; |
275 | u8 padding; | 282 | |
283 | /* enum wlcore_channel_type */ | ||
284 | u8 channel_type; | ||
276 | 285 | ||
277 | union { | 286 | union { |
278 | struct { | 287 | struct { |
diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index fef0db4213bc..03c635872335 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h | |||
@@ -45,7 +45,15 @@ enum { | |||
45 | CONF_HW_BIT_RATE_MCS_4 = BIT(17), | 45 | CONF_HW_BIT_RATE_MCS_4 = BIT(17), |
46 | CONF_HW_BIT_RATE_MCS_5 = BIT(18), | 46 | CONF_HW_BIT_RATE_MCS_5 = BIT(18), |
47 | CONF_HW_BIT_RATE_MCS_6 = BIT(19), | 47 | CONF_HW_BIT_RATE_MCS_6 = BIT(19), |
48 | CONF_HW_BIT_RATE_MCS_7 = BIT(20) | 48 | CONF_HW_BIT_RATE_MCS_7 = BIT(20), |
49 | CONF_HW_BIT_RATE_MCS_8 = BIT(21), | ||
50 | CONF_HW_BIT_RATE_MCS_9 = BIT(22), | ||
51 | CONF_HW_BIT_RATE_MCS_10 = BIT(23), | ||
52 | CONF_HW_BIT_RATE_MCS_11 = BIT(24), | ||
53 | CONF_HW_BIT_RATE_MCS_12 = BIT(25), | ||
54 | CONF_HW_BIT_RATE_MCS_13 = BIT(26), | ||
55 | CONF_HW_BIT_RATE_MCS_14 = BIT(27), | ||
56 | CONF_HW_BIT_RATE_MCS_15 = BIT(28), | ||
49 | }; | 57 | }; |
50 | 58 | ||
51 | enum { | 59 | enum { |
@@ -310,7 +318,7 @@ enum { | |||
310 | struct conf_sg_settings { | 318 | struct conf_sg_settings { |
311 | u32 params[CONF_SG_PARAMS_MAX]; | 319 | u32 params[CONF_SG_PARAMS_MAX]; |
312 | u8 state; | 320 | u8 state; |
313 | }; | 321 | } __packed; |
314 | 322 | ||
315 | enum conf_rx_queue_type { | 323 | enum conf_rx_queue_type { |
316 | CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ | 324 | CONF_RX_QUEUE_TYPE_LOW_PRIORITY, /* All except the high priority */ |
@@ -394,7 +402,7 @@ struct conf_rx_settings { | |||
394 | * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, | 402 | * Range: RX_QUEUE_TYPE_RX_LOW_PRIORITY, RX_QUEUE_TYPE_RX_HIGH_PRIORITY, |
395 | */ | 403 | */ |
396 | u8 queue_type; | 404 | u8 queue_type; |
397 | }; | 405 | } __packed; |
398 | 406 | ||
399 | #define CONF_TX_MAX_RATE_CLASSES 10 | 407 | #define CONF_TX_MAX_RATE_CLASSES 10 |
400 | 408 | ||
@@ -435,6 +443,12 @@ struct conf_rx_settings { | |||
435 | CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \ | 443 | CONF_HW_BIT_RATE_MCS_5 | CONF_HW_BIT_RATE_MCS_6 | \ |
436 | CONF_HW_BIT_RATE_MCS_7) | 444 | CONF_HW_BIT_RATE_MCS_7) |
437 | 445 | ||
446 | #define CONF_TX_MIMO_RATES (CONF_HW_BIT_RATE_MCS_8 | \ | ||
447 | CONF_HW_BIT_RATE_MCS_9 | CONF_HW_BIT_RATE_MCS_10 | \ | ||
448 | CONF_HW_BIT_RATE_MCS_11 | CONF_HW_BIT_RATE_MCS_12 | \ | ||
449 | CONF_HW_BIT_RATE_MCS_13 | CONF_HW_BIT_RATE_MCS_14 | \ | ||
450 | CONF_HW_BIT_RATE_MCS_15) | ||
451 | |||
438 | /* | 452 | /* |
439 | * Default rates for management traffic when operating in AP mode. This | 453 | * Default rates for management traffic when operating in AP mode. This |
440 | * should be configured according to the basic rate set of the AP | 454 | * should be configured according to the basic rate set of the AP |
@@ -487,7 +501,7 @@ struct conf_tx_rate_class { | |||
487 | * the policy (0 - long preamble, 1 - short preamble. | 501 | * the policy (0 - long preamble, 1 - short preamble. |
488 | */ | 502 | */ |
489 | u8 aflags; | 503 | u8 aflags; |
490 | }; | 504 | } __packed; |
491 | 505 | ||
492 | #define CONF_TX_MAX_AC_COUNT 4 | 506 | #define CONF_TX_MAX_AC_COUNT 4 |
493 | 507 | ||
@@ -504,7 +518,7 @@ enum conf_tx_ac { | |||
504 | CONF_TX_AC_VI = 2, /* video */ | 518 | CONF_TX_AC_VI = 2, /* video */ |
505 | CONF_TX_AC_VO = 3, /* voice */ | 519 | CONF_TX_AC_VO = 3, /* voice */ |
506 | CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */ | 520 | CONF_TX_AC_CTS2SELF = 4, /* fictitious AC, follows AC_VO */ |
507 | CONF_TX_AC_ANY_TID = 0x1f | 521 | CONF_TX_AC_ANY_TID = 0xff |
508 | }; | 522 | }; |
509 | 523 | ||
510 | struct conf_tx_ac_category { | 524 | struct conf_tx_ac_category { |
@@ -544,7 +558,7 @@ struct conf_tx_ac_category { | |||
544 | * Range: u16 | 558 | * Range: u16 |
545 | */ | 559 | */ |
546 | u16 tx_op_limit; | 560 | u16 tx_op_limit; |
547 | }; | 561 | } __packed; |
548 | 562 | ||
549 | #define CONF_TX_MAX_TID_COUNT 8 | 563 | #define CONF_TX_MAX_TID_COUNT 8 |
550 | 564 | ||
@@ -578,7 +592,7 @@ struct conf_tx_tid { | |||
578 | u8 ps_scheme; | 592 | u8 ps_scheme; |
579 | u8 ack_policy; | 593 | u8 ack_policy; |
580 | u32 apsd_conf[2]; | 594 | u32 apsd_conf[2]; |
581 | }; | 595 | } __packed; |
582 | 596 | ||
583 | struct conf_tx_settings { | 597 | struct conf_tx_settings { |
584 | /* | 598 | /* |
@@ -664,7 +678,7 @@ struct conf_tx_settings { | |||
664 | 678 | ||
665 | /* Time in ms for Tx watchdog timer to expire */ | 679 | /* Time in ms for Tx watchdog timer to expire */ |
666 | u32 tx_watchdog_timeout; | 680 | u32 tx_watchdog_timeout; |
667 | }; | 681 | } __packed; |
668 | 682 | ||
669 | enum { | 683 | enum { |
670 | CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ | 684 | CONF_WAKE_UP_EVENT_BEACON = 0x01, /* Wake on every Beacon*/ |
@@ -711,7 +725,7 @@ struct conf_bcn_filt_rule { | |||
711 | * Version for the vendor specifie IE (221) | 725 | * Version for the vendor specifie IE (221) |
712 | */ | 726 | */ |
713 | u8 version[CONF_BCN_IE_VER_LEN]; | 727 | u8 version[CONF_BCN_IE_VER_LEN]; |
714 | }; | 728 | } __packed; |
715 | 729 | ||
716 | #define CONF_MAX_RSSI_SNR_TRIGGERS 8 | 730 | #define CONF_MAX_RSSI_SNR_TRIGGERS 8 |
717 | 731 | ||
@@ -762,7 +776,7 @@ struct conf_sig_weights { | |||
762 | * Range: u8 | 776 | * Range: u8 |
763 | */ | 777 | */ |
764 | u8 snr_pkt_avg_weight; | 778 | u8 snr_pkt_avg_weight; |
765 | }; | 779 | } __packed; |
766 | 780 | ||
767 | enum conf_bcn_filt_mode { | 781 | enum conf_bcn_filt_mode { |
768 | CONF_BCN_FILT_MODE_DISABLED = 0, | 782 | CONF_BCN_FILT_MODE_DISABLED = 0, |
@@ -810,7 +824,7 @@ struct conf_conn_settings { | |||
810 | * | 824 | * |
811 | * Range: CONF_BCN_FILT_MODE_* | 825 | * Range: CONF_BCN_FILT_MODE_* |
812 | */ | 826 | */ |
813 | enum conf_bcn_filt_mode bcn_filt_mode; | 827 | u8 bcn_filt_mode; |
814 | 828 | ||
815 | /* | 829 | /* |
816 | * Configure Beacon filter pass-thru rules. | 830 | * Configure Beacon filter pass-thru rules. |
@@ -937,7 +951,7 @@ struct conf_conn_settings { | |||
937 | * Range: u16 | 951 | * Range: u16 |
938 | */ | 952 | */ |
939 | u8 max_listen_interval; | 953 | u8 max_listen_interval; |
940 | }; | 954 | } __packed; |
941 | 955 | ||
942 | enum { | 956 | enum { |
943 | CONF_REF_CLK_19_2_E, | 957 | CONF_REF_CLK_19_2_E, |
@@ -965,6 +979,11 @@ struct conf_itrim_settings { | |||
965 | 979 | ||
966 | /* moderation timeout in microsecs from the last TX */ | 980 | /* moderation timeout in microsecs from the last TX */ |
967 | u32 timeout; | 981 | u32 timeout; |
982 | } __packed; | ||
983 | |||
984 | enum conf_fast_wakeup { | ||
985 | CONF_FAST_WAKEUP_ENABLE, | ||
986 | CONF_FAST_WAKEUP_DISABLE, | ||
968 | }; | 987 | }; |
969 | 988 | ||
970 | struct conf_pm_config_settings { | 989 | struct conf_pm_config_settings { |
@@ -978,10 +997,10 @@ struct conf_pm_config_settings { | |||
978 | /* | 997 | /* |
979 | * Host fast wakeup support | 998 | * Host fast wakeup support |
980 | * | 999 | * |
981 | * Range: true, false | 1000 | * Range: enum conf_fast_wakeup |
982 | */ | 1001 | */ |
983 | bool host_fast_wakeup_support; | 1002 | u8 host_fast_wakeup_support; |
984 | }; | 1003 | } __packed; |
985 | 1004 | ||
986 | struct conf_roam_trigger_settings { | 1005 | struct conf_roam_trigger_settings { |
987 | /* | 1006 | /* |
@@ -1018,7 +1037,7 @@ struct conf_roam_trigger_settings { | |||
1018 | * Range: 0 - 255 | 1037 | * Range: 0 - 255 |
1019 | */ | 1038 | */ |
1020 | u8 avg_weight_snr_data; | 1039 | u8 avg_weight_snr_data; |
1021 | }; | 1040 | } __packed; |
1022 | 1041 | ||
1023 | struct conf_scan_settings { | 1042 | struct conf_scan_settings { |
1024 | /* | 1043 | /* |
@@ -1064,7 +1083,7 @@ struct conf_scan_settings { | |||
1064 | * Range: u32 Microsecs | 1083 | * Range: u32 Microsecs |
1065 | */ | 1084 | */ |
1066 | u32 split_scan_timeout; | 1085 | u32 split_scan_timeout; |
1067 | }; | 1086 | } __packed; |
1068 | 1087 | ||
1069 | struct conf_sched_scan_settings { | 1088 | struct conf_sched_scan_settings { |
1070 | /* | 1089 | /* |
@@ -1102,7 +1121,7 @@ struct conf_sched_scan_settings { | |||
1102 | 1121 | ||
1103 | /* SNR threshold to be used for filtering */ | 1122 | /* SNR threshold to be used for filtering */ |
1104 | s8 snr_threshold; | 1123 | s8 snr_threshold; |
1105 | }; | 1124 | } __packed; |
1106 | 1125 | ||
1107 | struct conf_ht_setting { | 1126 | struct conf_ht_setting { |
1108 | u8 rx_ba_win_size; | 1127 | u8 rx_ba_win_size; |
@@ -1111,7 +1130,7 @@ struct conf_ht_setting { | |||
1111 | 1130 | ||
1112 | /* bitmap of enabled TIDs for TX BA sessions */ | 1131 | /* bitmap of enabled TIDs for TX BA sessions */ |
1113 | u8 tx_ba_tid_bitmap; | 1132 | u8 tx_ba_tid_bitmap; |
1114 | }; | 1133 | } __packed; |
1115 | 1134 | ||
1116 | struct conf_memory_settings { | 1135 | struct conf_memory_settings { |
1117 | /* Number of stations supported in IBSS mode */ | 1136 | /* Number of stations supported in IBSS mode */ |
@@ -1151,7 +1170,7 @@ struct conf_memory_settings { | |||
1151 | * Range: 0-120 | 1170 | * Range: 0-120 |
1152 | */ | 1171 | */ |
1153 | u8 tx_min; | 1172 | u8 tx_min; |
1154 | }; | 1173 | } __packed; |
1155 | 1174 | ||
1156 | struct conf_fm_coex { | 1175 | struct conf_fm_coex { |
1157 | u8 enable; | 1176 | u8 enable; |
@@ -1164,7 +1183,7 @@ struct conf_fm_coex { | |||
1164 | u16 ldo_stabilization_time; | 1183 | u16 ldo_stabilization_time; |
1165 | u8 fm_disturbed_band_margin; | 1184 | u8 fm_disturbed_band_margin; |
1166 | u8 swallow_clk_diff; | 1185 | u8 swallow_clk_diff; |
1167 | }; | 1186 | } __packed; |
1168 | 1187 | ||
1169 | struct conf_rx_streaming_settings { | 1188 | struct conf_rx_streaming_settings { |
1170 | /* | 1189 | /* |
@@ -1193,7 +1212,7 @@ struct conf_rx_streaming_settings { | |||
1193 | * enable rx streaming also when there is no coex activity | 1212 | * enable rx streaming also when there is no coex activity |
1194 | */ | 1213 | */ |
1195 | u8 always; | 1214 | u8 always; |
1196 | }; | 1215 | } __packed; |
1197 | 1216 | ||
1198 | struct conf_fwlog { | 1217 | struct conf_fwlog { |
1199 | /* Continuous or on-demand */ | 1218 | /* Continuous or on-demand */ |
@@ -1217,7 +1236,7 @@ struct conf_fwlog { | |||
1217 | 1236 | ||
1218 | /* Regulates the frequency of log messages */ | 1237 | /* Regulates the frequency of log messages */ |
1219 | u8 threshold; | 1238 | u8 threshold; |
1220 | }; | 1239 | } __packed; |
1221 | 1240 | ||
1222 | #define ACX_RATE_MGMT_NUM_OF_RATES 13 | 1241 | #define ACX_RATE_MGMT_NUM_OF_RATES 13 |
1223 | struct conf_rate_policy_settings { | 1242 | struct conf_rate_policy_settings { |
@@ -1236,7 +1255,7 @@ struct conf_rate_policy_settings { | |||
1236 | u8 rate_check_up; | 1255 | u8 rate_check_up; |
1237 | u8 rate_check_down; | 1256 | u8 rate_check_down; |
1238 | u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES]; | 1257 | u8 rate_retry_policy[ACX_RATE_MGMT_NUM_OF_RATES]; |
1239 | }; | 1258 | } __packed; |
1240 | 1259 | ||
1241 | struct conf_hangover_settings { | 1260 | struct conf_hangover_settings { |
1242 | u32 recover_time; | 1261 | u32 recover_time; |
@@ -1250,7 +1269,23 @@ struct conf_hangover_settings { | |||
1250 | u8 quiet_time; | 1269 | u8 quiet_time; |
1251 | u8 increase_time; | 1270 | u8 increase_time; |
1252 | u8 window_size; | 1271 | u8 window_size; |
1253 | }; | 1272 | } __packed; |
1273 | |||
1274 | /* | ||
1275 | * The conf version consists of 4 bytes. The two MSB are the wlcore | ||
1276 | * version, the two LSB are the lower driver's private conf | ||
1277 | * version. | ||
1278 | */ | ||
1279 | #define WLCORE_CONF_VERSION (0x0001 << 16) | ||
1280 | #define WLCORE_CONF_MASK 0xffff0000 | ||
1281 | #define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ | ||
1282 | sizeof(struct wlcore_conf)) | ||
1283 | |||
1284 | struct wlcore_conf_header { | ||
1285 | __le32 magic; | ||
1286 | __le32 version; | ||
1287 | __le32 checksum; | ||
1288 | } __packed; | ||
1254 | 1289 | ||
1255 | struct wlcore_conf { | 1290 | struct wlcore_conf { |
1256 | struct conf_sg_settings sg; | 1291 | struct conf_sg_settings sg; |
@@ -1269,6 +1304,12 @@ struct wlcore_conf { | |||
1269 | struct conf_fwlog fwlog; | 1304 | struct conf_fwlog fwlog; |
1270 | struct conf_rate_policy_settings rate; | 1305 | struct conf_rate_policy_settings rate; |
1271 | struct conf_hangover_settings hangover; | 1306 | struct conf_hangover_settings hangover; |
1272 | }; | 1307 | } __packed; |
1308 | |||
1309 | struct wlcore_conf_file { | ||
1310 | struct wlcore_conf_header header; | ||
1311 | struct wlcore_conf core; | ||
1312 | u8 priv[0]; | ||
1313 | } __packed; | ||
1273 | 1314 | ||
1274 | #endif | 1315 | #endif |
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index d5aea1ff5ad1..689a847005c9 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/skbuff.h> | 26 | #include <linux/skbuff.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/module.h> | ||
28 | 29 | ||
29 | #include "wlcore.h" | 30 | #include "wlcore.h" |
30 | #include "debug.h" | 31 | #include "debug.h" |
@@ -32,14 +33,14 @@ | |||
32 | #include "ps.h" | 33 | #include "ps.h" |
33 | #include "io.h" | 34 | #include "io.h" |
34 | #include "tx.h" | 35 | #include "tx.h" |
36 | #include "hw_ops.h" | ||
35 | 37 | ||
36 | /* ms */ | 38 | /* ms */ |
37 | #define WL1271_DEBUGFS_STATS_LIFETIME 1000 | 39 | #define WL1271_DEBUGFS_STATS_LIFETIME 1000 |
38 | 40 | ||
39 | /* debugfs macros idea from mac80211 */ | 41 | /* debugfs macros idea from mac80211 */ |
40 | #define DEBUGFS_FORMAT_BUFFER_SIZE 100 | 42 | int wl1271_format_buffer(char __user *userbuf, size_t count, |
41 | static int wl1271_format_buffer(char __user *userbuf, size_t count, | 43 | loff_t *ppos, char *fmt, ...) |
42 | loff_t *ppos, char *fmt, ...) | ||
43 | { | 44 | { |
44 | va_list args; | 45 | va_list args; |
45 | char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; | 46 | char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; |
@@ -51,59 +52,9 @@ static int wl1271_format_buffer(char __user *userbuf, size_t count, | |||
51 | 52 | ||
52 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 53 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
53 | } | 54 | } |
55 | EXPORT_SYMBOL_GPL(wl1271_format_buffer); | ||
54 | 56 | ||
55 | #define DEBUGFS_READONLY_FILE(name, fmt, value...) \ | 57 | void wl1271_debugfs_update_stats(struct wl1271 *wl) |
56 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ | ||
57 | size_t count, loff_t *ppos) \ | ||
58 | { \ | ||
59 | struct wl1271 *wl = file->private_data; \ | ||
60 | return wl1271_format_buffer(userbuf, count, ppos, \ | ||
61 | fmt "\n", ##value); \ | ||
62 | } \ | ||
63 | \ | ||
64 | static const struct file_operations name## _ops = { \ | ||
65 | .read = name## _read, \ | ||
66 | .open = simple_open, \ | ||
67 | .llseek = generic_file_llseek, \ | ||
68 | }; | ||
69 | |||
70 | #define DEBUGFS_ADD(name, parent) \ | ||
71 | entry = debugfs_create_file(#name, 0400, parent, \ | ||
72 | wl, &name## _ops); \ | ||
73 | if (!entry || IS_ERR(entry)) \ | ||
74 | goto err; \ | ||
75 | |||
76 | #define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ | ||
77 | do { \ | ||
78 | entry = debugfs_create_file(#name, 0400, parent, \ | ||
79 | wl, &prefix## _## name## _ops); \ | ||
80 | if (!entry || IS_ERR(entry)) \ | ||
81 | goto err; \ | ||
82 | } while (0); | ||
83 | |||
84 | #define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ | ||
85 | static ssize_t sub## _ ##name## _read(struct file *file, \ | ||
86 | char __user *userbuf, \ | ||
87 | size_t count, loff_t *ppos) \ | ||
88 | { \ | ||
89 | struct wl1271 *wl = file->private_data; \ | ||
90 | \ | ||
91 | wl1271_debugfs_update_stats(wl); \ | ||
92 | \ | ||
93 | return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ | ||
94 | wl->stats.fw_stats->sub.name); \ | ||
95 | } \ | ||
96 | \ | ||
97 | static const struct file_operations sub## _ ##name## _ops = { \ | ||
98 | .read = sub## _ ##name## _read, \ | ||
99 | .open = simple_open, \ | ||
100 | .llseek = generic_file_llseek, \ | ||
101 | }; | ||
102 | |||
103 | #define DEBUGFS_FWSTATS_ADD(sub, name) \ | ||
104 | DEBUGFS_ADD(sub## _ ##name, stats) | ||
105 | |||
106 | static void wl1271_debugfs_update_stats(struct wl1271 *wl) | ||
107 | { | 58 | { |
108 | int ret; | 59 | int ret; |
109 | 60 | ||
@@ -125,97 +76,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) | |||
125 | out: | 76 | out: |
126 | mutex_unlock(&wl->mutex); | 77 | mutex_unlock(&wl->mutex); |
127 | } | 78 | } |
128 | 79 | EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats); | |
129 | DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); | ||
130 | |||
131 | DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); | ||
132 | DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); | ||
133 | DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); | ||
134 | DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); | ||
135 | DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); | ||
136 | DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); | ||
137 | DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); | ||
138 | DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); | ||
139 | |||
140 | DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); | ||
141 | DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); | ||
142 | DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); | ||
143 | DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); | ||
144 | |||
145 | DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); | ||
146 | DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); | ||
147 | DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); | ||
148 | DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); | ||
149 | DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); | ||
150 | DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); | ||
151 | DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); | ||
152 | DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); | ||
153 | DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); | ||
154 | DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); | ||
155 | DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); | ||
156 | DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); | ||
157 | DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); | ||
158 | DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); | ||
159 | DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); | ||
160 | DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); | ||
161 | DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); | ||
162 | DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); | ||
163 | |||
164 | DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); | ||
165 | DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); | ||
166 | /* skipping wep.reserved */ | ||
167 | DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); | ||
168 | DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); | ||
169 | DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); | ||
170 | DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); | ||
171 | |||
172 | DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); | ||
173 | DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); | ||
174 | DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); | ||
175 | DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); | ||
176 | DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); | ||
177 | DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); | ||
178 | DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); | ||
179 | DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); | ||
180 | DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); | ||
181 | DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); | ||
182 | DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); | ||
183 | DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); | ||
184 | /* skipping cont_miss_bcns_spread for now */ | ||
185 | DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); | ||
186 | |||
187 | DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); | ||
188 | DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); | ||
189 | |||
190 | DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); | ||
191 | DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); | ||
192 | DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); | ||
193 | DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); | ||
194 | DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); | ||
195 | DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); | ||
196 | |||
197 | DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); | ||
198 | DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); | ||
199 | DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); | ||
200 | DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); | ||
201 | DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); | ||
202 | DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); | ||
203 | DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); | ||
204 | DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); | ||
205 | |||
206 | DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); | ||
207 | DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); | ||
208 | DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); | ||
209 | DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); | ||
210 | DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); | ||
211 | DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); | ||
212 | DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); | ||
213 | |||
214 | DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); | ||
215 | DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); | ||
216 | DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); | ||
217 | DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); | ||
218 | DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); | ||
219 | 80 | ||
220 | DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); | 81 | DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); |
221 | DEBUGFS_READONLY_FILE(excessive_retries, "%u", | 82 | DEBUGFS_READONLY_FILE(excessive_retries, "%u", |
@@ -241,6 +102,89 @@ static const struct file_operations tx_queue_len_ops = { | |||
241 | .llseek = default_llseek, | 102 | .llseek = default_llseek, |
242 | }; | 103 | }; |
243 | 104 | ||
105 | static void chip_op_handler(struct wl1271 *wl, unsigned long value, | ||
106 | void *arg) | ||
107 | { | ||
108 | int ret; | ||
109 | int (*chip_op) (struct wl1271 *wl); | ||
110 | |||
111 | if (!arg) { | ||
112 | wl1271_warning("debugfs chip_op_handler with no callback"); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | ret = wl1271_ps_elp_wakeup(wl); | ||
117 | if (ret < 0) | ||
118 | return; | ||
119 | |||
120 | chip_op = arg; | ||
121 | chip_op(wl); | ||
122 | |||
123 | wl1271_ps_elp_sleep(wl); | ||
124 | } | ||
125 | |||
126 | |||
127 | static inline void no_write_handler(struct wl1271 *wl, | ||
128 | unsigned long value, | ||
129 | unsigned long param) | ||
130 | { | ||
131 | } | ||
132 | |||
133 | #define WL12XX_CONF_DEBUGFS(param, conf_sub_struct, \ | ||
134 | min_val, max_val, write_handler_locked, \ | ||
135 | write_handler_arg) \ | ||
136 | static ssize_t param##_read(struct file *file, \ | ||
137 | char __user *user_buf, \ | ||
138 | size_t count, loff_t *ppos) \ | ||
139 | { \ | ||
140 | struct wl1271 *wl = file->private_data; \ | ||
141 | return wl1271_format_buffer(user_buf, count, \ | ||
142 | ppos, "%d\n", \ | ||
143 | wl->conf.conf_sub_struct.param); \ | ||
144 | } \ | ||
145 | \ | ||
146 | static ssize_t param##_write(struct file *file, \ | ||
147 | const char __user *user_buf, \ | ||
148 | size_t count, loff_t *ppos) \ | ||
149 | { \ | ||
150 | struct wl1271 *wl = file->private_data; \ | ||
151 | unsigned long value; \ | ||
152 | int ret; \ | ||
153 | \ | ||
154 | ret = kstrtoul_from_user(user_buf, count, 10, &value); \ | ||
155 | if (ret < 0) { \ | ||
156 | wl1271_warning("illegal value for " #param); \ | ||
157 | return -EINVAL; \ | ||
158 | } \ | ||
159 | \ | ||
160 | if (value < min_val || value > max_val) { \ | ||
161 | wl1271_warning(#param " is not in valid range"); \ | ||
162 | return -ERANGE; \ | ||
163 | } \ | ||
164 | \ | ||
165 | mutex_lock(&wl->mutex); \ | ||
166 | wl->conf.conf_sub_struct.param = value; \ | ||
167 | \ | ||
168 | write_handler_locked(wl, value, write_handler_arg); \ | ||
169 | \ | ||
170 | mutex_unlock(&wl->mutex); \ | ||
171 | return count; \ | ||
172 | } \ | ||
173 | \ | ||
174 | static const struct file_operations param##_ops = { \ | ||
175 | .read = param##_read, \ | ||
176 | .write = param##_write, \ | ||
177 | .open = simple_open, \ | ||
178 | .llseek = default_llseek, \ | ||
179 | }; | ||
180 | |||
181 | WL12XX_CONF_DEBUGFS(irq_pkt_threshold, rx, 0, 65535, | ||
182 | chip_op_handler, wl1271_acx_init_rx_interrupt) | ||
183 | WL12XX_CONF_DEBUGFS(irq_blk_threshold, rx, 0, 65535, | ||
184 | chip_op_handler, wl1271_acx_init_rx_interrupt) | ||
185 | WL12XX_CONF_DEBUGFS(irq_timeout, rx, 0, 100, | ||
186 | chip_op_handler, wl1271_acx_init_rx_interrupt) | ||
187 | |||
244 | static ssize_t gpio_power_read(struct file *file, char __user *user_buf, | 188 | static ssize_t gpio_power_read(struct file *file, char __user *user_buf, |
245 | size_t count, loff_t *ppos) | 189 | size_t count, loff_t *ppos) |
246 | { | 190 | { |
@@ -535,8 +479,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, | |||
535 | DRIVER_STATE_PRINT_LHEX(ap_ps_map); | 479 | DRIVER_STATE_PRINT_LHEX(ap_ps_map); |
536 | DRIVER_STATE_PRINT_HEX(quirks); | 480 | DRIVER_STATE_PRINT_HEX(quirks); |
537 | DRIVER_STATE_PRINT_HEX(irq); | 481 | DRIVER_STATE_PRINT_HEX(irq); |
538 | DRIVER_STATE_PRINT_HEX(ref_clock); | 482 | /* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */ |
539 | DRIVER_STATE_PRINT_HEX(tcxo_clock); | ||
540 | DRIVER_STATE_PRINT_HEX(hw_pg_ver); | 483 | DRIVER_STATE_PRINT_HEX(hw_pg_ver); |
541 | DRIVER_STATE_PRINT_HEX(platform_quirks); | 484 | DRIVER_STATE_PRINT_HEX(platform_quirks); |
542 | DRIVER_STATE_PRINT_HEX(chip.id); | 485 | DRIVER_STATE_PRINT_HEX(chip.id); |
@@ -647,7 +590,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, | |||
647 | VIF_STATE_PRINT_INT(last_rssi_event); | 590 | VIF_STATE_PRINT_INT(last_rssi_event); |
648 | VIF_STATE_PRINT_INT(ba_support); | 591 | VIF_STATE_PRINT_INT(ba_support); |
649 | VIF_STATE_PRINT_INT(ba_allowed); | 592 | VIF_STATE_PRINT_INT(ba_allowed); |
650 | VIF_STATE_PRINT_INT(is_gem); | ||
651 | VIF_STATE_PRINT_LLHEX(tx_security_seq); | 593 | VIF_STATE_PRINT_LLHEX(tx_security_seq); |
652 | VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); | 594 | VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); |
653 | } | 595 | } |
@@ -1002,108 +944,30 @@ static const struct file_operations beacon_filtering_ops = { | |||
1002 | .llseek = default_llseek, | 944 | .llseek = default_llseek, |
1003 | }; | 945 | }; |
1004 | 946 | ||
1005 | static int wl1271_debugfs_add_files(struct wl1271 *wl, | 947 | static ssize_t fw_stats_raw_read(struct file *file, |
1006 | struct dentry *rootdir) | 948 | char __user *userbuf, |
949 | size_t count, loff_t *ppos) | ||
1007 | { | 950 | { |
1008 | int ret = 0; | 951 | struct wl1271 *wl = file->private_data; |
1009 | struct dentry *entry, *stats, *streaming; | ||
1010 | 952 | ||
1011 | stats = debugfs_create_dir("fw-statistics", rootdir); | 953 | wl1271_debugfs_update_stats(wl); |
1012 | if (!stats || IS_ERR(stats)) { | ||
1013 | entry = stats; | ||
1014 | goto err; | ||
1015 | } | ||
1016 | 954 | ||
1017 | DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); | 955 | return simple_read_from_buffer(userbuf, count, ppos, |
1018 | 956 | wl->stats.fw_stats, | |
1019 | DEBUGFS_FWSTATS_ADD(rx, out_of_mem); | 957 | wl->stats.fw_stats_len); |
1020 | DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); | 958 | } |
1021 | DEBUGFS_FWSTATS_ADD(rx, hw_stuck); | 959 | |
1022 | DEBUGFS_FWSTATS_ADD(rx, dropped); | 960 | static const struct file_operations fw_stats_raw_ops = { |
1023 | DEBUGFS_FWSTATS_ADD(rx, fcs_err); | 961 | .read = fw_stats_raw_read, |
1024 | DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); | 962 | .open = simple_open, |
1025 | DEBUGFS_FWSTATS_ADD(rx, path_reset); | 963 | .llseek = default_llseek, |
1026 | DEBUGFS_FWSTATS_ADD(rx, reset_counter); | 964 | }; |
1027 | 965 | ||
1028 | DEBUGFS_FWSTATS_ADD(dma, rx_requested); | 966 | static int wl1271_debugfs_add_files(struct wl1271 *wl, |
1029 | DEBUGFS_FWSTATS_ADD(dma, rx_errors); | 967 | struct dentry *rootdir) |
1030 | DEBUGFS_FWSTATS_ADD(dma, tx_requested); | 968 | { |
1031 | DEBUGFS_FWSTATS_ADD(dma, tx_errors); | 969 | int ret = 0; |
1032 | 970 | struct dentry *entry, *streaming; | |
1033 | DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); | ||
1034 | DEBUGFS_FWSTATS_ADD(isr, fiqs); | ||
1035 | DEBUGFS_FWSTATS_ADD(isr, rx_headers); | ||
1036 | DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); | ||
1037 | DEBUGFS_FWSTATS_ADD(isr, rx_rdys); | ||
1038 | DEBUGFS_FWSTATS_ADD(isr, irqs); | ||
1039 | DEBUGFS_FWSTATS_ADD(isr, tx_procs); | ||
1040 | DEBUGFS_FWSTATS_ADD(isr, decrypt_done); | ||
1041 | DEBUGFS_FWSTATS_ADD(isr, dma0_done); | ||
1042 | DEBUGFS_FWSTATS_ADD(isr, dma1_done); | ||
1043 | DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); | ||
1044 | DEBUGFS_FWSTATS_ADD(isr, commands); | ||
1045 | DEBUGFS_FWSTATS_ADD(isr, rx_procs); | ||
1046 | DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); | ||
1047 | DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); | ||
1048 | DEBUGFS_FWSTATS_ADD(isr, pci_pm); | ||
1049 | DEBUGFS_FWSTATS_ADD(isr, wakeups); | ||
1050 | DEBUGFS_FWSTATS_ADD(isr, low_rssi); | ||
1051 | |||
1052 | DEBUGFS_FWSTATS_ADD(wep, addr_key_count); | ||
1053 | DEBUGFS_FWSTATS_ADD(wep, default_key_count); | ||
1054 | /* skipping wep.reserved */ | ||
1055 | DEBUGFS_FWSTATS_ADD(wep, key_not_found); | ||
1056 | DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); | ||
1057 | DEBUGFS_FWSTATS_ADD(wep, packets); | ||
1058 | DEBUGFS_FWSTATS_ADD(wep, interrupt); | ||
1059 | |||
1060 | DEBUGFS_FWSTATS_ADD(pwr, ps_enter); | ||
1061 | DEBUGFS_FWSTATS_ADD(pwr, elp_enter); | ||
1062 | DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); | ||
1063 | DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); | ||
1064 | DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); | ||
1065 | DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); | ||
1066 | DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); | ||
1067 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); | ||
1068 | DEBUGFS_FWSTATS_ADD(pwr, power_save_off); | ||
1069 | DEBUGFS_FWSTATS_ADD(pwr, enable_ps); | ||
1070 | DEBUGFS_FWSTATS_ADD(pwr, disable_ps); | ||
1071 | DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); | ||
1072 | /* skipping cont_miss_bcns_spread for now */ | ||
1073 | DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); | ||
1074 | |||
1075 | DEBUGFS_FWSTATS_ADD(mic, rx_pkts); | ||
1076 | DEBUGFS_FWSTATS_ADD(mic, calc_failure); | ||
1077 | |||
1078 | DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); | ||
1079 | DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); | ||
1080 | DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); | ||
1081 | DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); | ||
1082 | DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); | ||
1083 | DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); | ||
1084 | |||
1085 | DEBUGFS_FWSTATS_ADD(event, heart_beat); | ||
1086 | DEBUGFS_FWSTATS_ADD(event, calibration); | ||
1087 | DEBUGFS_FWSTATS_ADD(event, rx_mismatch); | ||
1088 | DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); | ||
1089 | DEBUGFS_FWSTATS_ADD(event, rx_pool); | ||
1090 | DEBUGFS_FWSTATS_ADD(event, oom_late); | ||
1091 | DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); | ||
1092 | DEBUGFS_FWSTATS_ADD(event, tx_stuck); | ||
1093 | |||
1094 | DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); | ||
1095 | DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); | ||
1096 | DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); | ||
1097 | DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); | ||
1098 | DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); | ||
1099 | DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); | ||
1100 | DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); | ||
1101 | |||
1102 | DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); | ||
1103 | DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); | ||
1104 | DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); | ||
1105 | DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); | ||
1106 | DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); | ||
1107 | 971 | ||
1108 | DEBUGFS_ADD(tx_queue_len, rootdir); | 972 | DEBUGFS_ADD(tx_queue_len, rootdir); |
1109 | DEBUGFS_ADD(retry_count, rootdir); | 973 | DEBUGFS_ADD(retry_count, rootdir); |
@@ -1120,6 +984,10 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, | |||
1120 | DEBUGFS_ADD(dynamic_ps_timeout, rootdir); | 984 | DEBUGFS_ADD(dynamic_ps_timeout, rootdir); |
1121 | DEBUGFS_ADD(forced_ps, rootdir); | 985 | DEBUGFS_ADD(forced_ps, rootdir); |
1122 | DEBUGFS_ADD(split_scan_timeout, rootdir); | 986 | DEBUGFS_ADD(split_scan_timeout, rootdir); |
987 | DEBUGFS_ADD(irq_pkt_threshold, rootdir); | ||
988 | DEBUGFS_ADD(irq_blk_threshold, rootdir); | ||
989 | DEBUGFS_ADD(irq_timeout, rootdir); | ||
990 | DEBUGFS_ADD(fw_stats_raw, rootdir); | ||
1123 | 991 | ||
1124 | streaming = debugfs_create_dir("rx_streaming", rootdir); | 992 | streaming = debugfs_create_dir("rx_streaming", rootdir); |
1125 | if (!streaming || IS_ERR(streaming)) | 993 | if (!streaming || IS_ERR(streaming)) |
@@ -1145,7 +1013,7 @@ void wl1271_debugfs_reset(struct wl1271 *wl) | |||
1145 | if (!wl->stats.fw_stats) | 1013 | if (!wl->stats.fw_stats) |
1146 | return; | 1014 | return; |
1147 | 1015 | ||
1148 | memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); | 1016 | memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len); |
1149 | wl->stats.retry_count = 0; | 1017 | wl->stats.retry_count = 0; |
1150 | wl->stats.excessive_retries = 0; | 1018 | wl->stats.excessive_retries = 0; |
1151 | } | 1019 | } |
@@ -1160,34 +1028,34 @@ int wl1271_debugfs_init(struct wl1271 *wl) | |||
1160 | 1028 | ||
1161 | if (IS_ERR(rootdir)) { | 1029 | if (IS_ERR(rootdir)) { |
1162 | ret = PTR_ERR(rootdir); | 1030 | ret = PTR_ERR(rootdir); |
1163 | goto err; | 1031 | goto out; |
1164 | } | 1032 | } |
1165 | 1033 | ||
1166 | wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), | 1034 | wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL); |
1167 | GFP_KERNEL); | ||
1168 | |||
1169 | if (!wl->stats.fw_stats) { | 1035 | if (!wl->stats.fw_stats) { |
1170 | ret = -ENOMEM; | 1036 | ret = -ENOMEM; |
1171 | goto err_fw; | 1037 | goto out_remove; |
1172 | } | 1038 | } |
1173 | 1039 | ||
1174 | wl->stats.fw_stats_update = jiffies; | 1040 | wl->stats.fw_stats_update = jiffies; |
1175 | 1041 | ||
1176 | ret = wl1271_debugfs_add_files(wl, rootdir); | 1042 | ret = wl1271_debugfs_add_files(wl, rootdir); |
1043 | if (ret < 0) | ||
1044 | goto out_exit; | ||
1177 | 1045 | ||
1046 | ret = wlcore_debugfs_init(wl, rootdir); | ||
1178 | if (ret < 0) | 1047 | if (ret < 0) |
1179 | goto err_file; | 1048 | goto out_exit; |
1180 | 1049 | ||
1181 | return 0; | 1050 | goto out; |
1182 | 1051 | ||
1183 | err_file: | 1052 | out_exit: |
1184 | kfree(wl->stats.fw_stats); | 1053 | wl1271_debugfs_exit(wl); |
1185 | wl->stats.fw_stats = NULL; | ||
1186 | 1054 | ||
1187 | err_fw: | 1055 | out_remove: |
1188 | debugfs_remove_recursive(rootdir); | 1056 | debugfs_remove_recursive(rootdir); |
1189 | 1057 | ||
1190 | err: | 1058 | out: |
1191 | return ret; | 1059 | return ret; |
1192 | } | 1060 | } |
1193 | 1061 | ||
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h index a8d3aef011ff..f7381dd69009 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.h +++ b/drivers/net/wireless/ti/wlcore/debugfs.h | |||
@@ -26,8 +26,95 @@ | |||
26 | 26 | ||
27 | #include "wlcore.h" | 27 | #include "wlcore.h" |
28 | 28 | ||
29 | int wl1271_format_buffer(char __user *userbuf, size_t count, | ||
30 | loff_t *ppos, char *fmt, ...); | ||
31 | |||
29 | int wl1271_debugfs_init(struct wl1271 *wl); | 32 | int wl1271_debugfs_init(struct wl1271 *wl); |
30 | void wl1271_debugfs_exit(struct wl1271 *wl); | 33 | void wl1271_debugfs_exit(struct wl1271 *wl); |
31 | void wl1271_debugfs_reset(struct wl1271 *wl); | 34 | void wl1271_debugfs_reset(struct wl1271 *wl); |
35 | void wl1271_debugfs_update_stats(struct wl1271 *wl); | ||
36 | |||
37 | #define DEBUGFS_FORMAT_BUFFER_SIZE 256 | ||
38 | |||
39 | #define DEBUGFS_READONLY_FILE(name, fmt, value...) \ | ||
40 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ | ||
41 | size_t count, loff_t *ppos) \ | ||
42 | { \ | ||
43 | struct wl1271 *wl = file->private_data; \ | ||
44 | return wl1271_format_buffer(userbuf, count, ppos, \ | ||
45 | fmt "\n", ##value); \ | ||
46 | } \ | ||
47 | \ | ||
48 | static const struct file_operations name## _ops = { \ | ||
49 | .read = name## _read, \ | ||
50 | .open = simple_open, \ | ||
51 | .llseek = generic_file_llseek, \ | ||
52 | }; | ||
53 | |||
54 | #define DEBUGFS_ADD(name, parent) \ | ||
55 | do { \ | ||
56 | entry = debugfs_create_file(#name, 0400, parent, \ | ||
57 | wl, &name## _ops); \ | ||
58 | if (!entry || IS_ERR(entry)) \ | ||
59 | goto err; \ | ||
60 | } while (0); | ||
61 | |||
62 | |||
63 | #define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ | ||
64 | do { \ | ||
65 | entry = debugfs_create_file(#name, 0400, parent, \ | ||
66 | wl, &prefix## _## name## _ops); \ | ||
67 | if (!entry || IS_ERR(entry)) \ | ||
68 | goto err; \ | ||
69 | } while (0); | ||
70 | |||
71 | #define DEBUGFS_FWSTATS_FILE(sub, name, fmt, struct_type) \ | ||
72 | static ssize_t sub## _ ##name## _read(struct file *file, \ | ||
73 | char __user *userbuf, \ | ||
74 | size_t count, loff_t *ppos) \ | ||
75 | { \ | ||
76 | struct wl1271 *wl = file->private_data; \ | ||
77 | struct struct_type *stats = wl->stats.fw_stats; \ | ||
78 | \ | ||
79 | wl1271_debugfs_update_stats(wl); \ | ||
80 | \ | ||
81 | return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ | ||
82 | stats->sub.name); \ | ||
83 | } \ | ||
84 | \ | ||
85 | static const struct file_operations sub## _ ##name## _ops = { \ | ||
86 | .read = sub## _ ##name## _read, \ | ||
87 | .open = simple_open, \ | ||
88 | .llseek = generic_file_llseek, \ | ||
89 | }; | ||
90 | |||
91 | #define DEBUGFS_FWSTATS_FILE_ARRAY(sub, name, len, struct_type) \ | ||
92 | static ssize_t sub## _ ##name## _read(struct file *file, \ | ||
93 | char __user *userbuf, \ | ||
94 | size_t count, loff_t *ppos) \ | ||
95 | { \ | ||
96 | struct wl1271 *wl = file->private_data; \ | ||
97 | struct struct_type *stats = wl->stats.fw_stats; \ | ||
98 | char buf[DEBUGFS_FORMAT_BUFFER_SIZE] = ""; \ | ||
99 | int res, i; \ | ||
100 | \ | ||
101 | wl1271_debugfs_update_stats(wl); \ | ||
102 | \ | ||
103 | for (i = 0; i < len; i++) \ | ||
104 | res = snprintf(buf, sizeof(buf), "%s[%d] = %d\n", \ | ||
105 | buf, i, stats->sub.name[i]); \ | ||
106 | \ | ||
107 | return wl1271_format_buffer(userbuf, count, ppos, "%s", buf); \ | ||
108 | } \ | ||
109 | \ | ||
110 | static const struct file_operations sub## _ ##name## _ops = { \ | ||
111 | .read = sub## _ ##name## _read, \ | ||
112 | .open = simple_open, \ | ||
113 | .llseek = generic_file_llseek, \ | ||
114 | }; | ||
115 | |||
116 | #define DEBUGFS_FWSTATS_ADD(sub, name) \ | ||
117 | DEBUGFS_ADD(sub## _ ##name, stats) | ||
118 | |||
32 | 119 | ||
33 | #endif /* WL1271_DEBUGFS_H */ | 120 | #endif /* WL1271_DEBUGFS_H */ |
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 28e2a633c3be..c976f0409865 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c | |||
@@ -148,15 +148,33 @@ static int wl1271_event_process(struct wl1271 *wl) | |||
148 | int delay = wl->conf.conn.synch_fail_thold * | 148 | int delay = wl->conf.conn.synch_fail_thold * |
149 | wl->conf.conn.bss_lose_timeout; | 149 | wl->conf.conn.bss_lose_timeout; |
150 | wl1271_info("Beacon loss detected."); | 150 | wl1271_info("Beacon loss detected."); |
151 | cancel_delayed_work_sync(&wl->connection_loss_work); | 151 | |
152 | /* | ||
153 | * if the work is already queued, it should take place. We | ||
154 | * don't want to delay the connection loss indication | ||
155 | * any more. | ||
156 | */ | ||
152 | ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, | 157 | ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, |
153 | msecs_to_jiffies(delay)); | 158 | msecs_to_jiffies(delay)); |
159 | |||
160 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | ||
161 | vif = wl12xx_wlvif_to_vif(wlvif); | ||
162 | |||
163 | ieee80211_cqm_rssi_notify( | ||
164 | vif, | ||
165 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, | ||
166 | GFP_KERNEL); | ||
167 | } | ||
154 | } | 168 | } |
155 | 169 | ||
156 | if (vector & REGAINED_BSS_EVENT_ID) { | 170 | if (vector & REGAINED_BSS_EVENT_ID) { |
157 | /* TODO: check for multi-role */ | 171 | /* TODO: check for multi-role */ |
158 | wl1271_info("Beacon regained."); | 172 | wl1271_info("Beacon regained."); |
159 | cancel_delayed_work_sync(&wl->connection_loss_work); | 173 | cancel_delayed_work(&wl->connection_loss_work); |
174 | |||
175 | /* sanity check - we can't lose and gain the beacon together */ | ||
176 | WARN(vector & BSS_LOSE_EVENT_ID, | ||
177 | "Concurrent beacon loss and gain from FW"); | ||
160 | } | 178 | } |
161 | 179 | ||
162 | if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { | 180 | if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { |
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 9384b4d56c24..9e7787ba9610 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h | |||
@@ -119,4 +119,82 @@ static inline int wlcore_identify_fw(struct wl1271 *wl) | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline void | ||
123 | wlcore_hw_set_tx_desc_csum(struct wl1271 *wl, | ||
124 | struct wl1271_tx_hw_descr *desc, | ||
125 | struct sk_buff *skb) | ||
126 | { | ||
127 | if (!wl->ops->set_tx_desc_csum) | ||
128 | BUG_ON(1); | ||
129 | |||
130 | wl->ops->set_tx_desc_csum(wl, desc, skb); | ||
131 | } | ||
132 | |||
133 | static inline void | ||
134 | wlcore_hw_set_rx_csum(struct wl1271 *wl, | ||
135 | struct wl1271_rx_descriptor *desc, | ||
136 | struct sk_buff *skb) | ||
137 | { | ||
138 | if (wl->ops->set_rx_csum) | ||
139 | wl->ops->set_rx_csum(wl, desc, skb); | ||
140 | } | ||
141 | |||
142 | static inline u32 | ||
143 | wlcore_hw_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, | ||
144 | struct wl12xx_vif *wlvif) | ||
145 | { | ||
146 | if (wl->ops->ap_get_mimo_wide_rate_mask) | ||
147 | return wl->ops->ap_get_mimo_wide_rate_mask(wl, wlvif); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static inline int | ||
153 | wlcore_debugfs_init(struct wl1271 *wl, struct dentry *rootdir) | ||
154 | { | ||
155 | if (wl->ops->debugfs_init) | ||
156 | return wl->ops->debugfs_init(wl, rootdir); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static inline int | ||
162 | wlcore_handle_static_data(struct wl1271 *wl, void *static_data) | ||
163 | { | ||
164 | if (wl->ops->handle_static_data) | ||
165 | return wl->ops->handle_static_data(wl, static_data); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static inline int | ||
171 | wlcore_hw_get_spare_blocks(struct wl1271 *wl, bool is_gem) | ||
172 | { | ||
173 | if (!wl->ops->get_spare_blocks) | ||
174 | BUG_ON(1); | ||
175 | |||
176 | return wl->ops->get_spare_blocks(wl, is_gem); | ||
177 | } | ||
178 | |||
179 | static inline int | ||
180 | wlcore_hw_set_key(struct wl1271 *wl, enum set_key_cmd cmd, | ||
181 | struct ieee80211_vif *vif, | ||
182 | struct ieee80211_sta *sta, | ||
183 | struct ieee80211_key_conf *key_conf) | ||
184 | { | ||
185 | if (!wl->ops->set_key) | ||
186 | BUG_ON(1); | ||
187 | |||
188 | return wl->ops->set_key(wl, cmd, vif, sta, key_conf); | ||
189 | } | ||
190 | |||
191 | static inline u32 | ||
192 | wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len) | ||
193 | { | ||
194 | if (wl->ops->pre_pkt_send) | ||
195 | return wl->ops->pre_pkt_send(wl, buf_offset, last_len); | ||
196 | |||
197 | return buf_offset; | ||
198 | } | ||
199 | |||
122 | #endif | 200 | #endif |
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 9f89255eb6e6..645abd4b660d 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c | |||
@@ -460,6 +460,9 @@ int wl1271_init_ap_rates(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
460 | /* unconditionally enable HT rates */ | 460 | /* unconditionally enable HT rates */ |
461 | supported_rates |= CONF_TX_MCS_RATES; | 461 | supported_rates |= CONF_TX_MCS_RATES; |
462 | 462 | ||
463 | /* get extra MIMO or wide-chan rates where the HW supports it */ | ||
464 | supported_rates |= wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif); | ||
465 | |||
463 | /* configure unicast TX rate classes */ | 466 | /* configure unicast TX rate classes */ |
464 | for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { | 467 | for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { |
465 | rc.enabled_rates = supported_rates; | 468 | rc.enabled_rates = supported_rates; |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index acef93390d3d..1156e3f578c1 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -320,46 +320,6 @@ static void wlcore_adjust_conf(struct wl1271 *wl) | |||
320 | } | 320 | } |
321 | } | 321 | } |
322 | 322 | ||
323 | static int wl1271_plt_init(struct wl1271 *wl) | ||
324 | { | ||
325 | int ret; | ||
326 | |||
327 | ret = wl->ops->hw_init(wl); | ||
328 | if (ret < 0) | ||
329 | return ret; | ||
330 | |||
331 | ret = wl1271_acx_init_mem_config(wl); | ||
332 | if (ret < 0) | ||
333 | return ret; | ||
334 | |||
335 | ret = wl12xx_acx_mem_cfg(wl); | ||
336 | if (ret < 0) | ||
337 | goto out_free_memmap; | ||
338 | |||
339 | /* Enable data path */ | ||
340 | ret = wl1271_cmd_data_path(wl, 1); | ||
341 | if (ret < 0) | ||
342 | goto out_free_memmap; | ||
343 | |||
344 | /* Configure for CAM power saving (ie. always active) */ | ||
345 | ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); | ||
346 | if (ret < 0) | ||
347 | goto out_free_memmap; | ||
348 | |||
349 | /* configure PM */ | ||
350 | ret = wl1271_acx_pm_config(wl); | ||
351 | if (ret < 0) | ||
352 | goto out_free_memmap; | ||
353 | |||
354 | return 0; | ||
355 | |||
356 | out_free_memmap: | ||
357 | kfree(wl->target_mem_map); | ||
358 | wl->target_mem_map = NULL; | ||
359 | |||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, | 323 | static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, |
364 | struct wl12xx_vif *wlvif, | 324 | struct wl12xx_vif *wlvif, |
365 | u8 hlid, u8 tx_pkts) | 325 | u8 hlid, u8 tx_pkts) |
@@ -387,7 +347,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl, | |||
387 | 347 | ||
388 | static void wl12xx_irq_update_links_status(struct wl1271 *wl, | 348 | static void wl12xx_irq_update_links_status(struct wl1271 *wl, |
389 | struct wl12xx_vif *wlvif, | 349 | struct wl12xx_vif *wlvif, |
390 | struct wl_fw_status *status) | 350 | struct wl_fw_status_2 *status) |
391 | { | 351 | { |
392 | struct wl1271_link *lnk; | 352 | struct wl1271_link *lnk; |
393 | u32 cur_fw_ps_map; | 353 | u32 cur_fw_ps_map; |
@@ -419,7 +379,8 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, | |||
419 | } | 379 | } |
420 | 380 | ||
421 | static void wl12xx_fw_status(struct wl1271 *wl, | 381 | static void wl12xx_fw_status(struct wl1271 *wl, |
422 | struct wl_fw_status *status) | 382 | struct wl_fw_status_1 *status_1, |
383 | struct wl_fw_status_2 *status_2) | ||
423 | { | 384 | { |
424 | struct wl12xx_vif *wlvif; | 385 | struct wl12xx_vif *wlvif; |
425 | struct timespec ts; | 386 | struct timespec ts; |
@@ -428,37 +389,38 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
428 | int i; | 389 | int i; |
429 | size_t status_len; | 390 | size_t status_len; |
430 | 391 | ||
431 | status_len = sizeof(*status) + wl->fw_status_priv_len; | 392 | status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + |
393 | sizeof(*status_2) + wl->fw_status_priv_len; | ||
432 | 394 | ||
433 | wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status, | 395 | wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, |
434 | status_len, false); | 396 | status_len, false); |
435 | 397 | ||
436 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 398 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
437 | "drv_rx_counter = %d, tx_results_counter = %d)", | 399 | "drv_rx_counter = %d, tx_results_counter = %d)", |
438 | status->intr, | 400 | status_1->intr, |
439 | status->fw_rx_counter, | 401 | status_1->fw_rx_counter, |
440 | status->drv_rx_counter, | 402 | status_1->drv_rx_counter, |
441 | status->tx_results_counter); | 403 | status_1->tx_results_counter); |
442 | 404 | ||
443 | for (i = 0; i < NUM_TX_QUEUES; i++) { | 405 | for (i = 0; i < NUM_TX_QUEUES; i++) { |
444 | /* prevent wrap-around in freed-packets counter */ | 406 | /* prevent wrap-around in freed-packets counter */ |
445 | wl->tx_allocated_pkts[i] -= | 407 | wl->tx_allocated_pkts[i] -= |
446 | (status->counters.tx_released_pkts[i] - | 408 | (status_2->counters.tx_released_pkts[i] - |
447 | wl->tx_pkts_freed[i]) & 0xff; | 409 | wl->tx_pkts_freed[i]) & 0xff; |
448 | 410 | ||
449 | wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i]; | 411 | wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i]; |
450 | } | 412 | } |
451 | 413 | ||
452 | /* prevent wrap-around in total blocks counter */ | 414 | /* prevent wrap-around in total blocks counter */ |
453 | if (likely(wl->tx_blocks_freed <= | 415 | if (likely(wl->tx_blocks_freed <= |
454 | le32_to_cpu(status->total_released_blks))) | 416 | le32_to_cpu(status_2->total_released_blks))) |
455 | freed_blocks = le32_to_cpu(status->total_released_blks) - | 417 | freed_blocks = le32_to_cpu(status_2->total_released_blks) - |
456 | wl->tx_blocks_freed; | 418 | wl->tx_blocks_freed; |
457 | else | 419 | else |
458 | freed_blocks = 0x100000000LL - wl->tx_blocks_freed + | 420 | freed_blocks = 0x100000000LL - wl->tx_blocks_freed + |
459 | le32_to_cpu(status->total_released_blks); | 421 | le32_to_cpu(status_2->total_released_blks); |
460 | 422 | ||
461 | wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks); | 423 | wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks); |
462 | 424 | ||
463 | wl->tx_allocated_blocks -= freed_blocks; | 425 | wl->tx_allocated_blocks -= freed_blocks; |
464 | 426 | ||
@@ -474,7 +436,7 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
474 | cancel_delayed_work(&wl->tx_watchdog_work); | 436 | cancel_delayed_work(&wl->tx_watchdog_work); |
475 | } | 437 | } |
476 | 438 | ||
477 | avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; | 439 | avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks; |
478 | 440 | ||
479 | /* | 441 | /* |
480 | * The FW might change the total number of TX memblocks before | 442 | * The FW might change the total number of TX memblocks before |
@@ -493,13 +455,13 @@ static void wl12xx_fw_status(struct wl1271 *wl, | |||
493 | 455 | ||
494 | /* for AP update num of allocated TX blocks per link and ps status */ | 456 | /* for AP update num of allocated TX blocks per link and ps status */ |
495 | wl12xx_for_each_wlvif_ap(wl, wlvif) { | 457 | wl12xx_for_each_wlvif_ap(wl, wlvif) { |
496 | wl12xx_irq_update_links_status(wl, wlvif, status); | 458 | wl12xx_irq_update_links_status(wl, wlvif, status_2); |
497 | } | 459 | } |
498 | 460 | ||
499 | /* update the host-chipset time offset */ | 461 | /* update the host-chipset time offset */ |
500 | getnstimeofday(&ts); | 462 | getnstimeofday(&ts); |
501 | wl->time_offset = (timespec_to_ns(&ts) >> 10) - | 463 | wl->time_offset = (timespec_to_ns(&ts) >> 10) - |
502 | (s64)le32_to_cpu(status->fw_localtime); | 464 | (s64)le32_to_cpu(status_2->fw_localtime); |
503 | } | 465 | } |
504 | 466 | ||
505 | static void wl1271_flush_deferred_work(struct wl1271 *wl) | 467 | static void wl1271_flush_deferred_work(struct wl1271 *wl) |
@@ -568,20 +530,30 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) | |||
568 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | 530 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); |
569 | smp_mb__after_clear_bit(); | 531 | smp_mb__after_clear_bit(); |
570 | 532 | ||
571 | wl12xx_fw_status(wl, wl->fw_status); | 533 | wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); |
572 | 534 | ||
573 | wlcore_hw_tx_immediate_compl(wl); | 535 | wlcore_hw_tx_immediate_compl(wl); |
574 | 536 | ||
575 | intr = le32_to_cpu(wl->fw_status->intr); | 537 | intr = le32_to_cpu(wl->fw_status_1->intr); |
576 | intr &= WL1271_INTR_MASK; | 538 | intr &= WLCORE_ALL_INTR_MASK; |
577 | if (!intr) { | 539 | if (!intr) { |
578 | done = true; | 540 | done = true; |
579 | continue; | 541 | continue; |
580 | } | 542 | } |
581 | 543 | ||
582 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { | 544 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { |
583 | wl1271_error("watchdog interrupt received! " | 545 | wl1271_error("HW watchdog interrupt received! starting recovery."); |
546 | wl->watchdog_recovery = true; | ||
547 | wl12xx_queue_recovery_work(wl); | ||
548 | |||
549 | /* restarting the chip. ignore any other interrupt. */ | ||
550 | goto out; | ||
551 | } | ||
552 | |||
553 | if (unlikely(intr & WL1271_ACX_SW_INTR_WATCHDOG)) { | ||
554 | wl1271_error("SW watchdog interrupt received! " | ||
584 | "starting recovery."); | 555 | "starting recovery."); |
556 | wl->watchdog_recovery = true; | ||
585 | wl12xx_queue_recovery_work(wl); | 557 | wl12xx_queue_recovery_work(wl); |
586 | 558 | ||
587 | /* restarting the chip. ignore any other interrupt. */ | 559 | /* restarting the chip. ignore any other interrupt. */ |
@@ -591,7 +563,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) | |||
591 | if (likely(intr & WL1271_ACX_INTR_DATA)) { | 563 | if (likely(intr & WL1271_ACX_INTR_DATA)) { |
592 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 564 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
593 | 565 | ||
594 | wl12xx_rx(wl, wl->fw_status); | 566 | wl12xx_rx(wl, wl->fw_status_1); |
595 | 567 | ||
596 | /* Check if any tx blocks were freed */ | 568 | /* Check if any tx blocks were freed */ |
597 | spin_lock_irqsave(&wl->wl_lock, flags); | 569 | spin_lock_irqsave(&wl->wl_lock, flags); |
@@ -743,7 +715,7 @@ out: | |||
743 | return ret; | 715 | return ret; |
744 | } | 716 | } |
745 | 717 | ||
746 | static int wl1271_fetch_nvs(struct wl1271 *wl) | 718 | static void wl1271_fetch_nvs(struct wl1271 *wl) |
747 | { | 719 | { |
748 | const struct firmware *fw; | 720 | const struct firmware *fw; |
749 | int ret; | 721 | int ret; |
@@ -751,16 +723,15 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
751 | ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev); | 723 | ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev); |
752 | 724 | ||
753 | if (ret < 0) { | 725 | if (ret < 0) { |
754 | wl1271_error("could not get nvs file %s: %d", WL12XX_NVS_NAME, | 726 | wl1271_debug(DEBUG_BOOT, "could not get nvs file %s: %d", |
755 | ret); | 727 | WL12XX_NVS_NAME, ret); |
756 | return ret; | 728 | return; |
757 | } | 729 | } |
758 | 730 | ||
759 | wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); | 731 | wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); |
760 | 732 | ||
761 | if (!wl->nvs) { | 733 | if (!wl->nvs) { |
762 | wl1271_error("could not allocate memory for the nvs file"); | 734 | wl1271_error("could not allocate memory for the nvs file"); |
763 | ret = -ENOMEM; | ||
764 | goto out; | 735 | goto out; |
765 | } | 736 | } |
766 | 737 | ||
@@ -768,8 +739,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
768 | 739 | ||
769 | out: | 740 | out: |
770 | release_firmware(fw); | 741 | release_firmware(fw); |
771 | |||
772 | return ret; | ||
773 | } | 742 | } |
774 | 743 | ||
775 | void wl12xx_queue_recovery_work(struct wl1271 *wl) | 744 | void wl12xx_queue_recovery_work(struct wl1271 *wl) |
@@ -820,14 +789,16 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) | |||
820 | 789 | ||
821 | /* | 790 | /* |
822 | * Make sure the chip is awake and the logger isn't active. | 791 | * Make sure the chip is awake and the logger isn't active. |
823 | * This might fail if the firmware hanged. | 792 | * Do not send a stop fwlog command if the fw is hanged. |
824 | */ | 793 | */ |
825 | if (!wl1271_ps_elp_wakeup(wl)) | 794 | if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery) |
826 | wl12xx_cmd_stop_fwlog(wl); | 795 | wl12xx_cmd_stop_fwlog(wl); |
796 | else | ||
797 | goto out; | ||
827 | 798 | ||
828 | /* Read the first memory block address */ | 799 | /* Read the first memory block address */ |
829 | wl12xx_fw_status(wl, wl->fw_status); | 800 | wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); |
830 | first_addr = le32_to_cpu(wl->fw_status->log_start_addr); | 801 | first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr); |
831 | if (!first_addr) | 802 | if (!first_addr) |
832 | goto out; | 803 | goto out; |
833 | 804 | ||
@@ -872,9 +843,14 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
872 | 843 | ||
873 | wl12xx_read_fwlog_panic(wl); | 844 | wl12xx_read_fwlog_panic(wl); |
874 | 845 | ||
875 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", | 846 | /* change partitions momentarily so we can read the FW pc */ |
847 | wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); | ||
848 | wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x " | ||
849 | "hint_sts: 0x%08x", | ||
876 | wl->chip.fw_ver_str, | 850 | wl->chip.fw_ver_str, |
877 | wlcore_read_reg(wl, REG_PC_ON_RECOVERY)); | 851 | wlcore_read_reg(wl, REG_PC_ON_RECOVERY), |
852 | wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR)); | ||
853 | wlcore_set_partition(wl, &wl->ptable[PART_WORK]); | ||
878 | 854 | ||
879 | BUG_ON(bug_on_recovery && | 855 | BUG_ON(bug_on_recovery && |
880 | !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); | 856 | !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); |
@@ -885,8 +861,6 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
885 | goto out_unlock; | 861 | goto out_unlock; |
886 | } | 862 | } |
887 | 863 | ||
888 | BUG_ON(bug_on_recovery); | ||
889 | |||
890 | /* | 864 | /* |
891 | * Advance security sequence number to overcome potential progress | 865 | * Advance security sequence number to overcome potential progress |
892 | * in the firmware during recovery. This doens't hurt if the network is | 866 | * in the firmware during recovery. This doens't hurt if the network is |
@@ -900,7 +874,7 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
900 | } | 874 | } |
901 | 875 | ||
902 | /* Prevent spurious TX during FW restart */ | 876 | /* Prevent spurious TX during FW restart */ |
903 | ieee80211_stop_queues(wl->hw); | 877 | wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); |
904 | 878 | ||
905 | if (wl->sched_scanning) { | 879 | if (wl->sched_scanning) { |
906 | ieee80211_sched_scan_stopped(wl->hw); | 880 | ieee80211_sched_scan_stopped(wl->hw); |
@@ -914,6 +888,7 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
914 | vif = wl12xx_wlvif_to_vif(wlvif); | 888 | vif = wl12xx_wlvif_to_vif(wlvif); |
915 | __wl1271_op_remove_interface(wl, vif, false); | 889 | __wl1271_op_remove_interface(wl, vif, false); |
916 | } | 890 | } |
891 | wl->watchdog_recovery = false; | ||
917 | mutex_unlock(&wl->mutex); | 892 | mutex_unlock(&wl->mutex); |
918 | wl1271_op_stop(wl->hw); | 893 | wl1271_op_stop(wl->hw); |
919 | 894 | ||
@@ -925,9 +900,10 @@ static void wl1271_recovery_work(struct work_struct *work) | |||
925 | * Its safe to enable TX now - the queues are stopped after a request | 900 | * Its safe to enable TX now - the queues are stopped after a request |
926 | * to restart the HW. | 901 | * to restart the HW. |
927 | */ | 902 | */ |
928 | ieee80211_wake_queues(wl->hw); | 903 | wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART); |
929 | return; | 904 | return; |
930 | out_unlock: | 905 | out_unlock: |
906 | wl->watchdog_recovery = false; | ||
931 | mutex_unlock(&wl->mutex); | 907 | mutex_unlock(&wl->mutex); |
932 | } | 908 | } |
933 | 909 | ||
@@ -938,13 +914,19 @@ static void wl1271_fw_wakeup(struct wl1271 *wl) | |||
938 | 914 | ||
939 | static int wl1271_setup(struct wl1271 *wl) | 915 | static int wl1271_setup(struct wl1271 *wl) |
940 | { | 916 | { |
941 | wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL); | 917 | wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + |
942 | if (!wl->fw_status) | 918 | sizeof(*wl->fw_status_2) + |
919 | wl->fw_status_priv_len, GFP_KERNEL); | ||
920 | if (!wl->fw_status_1) | ||
943 | return -ENOMEM; | 921 | return -ENOMEM; |
944 | 922 | ||
923 | wl->fw_status_2 = (struct wl_fw_status_2 *) | ||
924 | (((u8 *) wl->fw_status_1) + | ||
925 | WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc)); | ||
926 | |||
945 | wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); | 927 | wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); |
946 | if (!wl->tx_res_if) { | 928 | if (!wl->tx_res_if) { |
947 | kfree(wl->fw_status); | 929 | kfree(wl->fw_status_1); |
948 | return -ENOMEM; | 930 | return -ENOMEM; |
949 | } | 931 | } |
950 | 932 | ||
@@ -987,13 +969,12 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) | |||
987 | * simplify the code and since the performance impact is | 969 | * simplify the code and since the performance impact is |
988 | * negligible, we use the same block size for all different | 970 | * negligible, we use the same block size for all different |
989 | * chip types. | 971 | * chip types. |
972 | * | ||
973 | * Check if the bus supports blocksize alignment and, if it | ||
974 | * doesn't, make sure we don't have the quirk. | ||
990 | */ | 975 | */ |
991 | if (wl1271_set_block_size(wl)) | 976 | if (!wl1271_set_block_size(wl)) |
992 | wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; | 977 | wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; |
993 | |||
994 | ret = wl->ops->identify_chip(wl); | ||
995 | if (ret < 0) | ||
996 | goto out; | ||
997 | 978 | ||
998 | /* TODO: make sure the lower driver has set things up correctly */ | 979 | /* TODO: make sure the lower driver has set things up correctly */ |
999 | 980 | ||
@@ -1005,13 +986,6 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) | |||
1005 | if (ret < 0) | 986 | if (ret < 0) |
1006 | goto out; | 987 | goto out; |
1007 | 988 | ||
1008 | /* No NVS from netlink, try to get it from the filesystem */ | ||
1009 | if (wl->nvs == NULL) { | ||
1010 | ret = wl1271_fetch_nvs(wl); | ||
1011 | if (ret < 0) | ||
1012 | goto out; | ||
1013 | } | ||
1014 | |||
1015 | out: | 989 | out: |
1016 | return ret; | 990 | return ret; |
1017 | } | 991 | } |
@@ -1039,14 +1013,10 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1039 | if (ret < 0) | 1013 | if (ret < 0) |
1040 | goto power_off; | 1014 | goto power_off; |
1041 | 1015 | ||
1042 | ret = wl->ops->boot(wl); | 1016 | ret = wl->ops->plt_init(wl); |
1043 | if (ret < 0) | 1017 | if (ret < 0) |
1044 | goto power_off; | 1018 | goto power_off; |
1045 | 1019 | ||
1046 | ret = wl1271_plt_init(wl); | ||
1047 | if (ret < 0) | ||
1048 | goto irq_disable; | ||
1049 | |||
1050 | wl->plt = true; | 1020 | wl->plt = true; |
1051 | wl->state = WL1271_STATE_ON; | 1021 | wl->state = WL1271_STATE_ON; |
1052 | wl1271_notice("firmware booted in PLT mode (%s)", | 1022 | wl1271_notice("firmware booted in PLT mode (%s)", |
@@ -1059,19 +1029,6 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1059 | 1029 | ||
1060 | goto out; | 1030 | goto out; |
1061 | 1031 | ||
1062 | irq_disable: | ||
1063 | mutex_unlock(&wl->mutex); | ||
1064 | /* Unlocking the mutex in the middle of handling is | ||
1065 | inherently unsafe. In this case we deem it safe to do, | ||
1066 | because we need to let any possibly pending IRQ out of | ||
1067 | the system (and while we are WL1271_STATE_OFF the IRQ | ||
1068 | work function will not do anything.) Also, any other | ||
1069 | possible concurrent operations will fail due to the | ||
1070 | current state, hence the wl1271 struct should be safe. */ | ||
1071 | wlcore_disable_interrupts(wl); | ||
1072 | wl1271_flush_deferred_work(wl); | ||
1073 | cancel_work_sync(&wl->netstack_work); | ||
1074 | mutex_lock(&wl->mutex); | ||
1075 | power_off: | 1032 | power_off: |
1076 | wl1271_power_off(wl); | 1033 | wl1271_power_off(wl); |
1077 | } | 1034 | } |
@@ -1154,9 +1111,16 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1154 | 1111 | ||
1155 | spin_lock_irqsave(&wl->wl_lock, flags); | 1112 | spin_lock_irqsave(&wl->wl_lock, flags); |
1156 | 1113 | ||
1157 | /* queue the packet */ | 1114 | /* |
1115 | * drop the packet if the link is invalid or the queue is stopped | ||
1116 | * for any reason but watermark. Watermark is a "soft"-stop so we | ||
1117 | * allow these packets through. | ||
1118 | */ | ||
1158 | if (hlid == WL12XX_INVALID_LINK_ID || | 1119 | if (hlid == WL12XX_INVALID_LINK_ID || |
1159 | (wlvif && !test_bit(hlid, wlvif->links_map))) { | 1120 | (wlvif && !test_bit(hlid, wlvif->links_map)) || |
1121 | (wlcore_is_queue_stopped(wl, q) && | ||
1122 | !wlcore_is_queue_stopped_by_reason(wl, q, | ||
1123 | WLCORE_QUEUE_STOP_REASON_WATERMARK))) { | ||
1160 | wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q); | 1124 | wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q); |
1161 | ieee80211_free_txskb(hw, skb); | 1125 | ieee80211_free_txskb(hw, skb); |
1162 | goto out; | 1126 | goto out; |
@@ -1174,8 +1138,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1174 | */ | 1138 | */ |
1175 | if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) { | 1139 | if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) { |
1176 | wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); | 1140 | wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q); |
1177 | ieee80211_stop_queue(wl->hw, mapping); | 1141 | wlcore_stop_queue_locked(wl, q, |
1178 | set_bit(q, &wl->stopped_queues_map); | 1142 | WLCORE_QUEUE_STOP_REASON_WATERMARK); |
1179 | } | 1143 | } |
1180 | 1144 | ||
1181 | /* | 1145 | /* |
@@ -1758,7 +1722,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1758 | cancel_delayed_work_sync(&wl->connection_loss_work); | 1722 | cancel_delayed_work_sync(&wl->connection_loss_work); |
1759 | 1723 | ||
1760 | /* let's notify MAC80211 about the remaining pending TX frames */ | 1724 | /* let's notify MAC80211 about the remaining pending TX frames */ |
1761 | wl12xx_tx_reset(wl, true); | 1725 | wl12xx_tx_reset(wl); |
1762 | mutex_lock(&wl->mutex); | 1726 | mutex_lock(&wl->mutex); |
1763 | 1727 | ||
1764 | wl1271_power_off(wl); | 1728 | wl1271_power_off(wl); |
@@ -1767,6 +1731,7 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1767 | 1731 | ||
1768 | wl->rx_counter = 0; | 1732 | wl->rx_counter = 0; |
1769 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; | 1733 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; |
1734 | wl->channel_type = NL80211_CHAN_NO_HT; | ||
1770 | wl->tx_blocks_available = 0; | 1735 | wl->tx_blocks_available = 0; |
1771 | wl->tx_allocated_blocks = 0; | 1736 | wl->tx_allocated_blocks = 0; |
1772 | wl->tx_results_count = 0; | 1737 | wl->tx_results_count = 0; |
@@ -1799,8 +1764,9 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1799 | 1764 | ||
1800 | wl1271_debugfs_reset(wl); | 1765 | wl1271_debugfs_reset(wl); |
1801 | 1766 | ||
1802 | kfree(wl->fw_status); | 1767 | kfree(wl->fw_status_1); |
1803 | wl->fw_status = NULL; | 1768 | wl->fw_status_1 = NULL; |
1769 | wl->fw_status_2 = NULL; | ||
1804 | kfree(wl->tx_res_if); | 1770 | kfree(wl->tx_res_if); |
1805 | wl->tx_res_if = NULL; | 1771 | wl->tx_res_if = NULL; |
1806 | kfree(wl->target_mem_map); | 1772 | kfree(wl->target_mem_map); |
@@ -1894,6 +1860,9 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | |||
1894 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx); | 1860 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx); |
1895 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx); | 1861 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx); |
1896 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx); | 1862 | wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx); |
1863 | wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC; | ||
1864 | wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC; | ||
1865 | wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; | ||
1897 | } else { | 1866 | } else { |
1898 | /* init ap data */ | 1867 | /* init ap data */ |
1899 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; | 1868 | wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID; |
@@ -1903,13 +1872,19 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | |||
1903 | for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) | 1872 | for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++) |
1904 | wl12xx_allocate_rate_policy(wl, | 1873 | wl12xx_allocate_rate_policy(wl, |
1905 | &wlvif->ap.ucast_rate_idx[i]); | 1874 | &wlvif->ap.ucast_rate_idx[i]); |
1875 | wlvif->basic_rate_set = CONF_TX_AP_ENABLED_RATES; | ||
1876 | /* | ||
1877 | * TODO: check if basic_rate shouldn't be | ||
1878 | * wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); | ||
1879 | * instead (the same thing for STA above). | ||
1880 | */ | ||
1881 | wlvif->basic_rate = CONF_TX_AP_ENABLED_RATES; | ||
1882 | /* TODO: this seems to be used only for STA, check it */ | ||
1883 | wlvif->rate_set = CONF_TX_AP_ENABLED_RATES; | ||
1906 | } | 1884 | } |
1907 | 1885 | ||
1908 | wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; | 1886 | wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate; |
1909 | wlvif->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; | 1887 | wlvif->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5; |
1910 | wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC; | ||
1911 | wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC; | ||
1912 | wlvif->rate_set = CONF_TX_RATE_MASK_BASIC; | ||
1913 | wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT; | 1888 | wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT; |
1914 | 1889 | ||
1915 | /* | 1890 | /* |
@@ -1919,6 +1894,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) | |||
1919 | wlvif->band = wl->band; | 1894 | wlvif->band = wl->band; |
1920 | wlvif->channel = wl->channel; | 1895 | wlvif->channel = wl->channel; |
1921 | wlvif->power_level = wl->power_level; | 1896 | wlvif->power_level = wl->power_level; |
1897 | wlvif->channel_type = wl->channel_type; | ||
1922 | 1898 | ||
1923 | INIT_WORK(&wlvif->rx_streaming_enable_work, | 1899 | INIT_WORK(&wlvif->rx_streaming_enable_work, |
1924 | wl1271_rx_streaming_enable_work); | 1900 | wl1271_rx_streaming_enable_work); |
@@ -2444,7 +2420,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2444 | } else { | 2420 | } else { |
2445 | /* The current firmware only supports sched_scan in idle */ | 2421 | /* The current firmware only supports sched_scan in idle */ |
2446 | if (wl->sched_scanning) { | 2422 | if (wl->sched_scanning) { |
2447 | wl1271_scan_sched_scan_stop(wl); | 2423 | wl1271_scan_sched_scan_stop(wl, wlvif); |
2448 | ieee80211_sched_scan_stopped(wl->hw); | 2424 | ieee80211_sched_scan_stopped(wl->hw); |
2449 | } | 2425 | } |
2450 | 2426 | ||
@@ -2469,13 +2445,20 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2469 | /* if the channel changes while joined, join again */ | 2445 | /* if the channel changes while joined, join again */ |
2470 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && | 2446 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL && |
2471 | ((wlvif->band != conf->channel->band) || | 2447 | ((wlvif->band != conf->channel->band) || |
2472 | (wlvif->channel != channel))) { | 2448 | (wlvif->channel != channel) || |
2449 | (wlvif->channel_type != conf->channel_type))) { | ||
2473 | /* send all pending packets */ | 2450 | /* send all pending packets */ |
2474 | wl1271_tx_work_locked(wl); | 2451 | wl1271_tx_work_locked(wl); |
2475 | wlvif->band = conf->channel->band; | 2452 | wlvif->band = conf->channel->band; |
2476 | wlvif->channel = channel; | 2453 | wlvif->channel = channel; |
2454 | wlvif->channel_type = conf->channel_type; | ||
2477 | 2455 | ||
2478 | if (!is_ap) { | 2456 | if (is_ap) { |
2457 | ret = wl1271_init_ap_rates(wl, wlvif); | ||
2458 | if (ret < 0) | ||
2459 | wl1271_error("AP rate policy change failed %d", | ||
2460 | ret); | ||
2461 | } else { | ||
2479 | /* | 2462 | /* |
2480 | * FIXME: the mac80211 should really provide a fixed | 2463 | * FIXME: the mac80211 should really provide a fixed |
2481 | * rate to use here. for now, just use the smallest | 2464 | * rate to use here. for now, just use the smallest |
@@ -2583,8 +2566,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2583 | * frames, such as the deauth. To make sure those frames reach the air, | 2566 | * frames, such as the deauth. To make sure those frames reach the air, |
2584 | * wait here until the TX queue is fully flushed. | 2567 | * wait here until the TX queue is fully flushed. |
2585 | */ | 2568 | */ |
2586 | if ((changed & IEEE80211_CONF_CHANGE_IDLE) && | 2569 | if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || |
2587 | (conf->flags & IEEE80211_CONF_IDLE)) | 2570 | ((changed & IEEE80211_CONF_CHANGE_IDLE) && |
2571 | (conf->flags & IEEE80211_CONF_IDLE))) | ||
2588 | wl1271_tx_flush(wl); | 2572 | wl1271_tx_flush(wl); |
2589 | 2573 | ||
2590 | mutex_lock(&wl->mutex); | 2574 | mutex_lock(&wl->mutex); |
@@ -2593,6 +2577,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
2593 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 2577 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2594 | wl->band = conf->channel->band; | 2578 | wl->band = conf->channel->band; |
2595 | wl->channel = channel; | 2579 | wl->channel = channel; |
2580 | wl->channel_type = conf->channel_type; | ||
2596 | } | 2581 | } |
2597 | 2582 | ||
2598 | if (changed & IEEE80211_CONF_CHANGE_POWER) | 2583 | if (changed & IEEE80211_CONF_CHANGE_POWER) |
@@ -2825,17 +2810,6 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2825 | int ret; | 2810 | int ret; |
2826 | bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); | 2811 | bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); |
2827 | 2812 | ||
2828 | /* | ||
2829 | * A role set to GEM cipher requires different Tx settings (namely | ||
2830 | * spare blocks). Note when we are in this mode so the HW can adjust. | ||
2831 | */ | ||
2832 | if (key_type == KEY_GEM) { | ||
2833 | if (action == KEY_ADD_OR_REPLACE) | ||
2834 | wlvif->is_gem = true; | ||
2835 | else if (action == KEY_REMOVE) | ||
2836 | wlvif->is_gem = false; | ||
2837 | } | ||
2838 | |||
2839 | if (is_ap) { | 2813 | if (is_ap) { |
2840 | struct wl1271_station *wl_sta; | 2814 | struct wl1271_station *wl_sta; |
2841 | u8 hlid; | 2815 | u8 hlid; |
@@ -2913,12 +2887,21 @@ static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
2913 | return 0; | 2887 | return 0; |
2914 | } | 2888 | } |
2915 | 2889 | ||
2916 | static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2890 | static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
2917 | struct ieee80211_vif *vif, | 2891 | struct ieee80211_vif *vif, |
2918 | struct ieee80211_sta *sta, | 2892 | struct ieee80211_sta *sta, |
2919 | struct ieee80211_key_conf *key_conf) | 2893 | struct ieee80211_key_conf *key_conf) |
2920 | { | 2894 | { |
2921 | struct wl1271 *wl = hw->priv; | 2895 | struct wl1271 *wl = hw->priv; |
2896 | |||
2897 | return wlcore_hw_set_key(wl, cmd, vif, sta, key_conf); | ||
2898 | } | ||
2899 | |||
2900 | int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, | ||
2901 | struct ieee80211_vif *vif, | ||
2902 | struct ieee80211_sta *sta, | ||
2903 | struct ieee80211_key_conf *key_conf) | ||
2904 | { | ||
2922 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | 2905 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
2923 | int ret; | 2906 | int ret; |
2924 | u32 tx_seq_32 = 0; | 2907 | u32 tx_seq_32 = 0; |
@@ -3029,6 +3012,7 @@ out_unlock: | |||
3029 | 3012 | ||
3030 | return ret; | 3013 | return ret; |
3031 | } | 3014 | } |
3015 | EXPORT_SYMBOL_GPL(wlcore_set_key); | ||
3032 | 3016 | ||
3033 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | 3017 | static int wl1271_op_hw_scan(struct ieee80211_hw *hw, |
3034 | struct ieee80211_vif *vif, | 3018 | struct ieee80211_vif *vif, |
@@ -3167,6 +3151,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, | |||
3167 | struct ieee80211_vif *vif) | 3151 | struct ieee80211_vif *vif) |
3168 | { | 3152 | { |
3169 | struct wl1271 *wl = hw->priv; | 3153 | struct wl1271 *wl = hw->priv; |
3154 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
3170 | int ret; | 3155 | int ret; |
3171 | 3156 | ||
3172 | wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop"); | 3157 | wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop"); |
@@ -3180,7 +3165,7 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, | |||
3180 | if (ret < 0) | 3165 | if (ret < 0) |
3181 | goto out; | 3166 | goto out; |
3182 | 3167 | ||
3183 | wl1271_scan_sched_scan_stop(wl); | 3168 | wl1271_scan_sched_scan_stop(wl, wlvif); |
3184 | 3169 | ||
3185 | wl1271_ps_elp_sleep(wl); | 3170 | wl1271_ps_elp_sleep(wl); |
3186 | out: | 3171 | out: |
@@ -3316,8 +3301,15 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates, | |||
3316 | skb->data, | 3301 | skb->data, |
3317 | skb->len, 0, | 3302 | skb->len, 0, |
3318 | rates); | 3303 | rates); |
3319 | |||
3320 | dev_kfree_skb(skb); | 3304 | dev_kfree_skb(skb); |
3305 | |||
3306 | if (ret < 0) | ||
3307 | goto out; | ||
3308 | |||
3309 | wl1271_debug(DEBUG_AP, "probe response updated"); | ||
3310 | set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags); | ||
3311 | |||
3312 | out: | ||
3321 | return ret; | 3313 | return ret; |
3322 | } | 3314 | } |
3323 | 3315 | ||
@@ -3422,6 +3414,87 @@ out: | |||
3422 | return ret; | 3414 | return ret; |
3423 | } | 3415 | } |
3424 | 3416 | ||
3417 | static int wlcore_set_beacon_template(struct wl1271 *wl, | ||
3418 | struct ieee80211_vif *vif, | ||
3419 | bool is_ap) | ||
3420 | { | ||
3421 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); | ||
3422 | struct ieee80211_hdr *hdr; | ||
3423 | u32 min_rate; | ||
3424 | int ret; | ||
3425 | int ieoffset = offsetof(struct ieee80211_mgmt, | ||
3426 | u.beacon.variable); | ||
3427 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); | ||
3428 | u16 tmpl_id; | ||
3429 | |||
3430 | if (!beacon) { | ||
3431 | ret = -EINVAL; | ||
3432 | goto out; | ||
3433 | } | ||
3434 | |||
3435 | wl1271_debug(DEBUG_MASTER, "beacon updated"); | ||
3436 | |||
3437 | ret = wl1271_ssid_set(vif, beacon, ieoffset); | ||
3438 | if (ret < 0) { | ||
3439 | dev_kfree_skb(beacon); | ||
3440 | goto out; | ||
3441 | } | ||
3442 | min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); | ||
3443 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : | ||
3444 | CMD_TEMPL_BEACON; | ||
3445 | ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id, | ||
3446 | beacon->data, | ||
3447 | beacon->len, 0, | ||
3448 | min_rate); | ||
3449 | if (ret < 0) { | ||
3450 | dev_kfree_skb(beacon); | ||
3451 | goto out; | ||
3452 | } | ||
3453 | |||
3454 | /* | ||
3455 | * In case we already have a probe-resp beacon set explicitly | ||
3456 | * by usermode, don't use the beacon data. | ||
3457 | */ | ||
3458 | if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags)) | ||
3459 | goto end_bcn; | ||
3460 | |||
3461 | /* remove TIM ie from probe response */ | ||
3462 | wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); | ||
3463 | |||
3464 | /* | ||
3465 | * remove p2p ie from probe response. | ||
3466 | * the fw reponds to probe requests that don't include | ||
3467 | * the p2p ie. probe requests with p2p ie will be passed, | ||
3468 | * and will be responded by the supplicant (the spec | ||
3469 | * forbids including the p2p ie when responding to probe | ||
3470 | * requests that didn't include it). | ||
3471 | */ | ||
3472 | wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, | ||
3473 | WLAN_OUI_TYPE_WFA_P2P, ieoffset); | ||
3474 | |||
3475 | hdr = (struct ieee80211_hdr *) beacon->data; | ||
3476 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
3477 | IEEE80211_STYPE_PROBE_RESP); | ||
3478 | if (is_ap) | ||
3479 | ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif, | ||
3480 | beacon->data, | ||
3481 | beacon->len, | ||
3482 | min_rate); | ||
3483 | else | ||
3484 | ret = wl1271_cmd_template_set(wl, wlvif->role_id, | ||
3485 | CMD_TEMPL_PROBE_RESPONSE, | ||
3486 | beacon->data, | ||
3487 | beacon->len, 0, | ||
3488 | min_rate); | ||
3489 | end_bcn: | ||
3490 | dev_kfree_skb(beacon); | ||
3491 | if (ret < 0) | ||
3492 | goto out; | ||
3493 | |||
3494 | out: | ||
3495 | return ret; | ||
3496 | } | ||
3497 | |||
3425 | static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | 3498 | static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, |
3426 | struct ieee80211_vif *vif, | 3499 | struct ieee80211_vif *vif, |
3427 | struct ieee80211_bss_conf *bss_conf, | 3500 | struct ieee80211_bss_conf *bss_conf, |
@@ -3440,81 +3513,12 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, | |||
3440 | 3513 | ||
3441 | if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) { | 3514 | if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) { |
3442 | u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); | 3515 | u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); |
3443 | if (!wl1271_ap_set_probe_resp_tmpl(wl, rate, vif)) { | 3516 | |
3444 | wl1271_debug(DEBUG_AP, "probe response updated"); | 3517 | wl1271_ap_set_probe_resp_tmpl(wl, rate, vif); |
3445 | set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags); | ||
3446 | } | ||
3447 | } | 3518 | } |
3448 | 3519 | ||
3449 | if ((changed & BSS_CHANGED_BEACON)) { | 3520 | if ((changed & BSS_CHANGED_BEACON)) { |
3450 | struct ieee80211_hdr *hdr; | 3521 | ret = wlcore_set_beacon_template(wl, vif, is_ap); |
3451 | u32 min_rate; | ||
3452 | int ieoffset = offsetof(struct ieee80211_mgmt, | ||
3453 | u.beacon.variable); | ||
3454 | struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); | ||
3455 | u16 tmpl_id; | ||
3456 | |||
3457 | if (!beacon) { | ||
3458 | ret = -EINVAL; | ||
3459 | goto out; | ||
3460 | } | ||
3461 | |||
3462 | wl1271_debug(DEBUG_MASTER, "beacon updated"); | ||
3463 | |||
3464 | ret = wl1271_ssid_set(vif, beacon, ieoffset); | ||
3465 | if (ret < 0) { | ||
3466 | dev_kfree_skb(beacon); | ||
3467 | goto out; | ||
3468 | } | ||
3469 | min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); | ||
3470 | tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : | ||
3471 | CMD_TEMPL_BEACON; | ||
3472 | ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id, | ||
3473 | beacon->data, | ||
3474 | beacon->len, 0, | ||
3475 | min_rate); | ||
3476 | if (ret < 0) { | ||
3477 | dev_kfree_skb(beacon); | ||
3478 | goto out; | ||
3479 | } | ||
3480 | |||
3481 | /* | ||
3482 | * In case we already have a probe-resp beacon set explicitly | ||
3483 | * by usermode, don't use the beacon data. | ||
3484 | */ | ||
3485 | if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags)) | ||
3486 | goto end_bcn; | ||
3487 | |||
3488 | /* remove TIM ie from probe response */ | ||
3489 | wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset); | ||
3490 | |||
3491 | /* | ||
3492 | * remove p2p ie from probe response. | ||
3493 | * the fw reponds to probe requests that don't include | ||
3494 | * the p2p ie. probe requests with p2p ie will be passed, | ||
3495 | * and will be responded by the supplicant (the spec | ||
3496 | * forbids including the p2p ie when responding to probe | ||
3497 | * requests that didn't include it). | ||
3498 | */ | ||
3499 | wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA, | ||
3500 | WLAN_OUI_TYPE_WFA_P2P, ieoffset); | ||
3501 | |||
3502 | hdr = (struct ieee80211_hdr *) beacon->data; | ||
3503 | hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
3504 | IEEE80211_STYPE_PROBE_RESP); | ||
3505 | if (is_ap) | ||
3506 | ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif, | ||
3507 | beacon->data, | ||
3508 | beacon->len, | ||
3509 | min_rate); | ||
3510 | else | ||
3511 | ret = wl1271_cmd_template_set(wl, wlvif->role_id, | ||
3512 | CMD_TEMPL_PROBE_RESPONSE, | ||
3513 | beacon->data, | ||
3514 | beacon->len, 0, | ||
3515 | min_rate); | ||
3516 | end_bcn: | ||
3517 | dev_kfree_skb(beacon); | ||
3518 | if (ret < 0) | 3522 | if (ret < 0) |
3519 | goto out; | 3523 | goto out; |
3520 | } | 3524 | } |
@@ -3551,6 +3555,14 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, | |||
3551 | ret = wl1271_ap_init_templates(wl, vif); | 3555 | ret = wl1271_ap_init_templates(wl, vif); |
3552 | if (ret < 0) | 3556 | if (ret < 0) |
3553 | goto out; | 3557 | goto out; |
3558 | |||
3559 | ret = wl1271_ap_set_probe_resp_tmpl(wl, wlvif->basic_rate, vif); | ||
3560 | if (ret < 0) | ||
3561 | goto out; | ||
3562 | |||
3563 | ret = wlcore_set_beacon_template(wl, vif, true); | ||
3564 | if (ret < 0) | ||
3565 | goto out; | ||
3554 | } | 3566 | } |
3555 | 3567 | ||
3556 | ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed); | 3568 | ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed); |
@@ -3691,7 +3703,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
3691 | sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; | 3703 | sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; |
3692 | if (sta->ht_cap.ht_supported) | 3704 | if (sta->ht_cap.ht_supported) |
3693 | sta_rate_set |= | 3705 | sta_rate_set |= |
3694 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); | 3706 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) | |
3707 | (sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET); | ||
3695 | sta_ht_cap = sta->ht_cap; | 3708 | sta_ht_cap = sta->ht_cap; |
3696 | sta_exists = true; | 3709 | sta_exists = true; |
3697 | 3710 | ||
@@ -3704,13 +3717,11 @@ sta_not_found: | |||
3704 | u32 rates; | 3717 | u32 rates; |
3705 | int ieoffset; | 3718 | int ieoffset; |
3706 | wlvif->aid = bss_conf->aid; | 3719 | wlvif->aid = bss_conf->aid; |
3720 | wlvif->channel_type = bss_conf->channel_type; | ||
3707 | wlvif->beacon_int = bss_conf->beacon_int; | 3721 | wlvif->beacon_int = bss_conf->beacon_int; |
3708 | do_join = true; | 3722 | do_join = true; |
3709 | set_assoc = true; | 3723 | set_assoc = true; |
3710 | 3724 | ||
3711 | /* Cancel connection_loss_work */ | ||
3712 | cancel_delayed_work_sync(&wl->connection_loss_work); | ||
3713 | |||
3714 | /* | 3725 | /* |
3715 | * use basic rates from AP, and determine lowest rate | 3726 | * use basic rates from AP, and determine lowest rate |
3716 | * to use with control frames. | 3727 | * to use with control frames. |
@@ -3960,6 +3971,17 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
3960 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", | 3971 | wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", |
3961 | (int)changed); | 3972 | (int)changed); |
3962 | 3973 | ||
3974 | /* | ||
3975 | * make sure to cancel pending disconnections if our association | ||
3976 | * state changed | ||
3977 | */ | ||
3978 | if (!is_ap && (changed & BSS_CHANGED_ASSOC)) | ||
3979 | cancel_delayed_work_sync(&wl->connection_loss_work); | ||
3980 | |||
3981 | if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) && | ||
3982 | !bss_conf->enable_beacon) | ||
3983 | wl1271_tx_flush(wl); | ||
3984 | |||
3963 | mutex_lock(&wl->mutex); | 3985 | mutex_lock(&wl->mutex); |
3964 | 3986 | ||
3965 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 3987 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
@@ -4636,7 +4658,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
4636 | .prepare_multicast = wl1271_op_prepare_multicast, | 4658 | .prepare_multicast = wl1271_op_prepare_multicast, |
4637 | .configure_filter = wl1271_op_configure_filter, | 4659 | .configure_filter = wl1271_op_configure_filter, |
4638 | .tx = wl1271_op_tx, | 4660 | .tx = wl1271_op_tx, |
4639 | .set_key = wl1271_op_set_key, | 4661 | .set_key = wlcore_op_set_key, |
4640 | .hw_scan = wl1271_op_hw_scan, | 4662 | .hw_scan = wl1271_op_hw_scan, |
4641 | .cancel_hw_scan = wl1271_op_cancel_hw_scan, | 4663 | .cancel_hw_scan = wl1271_op_cancel_hw_scan, |
4642 | .sched_scan_start = wl1271_op_sched_scan_start, | 4664 | .sched_scan_start = wl1271_op_sched_scan_start, |
@@ -4905,14 +4927,8 @@ static int wl1271_register_hw(struct wl1271 *wl) | |||
4905 | if (wl->mac80211_registered) | 4927 | if (wl->mac80211_registered) |
4906 | return 0; | 4928 | return 0; |
4907 | 4929 | ||
4908 | ret = wl12xx_get_hw_info(wl); | 4930 | wl1271_fetch_nvs(wl); |
4909 | if (ret < 0) { | 4931 | if (wl->nvs != NULL) { |
4910 | wl1271_error("couldn't get hw info"); | ||
4911 | goto out; | ||
4912 | } | ||
4913 | |||
4914 | ret = wl1271_fetch_nvs(wl); | ||
4915 | if (ret == 0) { | ||
4916 | /* NOTE: The wl->nvs->nvs element must be first, in | 4932 | /* NOTE: The wl->nvs->nvs element must be first, in |
4917 | * order to simplify the casting, we assume it is at | 4933 | * order to simplify the casting, we assume it is at |
4918 | * the beginning of the wl->nvs structure. | 4934 | * the beginning of the wl->nvs structure. |
@@ -4970,9 +4986,11 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
4970 | WL1271_CIPHER_SUITE_GEM, | 4986 | WL1271_CIPHER_SUITE_GEM, |
4971 | }; | 4987 | }; |
4972 | 4988 | ||
4973 | /* The tx descriptor buffer and the TKIP space. */ | 4989 | /* The tx descriptor buffer */ |
4974 | wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP + | 4990 | wl->hw->extra_tx_headroom = sizeof(struct wl1271_tx_hw_descr); |
4975 | sizeof(struct wl1271_tx_hw_descr); | 4991 | |
4992 | if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) | ||
4993 | wl->hw->extra_tx_headroom += WL1271_EXTRA_SPACE_TKIP; | ||
4976 | 4994 | ||
4977 | /* unit us */ | 4995 | /* unit us */ |
4978 | /* FIXME: find a proper value */ | 4996 | /* FIXME: find a proper value */ |
@@ -5025,12 +5043,14 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) | |||
5025 | */ | 5043 | */ |
5026 | memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, | 5044 | memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz, |
5027 | sizeof(wl1271_band_2ghz)); | 5045 | sizeof(wl1271_band_2ghz)); |
5028 | memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, &wl->ht_cap, | 5046 | memcpy(&wl->bands[IEEE80211_BAND_2GHZ].ht_cap, |
5029 | sizeof(wl->ht_cap)); | 5047 | &wl->ht_cap[IEEE80211_BAND_2GHZ], |
5048 | sizeof(*wl->ht_cap)); | ||
5030 | memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, | 5049 | memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz, |
5031 | sizeof(wl1271_band_5ghz)); | 5050 | sizeof(wl1271_band_5ghz)); |
5032 | memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, &wl->ht_cap, | 5051 | memcpy(&wl->bands[IEEE80211_BAND_5GHZ].ht_cap, |
5033 | sizeof(wl->ht_cap)); | 5052 | &wl->ht_cap[IEEE80211_BAND_5GHZ], |
5053 | sizeof(*wl->ht_cap)); | ||
5034 | 5054 | ||
5035 | wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | 5055 | wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
5036 | &wl->bands[IEEE80211_BAND_2GHZ]; | 5056 | &wl->bands[IEEE80211_BAND_2GHZ]; |
@@ -5117,6 +5137,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) | |||
5117 | wl->rx_counter = 0; | 5137 | wl->rx_counter = 0; |
5118 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; | 5138 | wl->power_level = WL1271_DEFAULT_POWER_LEVEL; |
5119 | wl->band = IEEE80211_BAND_2GHZ; | 5139 | wl->band = IEEE80211_BAND_2GHZ; |
5140 | wl->channel_type = NL80211_CHAN_NO_HT; | ||
5120 | wl->flags = 0; | 5141 | wl->flags = 0; |
5121 | wl->sg_enabled = true; | 5142 | wl->sg_enabled = true; |
5122 | wl->hw_pg_ver = -1; | 5143 | wl->hw_pg_ver = -1; |
@@ -5142,6 +5163,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) | |||
5142 | wl->state = WL1271_STATE_OFF; | 5163 | wl->state = WL1271_STATE_OFF; |
5143 | wl->fw_type = WL12XX_FW_TYPE_NONE; | 5164 | wl->fw_type = WL12XX_FW_TYPE_NONE; |
5144 | mutex_init(&wl->mutex); | 5165 | mutex_init(&wl->mutex); |
5166 | mutex_init(&wl->flush_mutex); | ||
5145 | 5167 | ||
5146 | order = get_order(WL1271_AGGR_BUFFER_SIZE); | 5168 | order = get_order(WL1271_AGGR_BUFFER_SIZE); |
5147 | wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); | 5169 | wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); |
@@ -5222,7 +5244,7 @@ int wlcore_free_hw(struct wl1271 *wl) | |||
5222 | kfree(wl->nvs); | 5244 | kfree(wl->nvs); |
5223 | wl->nvs = NULL; | 5245 | wl->nvs = NULL; |
5224 | 5246 | ||
5225 | kfree(wl->fw_status); | 5247 | kfree(wl->fw_status_1); |
5226 | kfree(wl->tx_res_if); | 5248 | kfree(wl->tx_res_if); |
5227 | destroy_workqueue(wl->freezable_wq); | 5249 | destroy_workqueue(wl->freezable_wq); |
5228 | 5250 | ||
@@ -5279,8 +5301,6 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) | |||
5279 | wlcore_adjust_conf(wl); | 5301 | wlcore_adjust_conf(wl); |
5280 | 5302 | ||
5281 | wl->irq = platform_get_irq(pdev, 0); | 5303 | wl->irq = platform_get_irq(pdev, 0); |
5282 | wl->ref_clock = pdata->board_ref_clock; | ||
5283 | wl->tcxo_clock = pdata->board_tcxo_clock; | ||
5284 | wl->platform_quirks = pdata->platform_quirks; | 5304 | wl->platform_quirks = pdata->platform_quirks; |
5285 | wl->set_power = pdata->set_power; | 5305 | wl->set_power = pdata->set_power; |
5286 | wl->dev = &pdev->dev; | 5306 | wl->dev = &pdev->dev; |
@@ -5316,6 +5336,16 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) | |||
5316 | } | 5336 | } |
5317 | disable_irq(wl->irq); | 5337 | disable_irq(wl->irq); |
5318 | 5338 | ||
5339 | ret = wl12xx_get_hw_info(wl); | ||
5340 | if (ret < 0) { | ||
5341 | wl1271_error("couldn't get hw info"); | ||
5342 | goto out; | ||
5343 | } | ||
5344 | |||
5345 | ret = wl->ops->identify_chip(wl); | ||
5346 | if (ret < 0) | ||
5347 | goto out; | ||
5348 | |||
5319 | ret = wl1271_init_ieee80211(wl); | 5349 | ret = wl1271_init_ieee80211(wl); |
5320 | if (ret) | 5350 | if (ret) |
5321 | goto out_irq; | 5351 | goto out_irq; |
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 756eee2257b4..47e81b32f7da 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #define WL1271_WAKEUP_TIMEOUT 500 | 29 | #define WL1271_WAKEUP_TIMEOUT 500 |
30 | 30 | ||
31 | #define ELP_ENTRY_DELAY 5 | ||
32 | |||
31 | void wl1271_elp_work(struct work_struct *work) | 33 | void wl1271_elp_work(struct work_struct *work) |
32 | { | 34 | { |
33 | struct delayed_work *dwork; | 35 | struct delayed_work *dwork; |
@@ -72,6 +74,7 @@ out: | |||
72 | void wl1271_ps_elp_sleep(struct wl1271 *wl) | 74 | void wl1271_ps_elp_sleep(struct wl1271 *wl) |
73 | { | 75 | { |
74 | struct wl12xx_vif *wlvif; | 76 | struct wl12xx_vif *wlvif; |
77 | u32 timeout; | ||
75 | 78 | ||
76 | if (wl->quirks & WLCORE_QUIRK_NO_ELP) | 79 | if (wl->quirks & WLCORE_QUIRK_NO_ELP) |
77 | return; | 80 | return; |
@@ -89,8 +92,13 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
89 | return; | 92 | return; |
90 | } | 93 | } |
91 | 94 | ||
95 | if (wl->conf.conn.forced_ps) | ||
96 | timeout = ELP_ENTRY_DELAY; | ||
97 | else | ||
98 | timeout = wl->conf.conn.dynamic_ps_timeout; | ||
99 | |||
92 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, | 100 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, |
93 | msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); | 101 | msecs_to_jiffies(timeout)); |
94 | } | 102 | } |
95 | 103 | ||
96 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) | 104 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) |
@@ -185,8 +193,12 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
185 | 193 | ||
186 | set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); | 194 | set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); |
187 | 195 | ||
188 | /* enable beacon early termination. Not relevant for 5GHz */ | 196 | /* |
189 | if (wlvif->band == IEEE80211_BAND_2GHZ) { | 197 | * enable beacon early termination. |
198 | * Not relevant for 5GHz and for high rates. | ||
199 | */ | ||
200 | if ((wlvif->band == IEEE80211_BAND_2GHZ) && | ||
201 | (wlvif->basic_rate < CONF_HW_BIT_RATE_9MBPS)) { | ||
190 | ret = wl1271_acx_bet_enable(wl, wlvif, true); | 202 | ret = wl1271_acx_bet_enable(wl, wlvif, true); |
191 | if (ret < 0) | 203 | if (ret < 0) |
192 | return ret; | 204 | return ret; |
@@ -196,7 +208,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
196 | wl1271_debug(DEBUG_PSM, "leaving psm"); | 208 | wl1271_debug(DEBUG_PSM, "leaving psm"); |
197 | 209 | ||
198 | /* disable beacon early termination */ | 210 | /* disable beacon early termination */ |
199 | if (wlvif->band == IEEE80211_BAND_2GHZ) { | 211 | if ((wlvif->band == IEEE80211_BAND_2GHZ) && |
212 | (wlvif->basic_rate < CONF_HW_BIT_RATE_9MBPS)) { | ||
200 | ret = wl1271_acx_bet_enable(wl, wlvif, false); | 213 | ret = wl1271_acx_bet_enable(wl, wlvif, false); |
201 | if (ret < 0) | 214 | if (ret < 0) |
202 | return ret; | 215 | return ret; |
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c index d6a3c6b07827..78200dcacfca 100644 --- a/drivers/net/wireless/ti/wlcore/rx.c +++ b/drivers/net/wireless/ti/wlcore/rx.c | |||
@@ -186,6 +186,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, | |||
186 | is_data = 1; | 186 | is_data = 1; |
187 | 187 | ||
188 | wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); | 188 | wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); |
189 | wlcore_hw_set_rx_csum(wl, desc, skb); | ||
189 | 190 | ||
190 | seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | 191 | seq_num = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; |
191 | wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d hlid %d", skb, | 192 | wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s seq %d hlid %d", skb, |
@@ -199,12 +200,12 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, | |||
199 | return is_data; | 200 | return is_data; |
200 | } | 201 | } |
201 | 202 | ||
202 | void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) | 203 | void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) |
203 | { | 204 | { |
204 | unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; | 205 | unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; |
205 | u32 buf_size; | 206 | u32 buf_size; |
206 | u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; | 207 | u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc; |
207 | u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; | 208 | u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc; |
208 | u32 rx_counter; | 209 | u32 rx_counter; |
209 | u32 pkt_len, align_pkt_len; | 210 | u32 pkt_len, align_pkt_len; |
210 | u32 pkt_offset, des; | 211 | u32 pkt_offset, des; |
@@ -223,7 +224,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) | |||
223 | break; | 224 | break; |
224 | buf_size += align_pkt_len; | 225 | buf_size += align_pkt_len; |
225 | rx_counter++; | 226 | rx_counter++; |
226 | rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; | 227 | rx_counter %= wl->num_rx_desc; |
227 | } | 228 | } |
228 | 229 | ||
229 | if (buf_size == 0) { | 230 | if (buf_size == 0) { |
@@ -263,7 +264,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status) | |||
263 | 264 | ||
264 | wl->rx_counter++; | 265 | wl->rx_counter++; |
265 | drv_rx_counter++; | 266 | drv_rx_counter++; |
266 | drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; | 267 | drv_rx_counter %= wl->num_rx_desc; |
267 | pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len); | 268 | pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len); |
268 | } | 269 | } |
269 | } | 270 | } |
diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h index e9a162a864ca..9be780179456 100644 --- a/drivers/net/wireless/ti/wlcore/rx.h +++ b/drivers/net/wireless/ti/wlcore/rx.h | |||
@@ -38,8 +38,6 @@ | |||
38 | #define RX_DESC_PACKETID_SHIFT 11 | 38 | #define RX_DESC_PACKETID_SHIFT 11 |
39 | #define RX_MAX_PACKET_ID 3 | 39 | #define RX_MAX_PACKET_ID 3 |
40 | 40 | ||
41 | #define NUM_RX_PKT_DESC_MOD_MASK 7 | ||
42 | |||
43 | #define RX_DESC_VALID_FCS 0x0001 | 41 | #define RX_DESC_VALID_FCS 0x0001 |
44 | #define RX_DESC_MATCH_RXADDR1 0x0002 | 42 | #define RX_DESC_MATCH_RXADDR1 0x0002 |
45 | #define RX_DESC_MCAST 0x0004 | 43 | #define RX_DESC_MCAST 0x0004 |
@@ -102,6 +100,9 @@ | |||
102 | /* If set, the start of IP payload is not 4 bytes aligned */ | 100 | /* If set, the start of IP payload is not 4 bytes aligned */ |
103 | #define RX_BUF_UNALIGNED_PAYLOAD BIT(20) | 101 | #define RX_BUF_UNALIGNED_PAYLOAD BIT(20) |
104 | 102 | ||
103 | /* If set, the buffer was padded by the FW to be 4 bytes aligned */ | ||
104 | #define RX_BUF_PADDED_PAYLOAD BIT(30) | ||
105 | |||
105 | /* Describes the alignment state of a Rx buffer */ | 106 | /* Describes the alignment state of a Rx buffer */ |
106 | enum wl_rx_buf_align { | 107 | enum wl_rx_buf_align { |
107 | WLCORE_RX_BUF_ALIGNED, | 108 | WLCORE_RX_BUF_ALIGNED, |
@@ -136,7 +137,7 @@ struct wl1271_rx_descriptor { | |||
136 | u8 reserved; | 137 | u8 reserved; |
137 | } __packed; | 138 | } __packed; |
138 | 139 | ||
139 | void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status *status); | 140 | void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); |
140 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 141 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); |
141 | int wl1271_rx_filter_enable(struct wl1271 *wl, | 142 | int wl1271_rx_filter_enable(struct wl1271 *wl, |
142 | int index, bool enable, | 143 | int index, bool enable, |
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index ade21a011c45..d9daed53ceb7 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c | |||
@@ -411,7 +411,8 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
411 | struct cfg80211_sched_scan_request *req, | 411 | struct cfg80211_sched_scan_request *req, |
412 | struct conn_scan_ch_params *channels, | 412 | struct conn_scan_ch_params *channels, |
413 | u32 band, bool radar, bool passive, | 413 | u32 band, bool radar, bool passive, |
414 | int start, int max_channels) | 414 | int start, int max_channels, |
415 | u8 *n_pactive_ch) | ||
415 | { | 416 | { |
416 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; | 417 | struct conf_sched_scan_settings *c = &wl->conf.sched_scan; |
417 | int i, j; | 418 | int i, j; |
@@ -479,6 +480,23 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, | |||
479 | channels[j].tx_power_att = req->channels[i]->max_power; | 480 | channels[j].tx_power_att = req->channels[i]->max_power; |
480 | channels[j].channel = req->channels[i]->hw_value; | 481 | channels[j].channel = req->channels[i]->hw_value; |
481 | 482 | ||
483 | if ((band == IEEE80211_BAND_2GHZ) && | ||
484 | (channels[j].channel >= 12) && | ||
485 | (channels[j].channel <= 14) && | ||
486 | (flags & IEEE80211_CHAN_PASSIVE_SCAN) && | ||
487 | !force_passive) { | ||
488 | /* pactive channels treated as DFS */ | ||
489 | channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; | ||
490 | |||
491 | /* | ||
492 | * n_pactive_ch is counted down from the end of | ||
493 | * the passive channel list | ||
494 | */ | ||
495 | (*n_pactive_ch)++; | ||
496 | wl1271_debug(DEBUG_SCAN, "n_pactive_ch = %d", | ||
497 | *n_pactive_ch); | ||
498 | } | ||
499 | |||
482 | j++; | 500 | j++; |
483 | } | 501 | } |
484 | } | 502 | } |
@@ -491,38 +509,47 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, | |||
491 | struct cfg80211_sched_scan_request *req, | 509 | struct cfg80211_sched_scan_request *req, |
492 | struct wl1271_cmd_sched_scan_config *cfg) | 510 | struct wl1271_cmd_sched_scan_config *cfg) |
493 | { | 511 | { |
512 | u8 n_pactive_ch = 0; | ||
513 | |||
494 | cfg->passive[0] = | 514 | cfg->passive[0] = |
495 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, | 515 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, |
496 | IEEE80211_BAND_2GHZ, | 516 | IEEE80211_BAND_2GHZ, |
497 | false, true, 0, | 517 | false, true, 0, |
498 | MAX_CHANNELS_2GHZ); | 518 | MAX_CHANNELS_2GHZ, |
519 | &n_pactive_ch); | ||
499 | cfg->active[0] = | 520 | cfg->active[0] = |
500 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, | 521 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_2, |
501 | IEEE80211_BAND_2GHZ, | 522 | IEEE80211_BAND_2GHZ, |
502 | false, false, | 523 | false, false, |
503 | cfg->passive[0], | 524 | cfg->passive[0], |
504 | MAX_CHANNELS_2GHZ); | 525 | MAX_CHANNELS_2GHZ, |
526 | &n_pactive_ch); | ||
505 | cfg->passive[1] = | 527 | cfg->passive[1] = |
506 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, | 528 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, |
507 | IEEE80211_BAND_5GHZ, | 529 | IEEE80211_BAND_5GHZ, |
508 | false, true, 0, | 530 | false, true, 0, |
509 | MAX_CHANNELS_5GHZ); | 531 | MAX_CHANNELS_5GHZ, |
532 | &n_pactive_ch); | ||
510 | cfg->dfs = | 533 | cfg->dfs = |
511 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, | 534 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, |
512 | IEEE80211_BAND_5GHZ, | 535 | IEEE80211_BAND_5GHZ, |
513 | true, true, | 536 | true, true, |
514 | cfg->passive[1], | 537 | cfg->passive[1], |
515 | MAX_CHANNELS_5GHZ); | 538 | MAX_CHANNELS_5GHZ, |
539 | &n_pactive_ch); | ||
516 | cfg->active[1] = | 540 | cfg->active[1] = |
517 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, | 541 | wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels_5, |
518 | IEEE80211_BAND_5GHZ, | 542 | IEEE80211_BAND_5GHZ, |
519 | false, false, | 543 | false, false, |
520 | cfg->passive[1] + cfg->dfs, | 544 | cfg->passive[1] + cfg->dfs, |
521 | MAX_CHANNELS_5GHZ); | 545 | MAX_CHANNELS_5GHZ, |
546 | &n_pactive_ch); | ||
522 | /* 802.11j channels are not supported yet */ | 547 | /* 802.11j channels are not supported yet */ |
523 | cfg->passive[2] = 0; | 548 | cfg->passive[2] = 0; |
524 | cfg->active[2] = 0; | 549 | cfg->active[2] = 0; |
525 | 550 | ||
551 | cfg->n_pactive_ch = n_pactive_ch; | ||
552 | |||
526 | wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", | 553 | wl1271_debug(DEBUG_SCAN, " 2.4GHz: active %d passive %d", |
527 | cfg->active[0], cfg->passive[0]); | 554 | cfg->active[0], cfg->passive[0]); |
528 | wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", | 555 | wl1271_debug(DEBUG_SCAN, " 5GHz: active %d passive %d", |
@@ -537,6 +564,7 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl, | |||
537 | /* Returns the scan type to be used or a negative value on error */ | 564 | /* Returns the scan type to be used or a negative value on error */ |
538 | static int | 565 | static int |
539 | wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, | 566 | wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, |
567 | struct wl12xx_vif *wlvif, | ||
540 | struct cfg80211_sched_scan_request *req) | 568 | struct cfg80211_sched_scan_request *req) |
541 | { | 569 | { |
542 | struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; | 570 | struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL; |
@@ -565,6 +593,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, | |||
565 | goto out; | 593 | goto out; |
566 | } | 594 | } |
567 | 595 | ||
596 | cmd->role_id = wlvif->dev_role_id; | ||
568 | if (!n_match_ssids) { | 597 | if (!n_match_ssids) { |
569 | /* No filter, with ssids */ | 598 | /* No filter, with ssids */ |
570 | type = SCAN_SSID_FILTER_DISABLED; | 599 | type = SCAN_SSID_FILTER_DISABLED; |
@@ -603,7 +632,9 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, | |||
603 | continue; | 632 | continue; |
604 | 633 | ||
605 | for (j = 0; j < cmd->n_ssids; j++) | 634 | for (j = 0; j < cmd->n_ssids; j++) |
606 | if (!memcmp(req->ssids[i].ssid, | 635 | if ((req->ssids[i].ssid_len == |
636 | req->ssids[j].ssid_len) && | ||
637 | !memcmp(req->ssids[i].ssid, | ||
607 | cmd->ssids[j].ssid, | 638 | cmd->ssids[j].ssid, |
608 | req->ssids[i].ssid_len)) { | 639 | req->ssids[i].ssid_len)) { |
609 | cmd->ssids[j].type = | 640 | cmd->ssids[j].type = |
@@ -652,6 +683,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
652 | if (!cfg) | 683 | if (!cfg) |
653 | return -ENOMEM; | 684 | return -ENOMEM; |
654 | 685 | ||
686 | cfg->role_id = wlvif->dev_role_id; | ||
655 | cfg->rssi_threshold = c->rssi_threshold; | 687 | cfg->rssi_threshold = c->rssi_threshold; |
656 | cfg->snr_threshold = c->snr_threshold; | 688 | cfg->snr_threshold = c->snr_threshold; |
657 | cfg->n_probe_reqs = c->num_probe_reqs; | 689 | cfg->n_probe_reqs = c->num_probe_reqs; |
@@ -669,7 +701,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
669 | cfg->intervals[i] = cpu_to_le32(req->interval); | 701 | cfg->intervals[i] = cpu_to_le32(req->interval); |
670 | 702 | ||
671 | cfg->ssid_len = 0; | 703 | cfg->ssid_len = 0; |
672 | ret = wl12xx_scan_sched_scan_ssid_list(wl, req); | 704 | ret = wl12xx_scan_sched_scan_ssid_list(wl, wlvif, req); |
673 | if (ret < 0) | 705 | if (ret < 0) |
674 | goto out; | 706 | goto out; |
675 | 707 | ||
@@ -741,6 +773,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
741 | if (!start) | 773 | if (!start) |
742 | return -ENOMEM; | 774 | return -ENOMEM; |
743 | 775 | ||
776 | start->role_id = wlvif->dev_role_id; | ||
744 | start->tag = WL1271_SCAN_DEFAULT_TAG; | 777 | start->tag = WL1271_SCAN_DEFAULT_TAG; |
745 | 778 | ||
746 | ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start, | 779 | ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start, |
@@ -762,7 +795,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl) | |||
762 | ieee80211_sched_scan_results(wl->hw); | 795 | ieee80211_sched_scan_results(wl->hw); |
763 | } | 796 | } |
764 | 797 | ||
765 | void wl1271_scan_sched_scan_stop(struct wl1271 *wl) | 798 | void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif) |
766 | { | 799 | { |
767 | struct wl1271_cmd_sched_scan_stop *stop; | 800 | struct wl1271_cmd_sched_scan_stop *stop; |
768 | int ret = 0; | 801 | int ret = 0; |
@@ -776,6 +809,7 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl) | |||
776 | return; | 809 | return; |
777 | } | 810 | } |
778 | 811 | ||
812 | stop->role_id = wlvif->dev_role_id; | ||
779 | stop->tag = WL1271_SCAN_DEFAULT_TAG; | 813 | stop->tag = WL1271_SCAN_DEFAULT_TAG; |
780 | 814 | ||
781 | ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop, | 815 | ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop, |
diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h index 81ee36ac2078..29f3c8d6b046 100644 --- a/drivers/net/wireless/ti/wlcore/scan.h +++ b/drivers/net/wireless/ti/wlcore/scan.h | |||
@@ -40,7 +40,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, | |||
40 | struct cfg80211_sched_scan_request *req, | 40 | struct cfg80211_sched_scan_request *req, |
41 | struct ieee80211_sched_scan_ies *ies); | 41 | struct ieee80211_sched_scan_ies *ies); |
42 | int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 42 | int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
43 | void wl1271_scan_sched_scan_stop(struct wl1271 *wl); | 43 | void wl1271_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
44 | void wl1271_scan_sched_scan_results(struct wl1271 *wl); | 44 | void wl1271_scan_sched_scan_results(struct wl1271 *wl); |
45 | 45 | ||
46 | #define WL1271_SCAN_MAX_CHANNELS 24 | 46 | #define WL1271_SCAN_MAX_CHANNELS 24 |
@@ -142,7 +142,8 @@ enum { | |||
142 | SCAN_BSS_TYPE_ANY, | 142 | SCAN_BSS_TYPE_ANY, |
143 | }; | 143 | }; |
144 | 144 | ||
145 | #define SCAN_CHANNEL_FLAGS_DFS BIT(0) | 145 | #define SCAN_CHANNEL_FLAGS_DFS BIT(0) /* channel is passive until an |
146 | activity is detected on it */ | ||
146 | #define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1) | 147 | #define SCAN_CHANNEL_FLAGS_DFS_ENABLED BIT(1) |
147 | 148 | ||
148 | struct conn_scan_ch_params { | 149 | struct conn_scan_ch_params { |
@@ -185,7 +186,10 @@ struct wl1271_cmd_sched_scan_config { | |||
185 | 186 | ||
186 | u8 dfs; | 187 | u8 dfs; |
187 | 188 | ||
188 | u8 padding[3]; | 189 | u8 n_pactive_ch; /* number of pactive (passive until fw detects energy) |
190 | channels in BG band */ | ||
191 | u8 role_id; | ||
192 | u8 padding[1]; | ||
189 | 193 | ||
190 | struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ]; | 194 | struct conn_scan_ch_params channels_2[MAX_CHANNELS_2GHZ]; |
191 | struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ]; | 195 | struct conn_scan_ch_params channels_5[MAX_CHANNELS_5GHZ]; |
@@ -212,21 +216,24 @@ struct wl1271_cmd_sched_scan_ssid_list { | |||
212 | 216 | ||
213 | u8 n_ssids; | 217 | u8 n_ssids; |
214 | struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS]; | 218 | struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS]; |
215 | u8 padding[3]; | 219 | u8 role_id; |
220 | u8 padding[2]; | ||
216 | } __packed; | 221 | } __packed; |
217 | 222 | ||
218 | struct wl1271_cmd_sched_scan_start { | 223 | struct wl1271_cmd_sched_scan_start { |
219 | struct wl1271_cmd_header header; | 224 | struct wl1271_cmd_header header; |
220 | 225 | ||
221 | u8 tag; | 226 | u8 tag; |
222 | u8 padding[3]; | 227 | u8 role_id; |
228 | u8 padding[2]; | ||
223 | } __packed; | 229 | } __packed; |
224 | 230 | ||
225 | struct wl1271_cmd_sched_scan_stop { | 231 | struct wl1271_cmd_sched_scan_stop { |
226 | struct wl1271_cmd_header header; | 232 | struct wl1271_cmd_header header; |
227 | 233 | ||
228 | u8 tag; | 234 | u8 tag; |
229 | u8 padding[3]; | 235 | u8 role_id; |
236 | u8 padding[2]; | ||
230 | } __packed; | 237 | } __packed; |
231 | 238 | ||
232 | 239 | ||
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 0a72347cfc4c..c67ec482e445 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/mmc/sdio.h> | ||
28 | #include <linux/mmc/sdio_func.h> | 29 | #include <linux/mmc/sdio_func.h> |
29 | #include <linux/mmc/sdio_ids.h> | 30 | #include <linux/mmc/sdio_ids.h> |
30 | #include <linux/mmc/card.h> | 31 | #include <linux/mmc/card.h> |
@@ -32,6 +33,7 @@ | |||
32 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
33 | #include <linux/wl12xx.h> | 34 | #include <linux/wl12xx.h> |
34 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
36 | #include <linux/printk.h> | ||
35 | 37 | ||
36 | #include "wlcore.h" | 38 | #include "wlcore.h" |
37 | #include "wl12xx_80211.h" | 39 | #include "wl12xx_80211.h" |
@@ -45,6 +47,8 @@ | |||
45 | #define SDIO_DEVICE_ID_TI_WL1271 0x4076 | 47 | #define SDIO_DEVICE_ID_TI_WL1271 0x4076 |
46 | #endif | 48 | #endif |
47 | 49 | ||
50 | static bool dump = false; | ||
51 | |||
48 | struct wl12xx_sdio_glue { | 52 | struct wl12xx_sdio_glue { |
49 | struct device *dev; | 53 | struct device *dev; |
50 | struct platform_device *core; | 54 | struct platform_device *core; |
@@ -76,6 +80,13 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, | |||
76 | 80 | ||
77 | sdio_claim_host(func); | 81 | sdio_claim_host(func); |
78 | 82 | ||
83 | if (unlikely(dump)) { | ||
84 | printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr); | ||
85 | print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ", | ||
86 | DUMP_PREFIX_OFFSET, 16, 1, | ||
87 | buf, len, false); | ||
88 | } | ||
89 | |||
79 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { | 90 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { |
80 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); | 91 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); |
81 | dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", | 92 | dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", |
@@ -105,6 +116,13 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, | |||
105 | 116 | ||
106 | sdio_claim_host(func); | 117 | sdio_claim_host(func); |
107 | 118 | ||
119 | if (unlikely(dump)) { | ||
120 | printk(KERN_DEBUG "wlcore_sdio: WRITE to 0x%04x\n", addr); | ||
121 | print_hex_dump(KERN_DEBUG, "wlcore_sdio: WRITE ", | ||
122 | DUMP_PREFIX_OFFSET, 16, 1, | ||
123 | buf, len, false); | ||
124 | } | ||
125 | |||
108 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { | 126 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { |
109 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); | 127 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); |
110 | dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", | 128 | dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", |
@@ -196,6 +214,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
196 | struct resource res[1]; | 214 | struct resource res[1]; |
197 | mmc_pm_flag_t mmcflags; | 215 | mmc_pm_flag_t mmcflags; |
198 | int ret = -ENOMEM; | 216 | int ret = -ENOMEM; |
217 | const char *chip_family; | ||
199 | 218 | ||
200 | /* We are only able to handle the wlan function */ | 219 | /* We are only able to handle the wlan function */ |
201 | if (func->num != 0x02) | 220 | if (func->num != 0x02) |
@@ -236,7 +255,18 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
236 | /* Tell PM core that we don't need the card to be powered now */ | 255 | /* Tell PM core that we don't need the card to be powered now */ |
237 | pm_runtime_put_noidle(&func->dev); | 256 | pm_runtime_put_noidle(&func->dev); |
238 | 257 | ||
239 | glue->core = platform_device_alloc("wl12xx", -1); | 258 | /* |
259 | * Due to a hardware bug, we can't differentiate wl18xx from | ||
260 | * wl12xx, because both report the same device ID. The only | ||
261 | * way to differentiate is by checking the SDIO revision, | ||
262 | * which is 3.00 on the wl18xx chips. | ||
263 | */ | ||
264 | if (func->card->cccr.sdio_vsn == SDIO_SDIO_REV_3_00) | ||
265 | chip_family = "wl18xx"; | ||
266 | else | ||
267 | chip_family = "wl12xx"; | ||
268 | |||
269 | glue->core = platform_device_alloc(chip_family, -1); | ||
240 | if (!glue->core) { | 270 | if (!glue->core) { |
241 | dev_err(glue->dev, "can't allocate platform_device"); | 271 | dev_err(glue->dev, "can't allocate platform_device"); |
242 | ret = -ENOMEM; | 272 | ret = -ENOMEM; |
@@ -367,6 +397,9 @@ static void __exit wl1271_exit(void) | |||
367 | module_init(wl1271_init); | 397 | module_init(wl1271_init); |
368 | module_exit(wl1271_exit); | 398 | module_exit(wl1271_exit); |
369 | 399 | ||
400 | module_param(dump, bool, S_IRUSR | S_IWUSR); | ||
401 | MODULE_PARM_DESC(dump, "Enable sdio read/write dumps."); | ||
402 | |||
370 | MODULE_LICENSE("GPL"); | 403 | MODULE_LICENSE("GPL"); |
371 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); | 404 | MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); |
372 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); | 405 | MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 6893bc207994..9273fdb3aaec 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c | |||
@@ -72,7 +72,7 @@ static int wl1271_alloc_tx_id(struct wl1271 *wl, struct sk_buff *skb) | |||
72 | return id; | 72 | return id; |
73 | } | 73 | } |
74 | 74 | ||
75 | static void wl1271_free_tx_id(struct wl1271 *wl, int id) | 75 | void wl1271_free_tx_id(struct wl1271 *wl, int id) |
76 | { | 76 | { |
77 | if (__test_and_clear_bit(id, wl->tx_frames_map)) { | 77 | if (__test_and_clear_bit(id, wl->tx_frames_map)) { |
78 | if (unlikely(wl->tx_frames_cnt == wl->num_tx_desc)) | 78 | if (unlikely(wl->tx_frames_cnt == wl->num_tx_desc)) |
@@ -82,6 +82,7 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id) | |||
82 | wl->tx_frames_cnt--; | 82 | wl->tx_frames_cnt--; |
83 | } | 83 | } |
84 | } | 84 | } |
85 | EXPORT_SYMBOL(wl1271_free_tx_id); | ||
85 | 86 | ||
86 | static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, | 87 | static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, |
87 | struct sk_buff *skb) | 88 | struct sk_buff *skb) |
@@ -127,6 +128,7 @@ bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb) | |||
127 | { | 128 | { |
128 | return wl->dummy_packet == skb; | 129 | return wl->dummy_packet == skb; |
129 | } | 130 | } |
131 | EXPORT_SYMBOL(wl12xx_is_dummy_packet); | ||
130 | 132 | ||
131 | u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 133 | u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
132 | struct sk_buff *skb) | 134 | struct sk_buff *skb) |
@@ -146,10 +148,10 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
146 | return wl->system_hlid; | 148 | return wl->system_hlid; |
147 | 149 | ||
148 | hdr = (struct ieee80211_hdr *)skb->data; | 150 | hdr = (struct ieee80211_hdr *)skb->data; |
149 | if (ieee80211_is_mgmt(hdr->frame_control)) | 151 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) |
150 | return wlvif->ap.global_hlid; | ||
151 | else | ||
152 | return wlvif->ap.bcast_hlid; | 152 | return wlvif->ap.bcast_hlid; |
153 | else | ||
154 | return wlvif->ap.global_hlid; | ||
153 | } | 155 | } |
154 | } | 156 | } |
155 | 157 | ||
@@ -176,37 +178,34 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
176 | unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, | 178 | unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, |
177 | unsigned int packet_length) | 179 | unsigned int packet_length) |
178 | { | 180 | { |
179 | if (wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN) | 181 | if ((wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) || |
180 | return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); | 182 | !(wl->quirks & WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN)) |
181 | else | ||
182 | return ALIGN(packet_length, WL1271_TX_ALIGN_TO); | 183 | return ALIGN(packet_length, WL1271_TX_ALIGN_TO); |
184 | else | ||
185 | return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); | ||
183 | } | 186 | } |
184 | EXPORT_SYMBOL(wlcore_calc_packet_alignment); | 187 | EXPORT_SYMBOL(wlcore_calc_packet_alignment); |
185 | 188 | ||
186 | static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | 189 | static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, |
187 | struct sk_buff *skb, u32 extra, u32 buf_offset, | 190 | struct sk_buff *skb, u32 extra, u32 buf_offset, |
188 | u8 hlid) | 191 | u8 hlid, bool is_gem) |
189 | { | 192 | { |
190 | struct wl1271_tx_hw_descr *desc; | 193 | struct wl1271_tx_hw_descr *desc; |
191 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; | 194 | u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; |
192 | u32 total_blocks; | 195 | u32 total_blocks; |
193 | int id, ret = -EBUSY, ac; | 196 | int id, ret = -EBUSY, ac; |
194 | u32 spare_blocks = wl->normal_tx_spare; | 197 | u32 spare_blocks; |
195 | bool is_dummy = false; | ||
196 | 198 | ||
197 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) | 199 | if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) |
198 | return -EAGAIN; | 200 | return -EAGAIN; |
199 | 201 | ||
202 | spare_blocks = wlcore_hw_get_spare_blocks(wl, is_gem); | ||
203 | |||
200 | /* allocate free identifier for the packet */ | 204 | /* allocate free identifier for the packet */ |
201 | id = wl1271_alloc_tx_id(wl, skb); | 205 | id = wl1271_alloc_tx_id(wl, skb); |
202 | if (id < 0) | 206 | if (id < 0) |
203 | return id; | 207 | return id; |
204 | 208 | ||
205 | if (unlikely(wl12xx_is_dummy_packet(wl, skb))) | ||
206 | is_dummy = true; | ||
207 | else if (wlvif->is_gem) | ||
208 | spare_blocks = wl->gem_tx_spare; | ||
209 | |||
210 | total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); | 209 | total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); |
211 | 210 | ||
212 | if (total_blocks <= wl->tx_blocks_available) { | 211 | if (total_blocks <= wl->tx_blocks_available) { |
@@ -228,7 +227,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
228 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | 227 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
229 | wl->tx_allocated_pkts[ac]++; | 228 | wl->tx_allocated_pkts[ac]++; |
230 | 229 | ||
231 | if (!is_dummy && wlvif && | 230 | if (!wl12xx_is_dummy_packet(wl, skb) && wlvif && |
232 | wlvif->bss_type == BSS_TYPE_AP_BSS && | 231 | wlvif->bss_type == BSS_TYPE_AP_BSS && |
233 | test_bit(hlid, wlvif->ap.sta_hlid_map)) | 232 | test_bit(hlid, wlvif->ap.sta_hlid_map)) |
234 | wl->links[hlid].allocated_pkts++; | 233 | wl->links[hlid].allocated_pkts++; |
@@ -268,6 +267,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
268 | if (extra) { | 267 | if (extra) { |
269 | int hdrlen = ieee80211_hdrlen(frame_control); | 268 | int hdrlen = ieee80211_hdrlen(frame_control); |
270 | memmove(frame_start, hdr, hdrlen); | 269 | memmove(frame_start, hdr, hdrlen); |
270 | skb_set_network_header(skb, skb_network_offset(skb) + extra); | ||
271 | } | 271 | } |
272 | 272 | ||
273 | /* configure packet life time */ | 273 | /* configure packet life time */ |
@@ -330,9 +330,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
330 | ieee80211_has_protected(frame_control)) | 330 | ieee80211_has_protected(frame_control)) |
331 | tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; | 331 | tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; |
332 | 332 | ||
333 | desc->reserved = 0; | ||
334 | desc->tx_attr = cpu_to_le16(tx_attr); | 333 | desc->tx_attr = cpu_to_le16(tx_attr); |
335 | 334 | ||
335 | wlcore_hw_set_tx_desc_csum(wl, desc, skb); | ||
336 | wlcore_hw_set_tx_desc_data_len(wl, desc, skb); | 336 | wlcore_hw_set_tx_desc_data_len(wl, desc, skb); |
337 | } | 337 | } |
338 | 338 | ||
@@ -346,6 +346,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
346 | u32 total_len; | 346 | u32 total_len; |
347 | u8 hlid; | 347 | u8 hlid; |
348 | bool is_dummy; | 348 | bool is_dummy; |
349 | bool is_gem = false; | ||
349 | 350 | ||
350 | if (!skb) | 351 | if (!skb) |
351 | return -EINVAL; | 352 | return -EINVAL; |
@@ -355,7 +356,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
355 | /* TODO: handle dummy packets on multi-vifs */ | 356 | /* TODO: handle dummy packets on multi-vifs */ |
356 | is_dummy = wl12xx_is_dummy_packet(wl, skb); | 357 | is_dummy = wl12xx_is_dummy_packet(wl, skb); |
357 | 358 | ||
358 | if (info->control.hw_key && | 359 | if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && |
360 | info->control.hw_key && | ||
359 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) | 361 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) |
360 | extra = WL1271_EXTRA_SPACE_TKIP; | 362 | extra = WL1271_EXTRA_SPACE_TKIP; |
361 | 363 | ||
@@ -373,6 +375,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
373 | return ret; | 375 | return ret; |
374 | wlvif->default_key = idx; | 376 | wlvif->default_key = idx; |
375 | } | 377 | } |
378 | |||
379 | is_gem = (cipher == WL1271_CIPHER_SUITE_GEM); | ||
376 | } | 380 | } |
377 | hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); | 381 | hlid = wl12xx_tx_get_hlid(wl, wlvif, skb); |
378 | if (hlid == WL12XX_INVALID_LINK_ID) { | 382 | if (hlid == WL12XX_INVALID_LINK_ID) { |
@@ -380,7 +384,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
380 | return -EINVAL; | 384 | return -EINVAL; |
381 | } | 385 | } |
382 | 386 | ||
383 | ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid); | 387 | ret = wl1271_tx_allocate(wl, wlvif, skb, extra, buf_offset, hlid, |
388 | is_gem); | ||
384 | if (ret < 0) | 389 | if (ret < 0) |
385 | return ret; | 390 | return ret; |
386 | 391 | ||
@@ -425,10 +430,10 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, | |||
425 | rate_set >>= 1; | 430 | rate_set >>= 1; |
426 | } | 431 | } |
427 | 432 | ||
428 | /* MCS rates indication are on bits 16 - 23 */ | 433 | /* MCS rates indication are on bits 16 - 31 */ |
429 | rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; | 434 | rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates; |
430 | 435 | ||
431 | for (bit = 0; bit < 8; bit++) { | 436 | for (bit = 0; bit < 16; bit++) { |
432 | if (rate_set & 0x1) | 437 | if (rate_set & 0x1) |
433 | enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); | 438 | enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit); |
434 | rate_set >>= 1; | 439 | rate_set >>= 1; |
@@ -439,18 +444,15 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, | |||
439 | 444 | ||
440 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl) | 445 | void wl1271_handle_tx_low_watermark(struct wl1271 *wl) |
441 | { | 446 | { |
442 | unsigned long flags; | ||
443 | int i; | 447 | int i; |
444 | 448 | ||
445 | for (i = 0; i < NUM_TX_QUEUES; i++) { | 449 | for (i = 0; i < NUM_TX_QUEUES; i++) { |
446 | if (test_bit(i, &wl->stopped_queues_map) && | 450 | if (wlcore_is_queue_stopped_by_reason(wl, i, |
451 | WLCORE_QUEUE_STOP_REASON_WATERMARK) && | ||
447 | wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) { | 452 | wl->tx_queue_count[i] <= WL1271_TX_QUEUE_LOW_WATERMARK) { |
448 | /* firmware buffer has space, restart queues */ | 453 | /* firmware buffer has space, restart queues */ |
449 | spin_lock_irqsave(&wl->wl_lock, flags); | 454 | wlcore_wake_queue(wl, i, |
450 | ieee80211_wake_queue(wl->hw, | 455 | WLCORE_QUEUE_STOP_REASON_WATERMARK); |
451 | wl1271_tx_get_mac80211_queue(i)); | ||
452 | clear_bit(i, &wl->stopped_queues_map); | ||
453 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
454 | } | 456 | } |
455 | } | 457 | } |
456 | } | 458 | } |
@@ -661,7 +663,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
661 | struct wl12xx_vif *wlvif; | 663 | struct wl12xx_vif *wlvif; |
662 | struct sk_buff *skb; | 664 | struct sk_buff *skb; |
663 | struct wl1271_tx_hw_descr *desc; | 665 | struct wl1271_tx_hw_descr *desc; |
664 | u32 buf_offset = 0; | 666 | u32 buf_offset = 0, last_len = 0; |
665 | bool sent_packets = false; | 667 | bool sent_packets = false; |
666 | unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; | 668 | unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; |
667 | int ret; | 669 | int ret; |
@@ -685,6 +687,9 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
685 | * Flush buffer and try again. | 687 | * Flush buffer and try again. |
686 | */ | 688 | */ |
687 | wl1271_skb_queue_head(wl, wlvif, skb); | 689 | wl1271_skb_queue_head(wl, wlvif, skb); |
690 | |||
691 | buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, | ||
692 | last_len); | ||
688 | wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, | 693 | wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, |
689 | buf_offset, true); | 694 | buf_offset, true); |
690 | sent_packets = true; | 695 | sent_packets = true; |
@@ -710,7 +715,8 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
710 | ieee80211_free_txskb(wl->hw, skb); | 715 | ieee80211_free_txskb(wl->hw, skb); |
711 | goto out_ack; | 716 | goto out_ack; |
712 | } | 717 | } |
713 | buf_offset += ret; | 718 | last_len = ret; |
719 | buf_offset += last_len; | ||
714 | wl->tx_packets_count++; | 720 | wl->tx_packets_count++; |
715 | if (has_data) { | 721 | if (has_data) { |
716 | desc = (struct wl1271_tx_hw_descr *) skb->data; | 722 | desc = (struct wl1271_tx_hw_descr *) skb->data; |
@@ -720,6 +726,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
720 | 726 | ||
721 | out_ack: | 727 | out_ack: |
722 | if (buf_offset) { | 728 | if (buf_offset) { |
729 | buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); | ||
723 | wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, | 730 | wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, |
724 | buf_offset, true); | 731 | buf_offset, true); |
725 | sent_packets = true; | 732 | sent_packets = true; |
@@ -849,7 +856,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
849 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | 856 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); |
850 | 857 | ||
851 | /* remove TKIP header space if present */ | 858 | /* remove TKIP header space if present */ |
852 | if (info->control.hw_key && | 859 | if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && |
860 | info->control.hw_key && | ||
853 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { | 861 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { |
854 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 862 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
855 | memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, | 863 | memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, |
@@ -871,8 +879,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
871 | /* Called upon reception of a TX complete interrupt */ | 879 | /* Called upon reception of a TX complete interrupt */ |
872 | void wl1271_tx_complete(struct wl1271 *wl) | 880 | void wl1271_tx_complete(struct wl1271 *wl) |
873 | { | 881 | { |
874 | struct wl1271_acx_mem_map *memmap = | 882 | struct wl1271_acx_mem_map *memmap = wl->target_mem_map; |
875 | (struct wl1271_acx_mem_map *)wl->target_mem_map; | ||
876 | u32 count, fw_counter; | 883 | u32 count, fw_counter; |
877 | u32 i; | 884 | u32 i; |
878 | 885 | ||
@@ -958,7 +965,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
958 | 965 | ||
959 | } | 966 | } |
960 | /* caller must hold wl->mutex and TX must be stopped */ | 967 | /* caller must hold wl->mutex and TX must be stopped */ |
961 | void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | 968 | void wl12xx_tx_reset(struct wl1271 *wl) |
962 | { | 969 | { |
963 | int i; | 970 | int i; |
964 | struct sk_buff *skb; | 971 | struct sk_buff *skb; |
@@ -973,15 +980,12 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
973 | wl->tx_queue_count[i] = 0; | 980 | wl->tx_queue_count[i] = 0; |
974 | } | 981 | } |
975 | 982 | ||
976 | wl->stopped_queues_map = 0; | ||
977 | |||
978 | /* | 983 | /* |
979 | * Make sure the driver is at a consistent state, in case this | 984 | * Make sure the driver is at a consistent state, in case this |
980 | * function is called from a context other than interface removal. | 985 | * function is called from a context other than interface removal. |
981 | * This call will always wake the TX queues. | 986 | * This call will always wake the TX queues. |
982 | */ | 987 | */ |
983 | if (reset_tx_queues) | 988 | wl1271_handle_tx_low_watermark(wl); |
984 | wl1271_handle_tx_low_watermark(wl); | ||
985 | 989 | ||
986 | for (i = 0; i < wl->num_tx_desc; i++) { | 990 | for (i = 0; i < wl->num_tx_desc; i++) { |
987 | if (wl->tx_frames[i] == NULL) | 991 | if (wl->tx_frames[i] == NULL) |
@@ -998,7 +1002,8 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) | |||
998 | */ | 1002 | */ |
999 | info = IEEE80211_SKB_CB(skb); | 1003 | info = IEEE80211_SKB_CB(skb); |
1000 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | 1004 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); |
1001 | if (info->control.hw_key && | 1005 | if ((wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE) && |
1006 | info->control.hw_key && | ||
1002 | info->control.hw_key->cipher == | 1007 | info->control.hw_key->cipher == |
1003 | WLAN_CIPHER_SUITE_TKIP) { | 1008 | WLAN_CIPHER_SUITE_TKIP) { |
1004 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1009 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
@@ -1024,6 +1029,11 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
1024 | int i; | 1029 | int i; |
1025 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); | 1030 | timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); |
1026 | 1031 | ||
1032 | /* only one flush should be in progress, for consistent queue state */ | ||
1033 | mutex_lock(&wl->flush_mutex); | ||
1034 | |||
1035 | wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); | ||
1036 | |||
1027 | while (!time_after(jiffies, timeout)) { | 1037 | while (!time_after(jiffies, timeout)) { |
1028 | mutex_lock(&wl->mutex); | 1038 | mutex_lock(&wl->mutex); |
1029 | wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", | 1039 | wl1271_debug(DEBUG_TX, "flushing tx buffer: %d %d", |
@@ -1032,7 +1042,7 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
1032 | if ((wl->tx_frames_cnt == 0) && | 1042 | if ((wl->tx_frames_cnt == 0) && |
1033 | (wl1271_tx_total_queue_count(wl) == 0)) { | 1043 | (wl1271_tx_total_queue_count(wl) == 0)) { |
1034 | mutex_unlock(&wl->mutex); | 1044 | mutex_unlock(&wl->mutex); |
1035 | return; | 1045 | goto out; |
1036 | } | 1046 | } |
1037 | mutex_unlock(&wl->mutex); | 1047 | mutex_unlock(&wl->mutex); |
1038 | msleep(1); | 1048 | msleep(1); |
@@ -1045,7 +1055,12 @@ void wl1271_tx_flush(struct wl1271 *wl) | |||
1045 | for (i = 0; i < WL12XX_MAX_LINKS; i++) | 1055 | for (i = 0; i < WL12XX_MAX_LINKS; i++) |
1046 | wl1271_tx_reset_link_queues(wl, i); | 1056 | wl1271_tx_reset_link_queues(wl, i); |
1047 | mutex_unlock(&wl->mutex); | 1057 | mutex_unlock(&wl->mutex); |
1058 | |||
1059 | out: | ||
1060 | wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FLUSH); | ||
1061 | mutex_unlock(&wl->flush_mutex); | ||
1048 | } | 1062 | } |
1063 | EXPORT_SYMBOL_GPL(wl1271_tx_flush); | ||
1049 | 1064 | ||
1050 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) | 1065 | u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) |
1051 | { | 1066 | { |
@@ -1054,3 +1069,96 @@ u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) | |||
1054 | 1069 | ||
1055 | return BIT(__ffs(rate_set)); | 1070 | return BIT(__ffs(rate_set)); |
1056 | } | 1071 | } |
1072 | |||
1073 | void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, | ||
1074 | enum wlcore_queue_stop_reason reason) | ||
1075 | { | ||
1076 | bool stopped = !!wl->queue_stop_reasons[queue]; | ||
1077 | |||
1078 | /* queue should not be stopped for this reason */ | ||
1079 | WARN_ON(test_and_set_bit(reason, &wl->queue_stop_reasons[queue])); | ||
1080 | |||
1081 | if (stopped) | ||
1082 | return; | ||
1083 | |||
1084 | ieee80211_stop_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); | ||
1085 | } | ||
1086 | |||
1087 | void wlcore_stop_queue(struct wl1271 *wl, u8 queue, | ||
1088 | enum wlcore_queue_stop_reason reason) | ||
1089 | { | ||
1090 | unsigned long flags; | ||
1091 | |||
1092 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
1093 | wlcore_stop_queue_locked(wl, queue, reason); | ||
1094 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1095 | } | ||
1096 | |||
1097 | void wlcore_wake_queue(struct wl1271 *wl, u8 queue, | ||
1098 | enum wlcore_queue_stop_reason reason) | ||
1099 | { | ||
1100 | unsigned long flags; | ||
1101 | |||
1102 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
1103 | |||
1104 | /* queue should not be clear for this reason */ | ||
1105 | WARN_ON(!test_and_clear_bit(reason, &wl->queue_stop_reasons[queue])); | ||
1106 | |||
1107 | if (wl->queue_stop_reasons[queue]) | ||
1108 | goto out; | ||
1109 | |||
1110 | ieee80211_wake_queue(wl->hw, wl1271_tx_get_mac80211_queue(queue)); | ||
1111 | |||
1112 | out: | ||
1113 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1114 | } | ||
1115 | |||
1116 | void wlcore_stop_queues(struct wl1271 *wl, | ||
1117 | enum wlcore_queue_stop_reason reason) | ||
1118 | { | ||
1119 | int i; | ||
1120 | |||
1121 | for (i = 0; i < NUM_TX_QUEUES; i++) | ||
1122 | wlcore_stop_queue(wl, i, reason); | ||
1123 | } | ||
1124 | EXPORT_SYMBOL_GPL(wlcore_stop_queues); | ||
1125 | |||
1126 | void wlcore_wake_queues(struct wl1271 *wl, | ||
1127 | enum wlcore_queue_stop_reason reason) | ||
1128 | { | ||
1129 | int i; | ||
1130 | |||
1131 | for (i = 0; i < NUM_TX_QUEUES; i++) | ||
1132 | wlcore_wake_queue(wl, i, reason); | ||
1133 | } | ||
1134 | EXPORT_SYMBOL_GPL(wlcore_wake_queues); | ||
1135 | |||
1136 | void wlcore_reset_stopped_queues(struct wl1271 *wl) | ||
1137 | { | ||
1138 | int i; | ||
1139 | unsigned long flags; | ||
1140 | |||
1141 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
1142 | |||
1143 | for (i = 0; i < NUM_TX_QUEUES; i++) { | ||
1144 | if (!wl->queue_stop_reasons[i]) | ||
1145 | continue; | ||
1146 | |||
1147 | wl->queue_stop_reasons[i] = 0; | ||
1148 | ieee80211_wake_queue(wl->hw, | ||
1149 | wl1271_tx_get_mac80211_queue(i)); | ||
1150 | } | ||
1151 | |||
1152 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1153 | } | ||
1154 | |||
1155 | bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, | ||
1156 | enum wlcore_queue_stop_reason reason) | ||
1157 | { | ||
1158 | return test_bit(reason, &wl->queue_stop_reasons[queue]); | ||
1159 | } | ||
1160 | |||
1161 | bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue) | ||
1162 | { | ||
1163 | return !!wl->queue_stop_reasons[queue]; | ||
1164 | } | ||
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 2fd6e5dc6f75..fa4be1b91135 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h | |||
@@ -85,6 +85,19 @@ struct wl128x_tx_mem { | |||
85 | u8 extra_bytes; | 85 | u8 extra_bytes; |
86 | } __packed; | 86 | } __packed; |
87 | 87 | ||
88 | struct wl18xx_tx_mem { | ||
89 | /* | ||
90 | * Total number of memory blocks allocated by the host for | ||
91 | * this packet. | ||
92 | */ | ||
93 | u8 total_mem_blocks; | ||
94 | |||
95 | /* | ||
96 | * control bits | ||
97 | */ | ||
98 | u8 ctrl; | ||
99 | } __packed; | ||
100 | |||
88 | /* | 101 | /* |
89 | * On wl128x based devices, when TX packets are aggregated, each packet | 102 | * On wl128x based devices, when TX packets are aggregated, each packet |
90 | * size must be aligned to the SDIO block size. The maximum block size | 103 | * size must be aligned to the SDIO block size. The maximum block size |
@@ -100,6 +113,7 @@ struct wl1271_tx_hw_descr { | |||
100 | union { | 113 | union { |
101 | struct wl127x_tx_mem wl127x_mem; | 114 | struct wl127x_tx_mem wl127x_mem; |
102 | struct wl128x_tx_mem wl128x_mem; | 115 | struct wl128x_tx_mem wl128x_mem; |
116 | struct wl18xx_tx_mem wl18xx_mem; | ||
103 | } __packed; | 117 | } __packed; |
104 | /* Device time (in us) when the packet arrived to the driver */ | 118 | /* Device time (in us) when the packet arrived to the driver */ |
105 | __le32 start_time; | 119 | __le32 start_time; |
@@ -116,7 +130,16 @@ struct wl1271_tx_hw_descr { | |||
116 | u8 tid; | 130 | u8 tid; |
117 | /* host link ID (HLID) */ | 131 | /* host link ID (HLID) */ |
118 | u8 hlid; | 132 | u8 hlid; |
119 | u8 reserved; | 133 | |
134 | union { | ||
135 | u8 wl12xx_reserved; | ||
136 | |||
137 | /* | ||
138 | * bit 0 -> 0 = udp, 1 = tcp | ||
139 | * bit 1:7 -> IP header offset | ||
140 | */ | ||
141 | u8 wl18xx_checksum_data; | ||
142 | } __packed; | ||
120 | } __packed; | 143 | } __packed; |
121 | 144 | ||
122 | enum wl1271_tx_hw_res_status { | 145 | enum wl1271_tx_hw_res_status { |
@@ -161,6 +184,13 @@ struct wl1271_tx_hw_res_if { | |||
161 | struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; | 184 | struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; |
162 | } __packed; | 185 | } __packed; |
163 | 186 | ||
187 | enum wlcore_queue_stop_reason { | ||
188 | WLCORE_QUEUE_STOP_REASON_WATERMARK, | ||
189 | WLCORE_QUEUE_STOP_REASON_FW_RESTART, | ||
190 | WLCORE_QUEUE_STOP_REASON_FLUSH, | ||
191 | WLCORE_QUEUE_STOP_REASON_SPARE_BLK, /* 18xx specific */ | ||
192 | }; | ||
193 | |||
164 | static inline int wl1271_tx_get_queue(int queue) | 194 | static inline int wl1271_tx_get_queue(int queue) |
165 | { | 195 | { |
166 | switch (queue) { | 196 | switch (queue) { |
@@ -207,7 +237,7 @@ void wl1271_tx_work(struct work_struct *work); | |||
207 | void wl1271_tx_work_locked(struct wl1271 *wl); | 237 | void wl1271_tx_work_locked(struct wl1271 *wl); |
208 | void wl1271_tx_complete(struct wl1271 *wl); | 238 | void wl1271_tx_complete(struct wl1271 *wl); |
209 | void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 239 | void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
210 | void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues); | 240 | void wl12xx_tx_reset(struct wl1271 *wl); |
211 | void wl1271_tx_flush(struct wl1271 *wl); | 241 | void wl1271_tx_flush(struct wl1271 *wl); |
212 | u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band); | 242 | u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum ieee80211_band band); |
213 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, | 243 | u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set, |
@@ -223,6 +253,21 @@ bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb); | |||
223 | void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); | 253 | void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); |
224 | unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, | 254 | unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl, |
225 | unsigned int packet_length); | 255 | unsigned int packet_length); |
256 | void wl1271_free_tx_id(struct wl1271 *wl, int id); | ||
257 | void wlcore_stop_queue_locked(struct wl1271 *wl, u8 queue, | ||
258 | enum wlcore_queue_stop_reason reason); | ||
259 | void wlcore_stop_queue(struct wl1271 *wl, u8 queue, | ||
260 | enum wlcore_queue_stop_reason reason); | ||
261 | void wlcore_wake_queue(struct wl1271 *wl, u8 queue, | ||
262 | enum wlcore_queue_stop_reason reason); | ||
263 | void wlcore_stop_queues(struct wl1271 *wl, | ||
264 | enum wlcore_queue_stop_reason reason); | ||
265 | void wlcore_wake_queues(struct wl1271 *wl, | ||
266 | enum wlcore_queue_stop_reason reason); | ||
267 | void wlcore_reset_stopped_queues(struct wl1271 *wl); | ||
268 | bool wlcore_is_queue_stopped_by_reason(struct wl1271 *wl, u8 queue, | ||
269 | enum wlcore_queue_stop_reason reason); | ||
270 | bool wlcore_is_queue_stopped(struct wl1271 *wl, u8 queue); | ||
226 | 271 | ||
227 | /* from main.c */ | 272 | /* from main.c */ |
228 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); | 273 | void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); |
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 0b3f0b586f4b..761a72f4b8d1 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h | |||
@@ -24,8 +24,9 @@ | |||
24 | 24 | ||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | 26 | ||
27 | #include "wl12xx.h" | 27 | #include "wlcore_i.h" |
28 | #include "event.h" | 28 | #include "event.h" |
29 | #include "boot.h" | ||
29 | 30 | ||
30 | /* The maximum number of Tx descriptors in all chip families */ | 31 | /* The maximum number of Tx descriptors in all chip families */ |
31 | #define WLCORE_MAX_TX_DESCRIPTORS 32 | 32 | #define WLCORE_MAX_TX_DESCRIPTORS 32 |
@@ -33,11 +34,13 @@ | |||
33 | /* forward declaration */ | 34 | /* forward declaration */ |
34 | struct wl1271_tx_hw_descr; | 35 | struct wl1271_tx_hw_descr; |
35 | enum wl_rx_buf_align; | 36 | enum wl_rx_buf_align; |
37 | struct wl1271_rx_descriptor; | ||
36 | 38 | ||
37 | struct wlcore_ops { | 39 | struct wlcore_ops { |
38 | int (*identify_chip)(struct wl1271 *wl); | 40 | int (*identify_chip)(struct wl1271 *wl); |
39 | int (*identify_fw)(struct wl1271 *wl); | 41 | int (*identify_fw)(struct wl1271 *wl); |
40 | int (*boot)(struct wl1271 *wl); | 42 | int (*boot)(struct wl1271 *wl); |
43 | int (*plt_init)(struct wl1271 *wl); | ||
41 | void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, | 44 | void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, |
42 | void *buf, size_t len); | 45 | void *buf, size_t len); |
43 | void (*ack_event)(struct wl1271 *wl); | 46 | void (*ack_event)(struct wl1271 *wl); |
@@ -61,6 +64,23 @@ struct wlcore_ops { | |||
61 | struct wl12xx_vif *wlvif); | 64 | struct wl12xx_vif *wlvif); |
62 | s8 (*get_pg_ver)(struct wl1271 *wl); | 65 | s8 (*get_pg_ver)(struct wl1271 *wl); |
63 | void (*get_mac)(struct wl1271 *wl); | 66 | void (*get_mac)(struct wl1271 *wl); |
67 | void (*set_tx_desc_csum)(struct wl1271 *wl, | ||
68 | struct wl1271_tx_hw_descr *desc, | ||
69 | struct sk_buff *skb); | ||
70 | void (*set_rx_csum)(struct wl1271 *wl, | ||
71 | struct wl1271_rx_descriptor *desc, | ||
72 | struct sk_buff *skb); | ||
73 | u32 (*ap_get_mimo_wide_rate_mask)(struct wl1271 *wl, | ||
74 | struct wl12xx_vif *wlvif); | ||
75 | int (*debugfs_init)(struct wl1271 *wl, struct dentry *rootdir); | ||
76 | int (*handle_static_data)(struct wl1271 *wl, | ||
77 | struct wl1271_static_data *static_data); | ||
78 | int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); | ||
79 | int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, | ||
80 | struct ieee80211_vif *vif, | ||
81 | struct ieee80211_sta *sta, | ||
82 | struct ieee80211_key_conf *key_conf); | ||
83 | u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); | ||
64 | }; | 84 | }; |
65 | 85 | ||
66 | enum wlcore_partitions { | 86 | enum wlcore_partitions { |
@@ -109,6 +129,15 @@ enum wlcore_registers { | |||
109 | REG_TABLE_LEN, | 129 | REG_TABLE_LEN, |
110 | }; | 130 | }; |
111 | 131 | ||
132 | struct wl1271_stats { | ||
133 | void *fw_stats; | ||
134 | unsigned long fw_stats_update; | ||
135 | size_t fw_stats_len; | ||
136 | |||
137 | unsigned int retry_count; | ||
138 | unsigned int excessive_retries; | ||
139 | }; | ||
140 | |||
112 | struct wl1271 { | 141 | struct wl1271 { |
113 | struct ieee80211_hw *hw; | 142 | struct ieee80211_hw *hw; |
114 | bool mac80211_registered; | 143 | bool mac80211_registered; |
@@ -121,7 +150,6 @@ struct wl1271 { | |||
121 | 150 | ||
122 | void (*set_power)(bool enable); | 151 | void (*set_power)(bool enable); |
123 | int irq; | 152 | int irq; |
124 | int ref_clock; | ||
125 | 153 | ||
126 | spinlock_t wl_lock; | 154 | spinlock_t wl_lock; |
127 | 155 | ||
@@ -186,7 +214,7 @@ struct wl1271 { | |||
186 | 214 | ||
187 | /* Frames scheduled for transmission, not handled yet */ | 215 | /* Frames scheduled for transmission, not handled yet */ |
188 | int tx_queue_count[NUM_TX_QUEUES]; | 216 | int tx_queue_count[NUM_TX_QUEUES]; |
189 | long stopped_queues_map; | 217 | unsigned long queue_stop_reasons[NUM_TX_QUEUES]; |
190 | 218 | ||
191 | /* Frames received, not handled yet by mac80211 */ | 219 | /* Frames received, not handled yet by mac80211 */ |
192 | struct sk_buff_head deferred_rx_queue; | 220 | struct sk_buff_head deferred_rx_queue; |
@@ -205,9 +233,6 @@ struct wl1271 { | |||
205 | /* FW Rx counter */ | 233 | /* FW Rx counter */ |
206 | u32 rx_counter; | 234 | u32 rx_counter; |
207 | 235 | ||
208 | /* Rx memory pool address */ | ||
209 | struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; | ||
210 | |||
211 | /* Intermediate buffer, used for packet aggregation */ | 236 | /* Intermediate buffer, used for packet aggregation */ |
212 | u8 *aggr_buf; | 237 | u8 *aggr_buf; |
213 | 238 | ||
@@ -228,6 +253,7 @@ struct wl1271 { | |||
228 | 253 | ||
229 | /* Hardware recovery work */ | 254 | /* Hardware recovery work */ |
230 | struct work_struct recovery_work; | 255 | struct work_struct recovery_work; |
256 | bool watchdog_recovery; | ||
231 | 257 | ||
232 | /* Pointer that holds DMA-friendly block for the mailbox */ | 258 | /* Pointer that holds DMA-friendly block for the mailbox */ |
233 | struct event_mailbox *mbox; | 259 | struct event_mailbox *mbox; |
@@ -263,7 +289,8 @@ struct wl1271 { | |||
263 | u32 buffer_cmd; | 289 | u32 buffer_cmd; |
264 | u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; | 290 | u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; |
265 | 291 | ||
266 | struct wl_fw_status *fw_status; | 292 | struct wl_fw_status_1 *fw_status_1; |
293 | struct wl_fw_status_2 *fw_status_2; | ||
267 | struct wl1271_tx_hw_res_if *tx_res_if; | 294 | struct wl1271_tx_hw_res_if *tx_res_if; |
268 | 295 | ||
269 | /* Current chipset configuration */ | 296 | /* Current chipset configuration */ |
@@ -279,8 +306,6 @@ struct wl1271 { | |||
279 | /* bands supported by this instance of wl12xx */ | 306 | /* bands supported by this instance of wl12xx */ |
280 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; | 307 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
281 | 308 | ||
282 | int tcxo_clock; | ||
283 | |||
284 | /* | 309 | /* |
285 | * wowlan trigger was configured during suspend. | 310 | * wowlan trigger was configured during suspend. |
286 | * (currently, only "ANY" trigger is supported) | 311 | * (currently, only "ANY" trigger is supported) |
@@ -333,10 +358,8 @@ struct wl1271 { | |||
333 | 358 | ||
334 | /* number of TX descriptors the HW supports. */ | 359 | /* number of TX descriptors the HW supports. */ |
335 | u32 num_tx_desc; | 360 | u32 num_tx_desc; |
336 | 361 | /* number of RX descriptors the HW supports. */ | |
337 | /* spare Tx blocks for normal/GEM operating modes */ | 362 | u32 num_rx_desc; |
338 | u32 normal_tx_spare; | ||
339 | u32 gem_tx_spare; | ||
340 | 363 | ||
341 | /* translate HW Tx rates to standard rate-indices */ | 364 | /* translate HW Tx rates to standard rate-indices */ |
342 | const u8 **band_rate_to_idx; | 365 | const u8 **band_rate_to_idx; |
@@ -348,19 +371,32 @@ struct wl1271 { | |||
348 | u8 hw_min_ht_rate; | 371 | u8 hw_min_ht_rate; |
349 | 372 | ||
350 | /* HW HT (11n) capabilities */ | 373 | /* HW HT (11n) capabilities */ |
351 | struct ieee80211_sta_ht_cap ht_cap; | 374 | struct ieee80211_sta_ht_cap ht_cap[IEEE80211_NUM_BANDS]; |
352 | 375 | ||
353 | /* size of the private FW status data */ | 376 | /* size of the private FW status data */ |
354 | size_t fw_status_priv_len; | 377 | size_t fw_status_priv_len; |
355 | 378 | ||
356 | /* RX Data filter rule state - enabled/disabled */ | 379 | /* RX Data filter rule state - enabled/disabled */ |
357 | bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; | 380 | bool rx_filter_enabled[WL1271_MAX_RX_FILTERS]; |
381 | |||
382 | /* size of the private static data */ | ||
383 | size_t static_data_priv_len; | ||
384 | |||
385 | /* the current channel type */ | ||
386 | enum nl80211_channel_type channel_type; | ||
387 | |||
388 | /* mutex for protecting the tx_flush function */ | ||
389 | struct mutex flush_mutex; | ||
358 | }; | 390 | }; |
359 | 391 | ||
360 | int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); | 392 | int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); |
361 | int __devexit wlcore_remove(struct platform_device *pdev); | 393 | int __devexit wlcore_remove(struct platform_device *pdev); |
362 | struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); | 394 | struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size); |
363 | int wlcore_free_hw(struct wl1271 *wl); | 395 | int wlcore_free_hw(struct wl1271 *wl); |
396 | int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, | ||
397 | struct ieee80211_vif *vif, | ||
398 | struct ieee80211_sta *sta, | ||
399 | struct ieee80211_key_conf *key_conf); | ||
364 | 400 | ||
365 | /* Firmware image load chunk size */ | 401 | /* Firmware image load chunk size */ |
366 | #define CHUNK_SIZE 16384 | 402 | #define CHUNK_SIZE 16384 |
@@ -385,6 +421,12 @@ int wlcore_free_hw(struct wl1271 *wl); | |||
385 | /* Some firmwares may not support ELP */ | 421 | /* Some firmwares may not support ELP */ |
386 | #define WLCORE_QUIRK_NO_ELP BIT(6) | 422 | #define WLCORE_QUIRK_NO_ELP BIT(6) |
387 | 423 | ||
424 | /* pad only the last frame in the aggregate buffer */ | ||
425 | #define WLCORE_QUIRK_TX_PAD_LAST_FRAME BIT(7) | ||
426 | |||
427 | /* extra header space is required for TKIP */ | ||
428 | #define WLCORE_QUIRK_TKIP_HEADER_SPACE BIT(8) | ||
429 | |||
388 | /* TODO: move to the lower drivers when all usages are abstracted */ | 430 | /* TODO: move to the lower drivers when all usages are abstracted */ |
389 | #define CHIP_ID_1271_PG10 (0x4030101) | 431 | #define CHIP_ID_1271_PG10 (0x4030101) |
390 | #define CHIP_ID_1271_PG20 (0x4030111) | 432 | #define CHIP_ID_1271_PG20 (0x4030111) |
diff --git a/drivers/net/wireless/ti/wlcore/wl12xx.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index f12bdf745180..8260b1e9288a 100644 --- a/drivers/net/wireless/ti/wlcore/wl12xx.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h | |||
@@ -22,8 +22,8 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #ifndef __WL12XX_H__ | 25 | #ifndef __WLCORE_I_H__ |
26 | #define __WL12XX_H__ | 26 | #define __WLCORE_I_H__ |
27 | 27 | ||
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
@@ -89,7 +89,7 @@ | |||
89 | #define WL1271_AP_BSS_INDEX 0 | 89 | #define WL1271_AP_BSS_INDEX 0 |
90 | #define WL1271_AP_DEF_BEACON_EXP 20 | 90 | #define WL1271_AP_DEF_BEACON_EXP 20 |
91 | 91 | ||
92 | #define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) | 92 | #define WL1271_AGGR_BUFFER_SIZE (5 * PAGE_SIZE) |
93 | 93 | ||
94 | enum wl1271_state { | 94 | enum wl1271_state { |
95 | WL1271_STATE_OFF, | 95 | WL1271_STATE_OFF, |
@@ -132,16 +132,7 @@ struct wl1271_chip { | |||
132 | unsigned int fw_ver[NUM_FW_VER]; | 132 | unsigned int fw_ver[NUM_FW_VER]; |
133 | }; | 133 | }; |
134 | 134 | ||
135 | struct wl1271_stats { | ||
136 | struct acx_statistics *fw_stats; | ||
137 | unsigned long fw_stats_update; | ||
138 | |||
139 | unsigned int retry_count; | ||
140 | unsigned int excessive_retries; | ||
141 | }; | ||
142 | |||
143 | #define NUM_TX_QUEUES 4 | 135 | #define NUM_TX_QUEUES 4 |
144 | #define NUM_RX_PKT_DESC 8 | ||
145 | 136 | ||
146 | #define AP_MAX_STATIONS 8 | 137 | #define AP_MAX_STATIONS 8 |
147 | 138 | ||
@@ -159,13 +150,26 @@ struct wl_fw_packet_counters { | |||
159 | } __packed; | 150 | } __packed; |
160 | 151 | ||
161 | /* FW status registers */ | 152 | /* FW status registers */ |
162 | struct wl_fw_status { | 153 | struct wl_fw_status_1 { |
163 | __le32 intr; | 154 | __le32 intr; |
164 | u8 fw_rx_counter; | 155 | u8 fw_rx_counter; |
165 | u8 drv_rx_counter; | 156 | u8 drv_rx_counter; |
166 | u8 reserved; | 157 | u8 reserved; |
167 | u8 tx_results_counter; | 158 | u8 tx_results_counter; |
168 | __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; | 159 | __le32 rx_pkt_descs[0]; |
160 | } __packed; | ||
161 | |||
162 | /* | ||
163 | * Each HW arch has a different number of Rx descriptors. | ||
164 | * The length of the status depends on it, since it holds an array | ||
165 | * of descriptors. | ||
166 | */ | ||
167 | #define WLCORE_FW_STATUS_1_LEN(num_rx_desc) \ | ||
168 | (sizeof(struct wl_fw_status_1) + \ | ||
169 | (sizeof(((struct wl_fw_status_1 *)0)->rx_pkt_descs[0])) * \ | ||
170 | num_rx_desc) | ||
171 | |||
172 | struct wl_fw_status_2 { | ||
169 | __le32 fw_localtime; | 173 | __le32 fw_localtime; |
170 | 174 | ||
171 | /* | 175 | /* |
@@ -194,11 +198,6 @@ struct wl_fw_status { | |||
194 | u8 priv[0]; | 198 | u8 priv[0]; |
195 | } __packed; | 199 | } __packed; |
196 | 200 | ||
197 | struct wl1271_rx_mem_pool_addr { | ||
198 | u32 addr; | ||
199 | u32 addr_extra; | ||
200 | }; | ||
201 | |||
202 | #define WL1271_MAX_CHANNELS 64 | 201 | #define WL1271_MAX_CHANNELS 64 |
203 | struct wl1271_scan { | 202 | struct wl1271_scan { |
204 | struct cfg80211_scan_request *req; | 203 | struct cfg80211_scan_request *req; |
@@ -367,6 +366,7 @@ struct wl12xx_vif { | |||
367 | /* The current band */ | 366 | /* The current band */ |
368 | enum ieee80211_band band; | 367 | enum ieee80211_band band; |
369 | int channel; | 368 | int channel; |
369 | enum nl80211_channel_type channel_type; | ||
370 | 370 | ||
371 | u32 bitrate_masks[IEEE80211_NUM_BANDS]; | 371 | u32 bitrate_masks[IEEE80211_NUM_BANDS]; |
372 | u32 basic_rate_set; | 372 | u32 basic_rate_set; |
@@ -417,9 +417,6 @@ struct wl12xx_vif { | |||
417 | struct work_struct rx_streaming_disable_work; | 417 | struct work_struct rx_streaming_disable_work; |
418 | struct timer_list rx_streaming_timer; | 418 | struct timer_list rx_streaming_timer; |
419 | 419 | ||
420 | /* does the current role use GEM for encryption (AP or STA) */ | ||
421 | bool is_gem; | ||
422 | |||
423 | /* | 420 | /* |
424 | * This struct must be last! | 421 | * This struct must be last! |
425 | * data that has to be saved acrossed reconfigs (e.g. recovery) | 422 | * data that has to be saved acrossed reconfigs (e.g. recovery) |
@@ -501,7 +498,8 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, | |||
501 | /* Macros to handle wl1271.sta_rate_set */ | 498 | /* Macros to handle wl1271.sta_rate_set */ |
502 | #define HW_BG_RATES_MASK 0xffff | 499 | #define HW_BG_RATES_MASK 0xffff |
503 | #define HW_HT_RATES_OFFSET 16 | 500 | #define HW_HT_RATES_OFFSET 16 |
501 | #define HW_MIMO_RATES_OFFSET 24 | ||
504 | 502 | ||
505 | #define WL12XX_HW_BLOCK_SIZE 256 | 503 | #define WL12XX_HW_BLOCK_SIZE 256 |
506 | 504 | ||
507 | #endif | 505 | #endif /* __WLCORE_I_H__ */ |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 117c4123943c..7ab922209b25 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -827,7 +827,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, | |||
827 | static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value, | 827 | static inline int zd_ioread32_locked(struct zd_chip *chip, u32 *value, |
828 | const zd_addr_t addr) | 828 | const zd_addr_t addr) |
829 | { | 829 | { |
830 | return zd_ioread32v_locked(chip, value, (const zd_addr_t *)&addr, 1); | 830 | return zd_ioread32v_locked(chip, value, &addr, 1); |
831 | } | 831 | } |
832 | 832 | ||
833 | static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value, | 833 | static inline int zd_iowrite16_locked(struct zd_chip *chip, u16 value, |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 99193b456a79..45e3bb28a01c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -274,7 +274,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
274 | static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, | 274 | static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, |
275 | const zd_addr_t addr) | 275 | const zd_addr_t addr) |
276 | { | 276 | { |
277 | return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); | 277 | return zd_usb_ioread16v(usb, value, &addr, 1); |
278 | } | 278 | } |
279 | 279 | ||
280 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb); | 280 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb); |