Staging: comedi: serial2002: fix include build issue
[cascardo/linux.git] / drivers / staging / agnx / xmit.c
1 /**
2  * Airgo MIMO wireless driver
3  *
4  * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6  * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7  * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/pci.h>
15 #include <linux/delay.h>
16 #include "agnx.h"
17 #include "debug.h"
18 #include "phy.h"
19
20 unsigned int rx_frame_cnt;
21 /* unsigned int local_tx_sent_cnt = 0; */
22
23 static inline void disable_rx_engine(struct agnx_priv *priv)
24 {
25         void __iomem *ctl = priv->ctl;
26         iowrite32(0x100, ctl + AGNX_CIR_RXCTL);
27         /* Wait for RX Control to have the Disable Rx Interrupt (0x100) set */
28         ioread32(ctl + AGNX_CIR_RXCTL);
29 }
30
31 static inline void enable_rx_engine(struct agnx_priv *priv)
32 {
33         void __iomem *ctl = priv->ctl;
34         iowrite32(0x80, ctl + AGNX_CIR_RXCTL);
35         ioread32(ctl + AGNX_CIR_RXCTL);
36 }
37
38 inline void disable_rx_interrupt(struct agnx_priv *priv)
39 {
40         void __iomem *ctl = priv->ctl;
41         u32 reg;
42
43         disable_rx_engine(priv);
44         reg = ioread32(ctl + AGNX_CIR_RXCFG);
45         reg &= ~0x20;
46         iowrite32(reg, ctl + AGNX_CIR_RXCFG);
47         ioread32(ctl + AGNX_CIR_RXCFG);
48 }
49
50 inline void enable_rx_interrupt(struct agnx_priv *priv)
51 {
52         void __iomem *ctl = priv->ctl;
53         u32 reg;
54
55         reg = ioread32(ctl + AGNX_CIR_RXCFG);
56         reg |= 0x20;
57         iowrite32(reg, ctl + AGNX_CIR_RXCFG);
58         ioread32(ctl + AGNX_CIR_RXCFG);
59         enable_rx_engine(priv);
60 }
61
62 static inline void rx_desc_init(struct agnx_priv *priv, unsigned int idx)
63 {
64         struct agnx_desc *desc = priv->rx.desc + idx;
65         struct agnx_info *info = priv->rx.info + idx;
66
67         memset(info, 0, sizeof(*info));
68
69         info->dma_len = IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct agnx_hdr);
70         info->skb = dev_alloc_skb(info->dma_len);
71         if (info->skb == NULL)
72                 agnx_bug("refill err");
73
74         info->mapping = pci_map_single(priv->pdev, skb_tail_pointer(info->skb),
75                                        info->dma_len, PCI_DMA_FROMDEVICE);
76         memset(desc, 0, sizeof(*desc));
77         desc->dma_addr = cpu_to_be32(info->mapping);
78         /* Set the owner to the card */
79         desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
80 }
81
82 static inline void rx_desc_reinit(struct agnx_priv *priv, unsigned int idx)
83 {
84         struct agnx_info *info = priv->rx.info + idx;
85
86         /* Cause ieee80211 will free the skb buffer, so we needn't to free it again?! */
87         pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
88         rx_desc_init(priv, idx);
89 }
90
91 static inline void rx_desc_reusing(struct agnx_priv *priv, unsigned int idx)
92 {
93         struct agnx_desc *desc = priv->rx.desc + idx;
94         struct agnx_info *info = priv->rx.info + idx;
95
96         memset(desc, 0, sizeof(*desc));
97         desc->dma_addr = cpu_to_be32(info->mapping);
98         /* Set the owner to the card */
99         desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
100 }
101
102 static void rx_desc_free(struct agnx_priv *priv, unsigned int idx)
103 {
104         struct agnx_desc *desc = priv->rx.desc + idx;
105         struct agnx_info *info = priv->rx.info + idx;
106
107         BUG_ON(!desc || !info);
108         if (info->mapping)
109                 pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
110         if (info->skb)
111                 dev_kfree_skb(info->skb);
112         memset(info, 0, sizeof(*info));
113         memset(desc, 0, sizeof(*desc));
114 }
115
116 static inline void __tx_desc_free(struct agnx_priv *priv,
117                                   struct agnx_desc *desc, struct agnx_info *info)
118 {
119         BUG_ON(!desc || !info);
120         /* TODO make sure mapping, skb and len are consistency */
121         if (info->mapping)
122                 pci_unmap_single(priv->pdev, info->mapping,
123                                  info->dma_len, PCI_DMA_TODEVICE);
124         if (info->type == PACKET)
125                 dev_kfree_skb(info->skb);
126
127         memset(info, 0, sizeof(*info));
128         memset(desc, 0, sizeof(*desc));
129 }
130
131 static void txm_desc_free(struct agnx_priv *priv, unsigned int idx)
132 {
133         struct agnx_desc *desc = priv->txm.desc + idx;
134         struct agnx_info *info = priv->txm.info + idx;
135
136         __tx_desc_free(priv, desc, info);
137 }
138
139 static void txd_desc_free(struct agnx_priv *priv, unsigned int idx)
140 {
141         struct agnx_desc *desc = priv->txd.desc + idx;
142         struct agnx_info *info = priv->txd.info + idx;
143
144         __tx_desc_free(priv, desc, info);
145 }
146
147 int fill_rings(struct agnx_priv *priv)
148 {
149         void __iomem *ctl = priv->ctl;
150         unsigned int i;
151         u32 reg;
152         AGNX_TRACE;
153
154         priv->txd.idx_sent = priv->txm.idx_sent = 0;
155         priv->rx.idx = priv->txm.idx = priv->txd.idx = 0;
156
157         for (i = 0; i < priv->rx.size; i++)
158                 rx_desc_init(priv, i);
159         for (i = 0; i < priv->txm.size; i++) {
160                 memset(priv->txm.desc + i, 0, sizeof(struct agnx_desc));
161                 memset(priv->txm.info + i, 0, sizeof(struct agnx_info));
162         }
163         for (i = 0; i < priv->txd.size; i++) {
164                 memset(priv->txd.desc + i, 0, sizeof(struct agnx_desc));
165                 memset(priv->txd.info + i, 0, sizeof(struct agnx_info));
166         }
167
168         /* FIXME Set the card RX TXM and TXD address */
169         agnx_write32(ctl, AGNX_CIR_RXCMSTART, priv->rx.dma);
170         agnx_write32(ctl, AGNX_CIR_RXCMEND, priv->txm.dma);
171
172         agnx_write32(ctl, AGNX_CIR_TXMSTART, priv->txm.dma);
173         agnx_write32(ctl, AGNX_CIR_TXMEND, priv->txd.dma);
174
175         agnx_write32(ctl, AGNX_CIR_TXDSTART, priv->txd.dma);
176         agnx_write32(ctl, AGNX_CIR_TXDEND, priv->txd.dma +
177                      sizeof(struct agnx_desc) * priv->txd.size);
178
179         /* FIXME Relinquish control of rings to card */
180         reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
181         reg &= ~0x800;
182         agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
183         return 0;
184 } /* fill_rings */
185
186 void unfill_rings(struct agnx_priv *priv)
187 {
188         unsigned long flags;
189         unsigned int i;
190         AGNX_TRACE;
191
192         spin_lock_irqsave(&priv->lock, flags);
193
194         for (i = 0; i < priv->rx.size; i++)
195                 rx_desc_free(priv, i);
196         for (i = 0; i < priv->txm.size; i++)
197                 txm_desc_free(priv, i);
198         for (i = 0; i < priv->txd.size; i++)
199                 txd_desc_free(priv, i);
200
201         spin_unlock_irqrestore(&priv->lock, flags);
202 }
203
204 /* Extract the bitrate out of a CCK PLCP header.
205    copy from bcm43xx driver */
206 static inline u8 agnx_plcp_get_bitrate_cck(__be32 *phyhdr_11b)
207 {
208         /* FIXME */
209         switch (*(u8 *)phyhdr_11b) {
210         case 0x0A:
211                 return 0;
212         case 0x14:
213                 return 1;
214         case 0x37:
215                 return 2;
216         case 0x6E:
217                 return 3;
218         }
219         agnx_bug("Wrong plcp rate");
220         return 0;
221 }
222
223 /* FIXME */
224 static inline u8 agnx_plcp_get_bitrate_ofdm(__be32 *phyhdr_11g)
225 {
226         u8 rate = *(u8 *)phyhdr_11g & 0xF;
227
228         printk(PFX "G mode rate is 0x%x\n", rate);
229         return rate;
230 }
231
232 /* FIXME */
233 static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
234                          struct ieee80211_rx_status *stat)
235 {
236         void __iomem *ctl = priv->ctl;
237         u8 *rssi;
238         u32 noise;
239         /* FIXME just for test */
240         int snr = 40;           /* signal-to-noise ratio */
241
242         memset(stat, 0, sizeof(*stat));
243         /* RSSI */
244         rssi = (u8 *)&hdr->phy_stats_lo;
245 /*      stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
246         /* Noise */
247         noise = ioread32(ctl + AGNX_GCR_NOISE0);
248         noise += ioread32(ctl + AGNX_GCR_NOISE1);
249         noise += ioread32(ctl + AGNX_GCR_NOISE2);
250         stat->noise = noise / 3;
251         /* Signal quality */
252 /*      snr = stat->ssi - stat->noise; */
253         if (snr >= 0 && snr < 40)
254                 stat->signal = 5 * snr / 2;
255         else if (snr >= 40)
256                 stat->signal = 100;
257         else
258                 stat->signal = 0;
259
260
261         if (hdr->_11b0 && !hdr->_11g0) {
262                 stat->rate_idx = agnx_plcp_get_bitrate_cck(&hdr->_11b0);
263         } else if (!hdr->_11b0 && hdr->_11g0) {
264                 printk(PFX "RX: Found G mode packet\n");
265                 stat->rate_idx = agnx_plcp_get_bitrate_ofdm(&hdr->_11g0);
266         } else
267                 agnx_bug("Unknown packets type");
268
269
270         stat->band = IEEE80211_BAND_2GHZ;
271         stat->freq = agnx_channels[priv->channel - 1].center_freq;
272 /*      stat->antenna = 3;
273         stat->mactime = be32_to_cpu(hdr->time_stamp);
274         stat->channel = priv->channel; */
275 }
276
277 static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
278                                     struct sk_buff *skb)
279 {
280         u16 fctl;
281         unsigned int hdrlen;
282
283         fctl = le16_to_cpu(ieeehdr->frame_control);
284         hdrlen = ieee80211_hdrlen(fctl);
285         /* FIXME */
286         if (hdrlen < (2+2+6)/*minimum hdr*/ ||
287             hdrlen > sizeof(struct ieee80211_mgmt)) {
288                 printk(KERN_ERR PFX "hdr len is %d\n", hdrlen);
289                 agnx_bug("Wrong ieee80211 hdr detected");
290         }
291         skb_push(skb, hdrlen);
292         memcpy(skb->data, ieeehdr, hdrlen);
293 } /* combine_hdr_frag */
294
295 static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
296                                     unsigned packet_len)
297 {
298         if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
299                 printk(PFX "RX: CRC check fail\n");
300                 goto drop;
301         }
302         if (packet_len > 2048) {
303                 printk(PFX "RX: Too long packet detected\n");
304                 goto drop;
305         }
306
307         /* FIXME Just usable for Promious Mode, for Manage mode exclude FCS */
308 /*      if (packet_len - sizeof(*agnxhdr) < FCS_LEN) { */
309 /*              printk(PFX "RX: Too short packet detected\n"); */
310 /*              goto drop; */
311 /*      } */
312         return 0;
313 drop:
314         priv->stats.dot11FCSErrorCount++;
315         return -1;
316 }
317
318 void handle_rx_irq(struct agnx_priv *priv)
319 {
320         struct ieee80211_rx_status status;
321         unsigned int len;
322 /*      AGNX_TRACE; */
323
324         do {
325                 struct agnx_desc *desc;
326                 u32 frag;
327                 struct agnx_info *info;
328                 struct agnx_hdr *hdr;
329                 struct sk_buff *skb;
330                 unsigned int i = priv->rx.idx % priv->rx.size;
331
332                 desc = priv->rx.desc + i;
333                 frag = be32_to_cpu(desc->frag);
334                 if (frag & OWNER)
335                         break;
336
337                 info = priv->rx.info + i;
338                 skb = info->skb;
339                 hdr = (struct agnx_hdr *)(skb->data);
340
341                 len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
342                 if (agnx_packet_check(priv, hdr, len) == -1) {
343                         rx_desc_reusing(priv, i);
344                         continue;
345                 }
346                 skb_put(skb, len);
347
348                 do {
349                                 u16 fctl;
350                         fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
351                         if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
352                                 dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
353                 } while (0);
354
355                 if (hdr->_11b0 && !hdr->_11g0) {
356 /*                      int j;
357                         u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
358                                                ->frame_control);
359                         if ( (fctl & IEEE80211_FCTL_FTYPE) ==  IEEE80211_FTYPE_DATA) {
360                                 agnx_print_rx_hdr(hdr);
361                                 agnx_print_sta(priv, BSSID_STAID);
362                                 for (j = 0; j < 8; j++)
363                                         agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
364                         } */
365
366                         get_rx_stats(priv, hdr, &status);
367                         skb_pull(skb, sizeof(*hdr));
368                         combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
369                 } else if (!hdr->_11b0 && hdr->_11g0) {
370 /*                      int j; */
371                         agnx_print_rx_hdr(hdr);
372                         agnx_print_sta(priv, BSSID_STAID);
373 /*                      for (j = 0; j < 8; j++) */
374                         agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
375
376                         print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
377                                              skb->data, skb->len + 8);
378
379 /*                      if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
380                         get_rx_stats(priv, hdr, &status);
381                         skb_pull(skb, sizeof(*hdr));
382                         combine_hdr_frag((struct ieee80211_hdr *)
383                                          ((void *)&hdr->mac_hdr), skb);
384 /*                      dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
385                 } else
386                         agnx_bug("Unknown packets type");
387                 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
388                 ieee80211_rx_irqsafe(priv->hw, skb);
389                 rx_desc_reinit(priv, i);
390
391         } while (priv->rx.idx++);
392 } /* handle_rx_irq */
393
394 static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
395 {
396         struct agnx_desc *desc;
397         struct agnx_info *info;
398         unsigned int idx;
399
400         for (idx = ring->idx_sent; idx < ring->idx; idx++) {
401                 unsigned int i = idx % ring->size;
402                 u32  frag;
403
404                 desc = ring->desc + i;
405                 info = ring->info + i;
406
407                 frag = be32_to_cpu(desc->frag);
408                 if (frag & OWNER) {
409                         if (info->type == HEADER)
410                                 break;
411                         else
412                                 agnx_bug("TX error");
413                 }
414
415                 pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
416
417                 do {
418 /*                      int j; */
419                         size_t len;
420                         len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
421 /*                      if (len == 614) { */
422 /*                              agnx_print_desc(desc); */
423                                 if (info->type == PACKET) {
424 /*                                      agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
425 /*                                      agnx_print_sta_power(priv, LOCAL_STAID); */
426 /*                                      agnx_print_sta(priv, LOCAL_STAID); */
427 /*                                      for (j = 0; j < 8; j++) */
428 /*                                      agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
429 /*                                      agnx_print_sta_power(priv, BSSID_STAID); */
430 /*                                      agnx_print_sta(priv, BSSID_STAID); */
431 /*                                      for (j = 0; j < 8; j++) */
432 /*                                      agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
433                                 }
434 /*                      } */
435                 } while (0);
436
437                 if (info->type == PACKET) {
438 /*                      dump_txm_registers(priv);
439                         dump_rxm_registers(priv);
440                         dump_bm_registers(priv);
441                         dump_cir_registers(priv); */
442                 }
443
444                 if (info->type == PACKET) {
445 /*                      struct ieee80211_hdr *hdr; */
446                         struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
447
448                         skb_pull(info->skb, sizeof(struct agnx_hdr));
449                         memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
450
451 /*                      dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
452 /*                      print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
453 /*                                           info->skb->data, info->skb->len); */
454
455                         if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK))
456                                 txi->flags |= IEEE80211_TX_STAT_ACK;
457
458                         ieee80211_tx_status_irqsafe(priv->hw, info->skb);
459
460
461 /*                              info->tx_status.queue_number = (ring->size - i) / 2; */
462 /*                              ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
463 /*                      } else */
464 /*                              dev_kfree_skb_irq(info->skb); */
465                 }
466                 memset(desc, 0, sizeof(*desc));
467                 memset(info, 0, sizeof(*info));
468         }
469
470         ring->idx_sent = idx;
471         /* TODO fill the priv->low_level_stats */
472
473         /* ieee80211_wake_queue(priv->hw, 0); */
474 }
475
476 void handle_txm_irq(struct agnx_priv *priv)
477 {
478         handle_tx_irq(priv, &priv->txm);
479 }
480
481 void handle_txd_irq(struct agnx_priv *priv)
482 {
483         handle_tx_irq(priv, &priv->txd);
484 }
485
486 void handle_other_irq(struct agnx_priv *priv)
487 {
488 /*      void __iomem *ctl = priv->ctl; */
489         u32 status = priv->irq_status;
490         void __iomem *ctl = priv->ctl;
491         u32 reg;
492
493         if (status & IRQ_TX_BEACON) {
494                 iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT);
495                 printk(PFX "IRQ: TX Beacon control is 0X%.8X\n", ioread32(ctl + AGNX_TXM_BEACON_CTL));
496                 printk(PFX "IRQ: TX Beacon rx frame num: %d\n", rx_frame_cnt);
497         }
498         if (status & IRQ_TX_RETRY) {
499                 reg = ioread32(ctl + AGNX_TXM_RETRYSTAID);
500                 printk(PFX "IRQ: TX Retry, RETRY STA ID is %x\n", reg);
501         }
502         if (status & IRQ_TX_ACTIVITY)
503                 printk(PFX "IRQ: TX Activity\n");
504         if (status & IRQ_RX_ACTIVITY)
505                 printk(PFX "IRQ: RX Activity\n");
506         if (status & IRQ_RX_X)
507                 printk(PFX "IRQ: RX X\n");
508         if (status & IRQ_RX_Y) {
509                 reg = ioread32(ctl + AGNX_INT_MASK);
510                 reg &= ~IRQ_RX_Y;
511                 iowrite32(reg, ctl + AGNX_INT_MASK);
512                 iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT);
513                 printk(PFX "IRQ: RX Y\n");
514         }
515         if (status & IRQ_RX_HASHHIT)  {
516                 reg = ioread32(ctl + AGNX_INT_MASK);
517                 reg &= ~IRQ_RX_HASHHIT;
518                 iowrite32(reg, ctl + AGNX_INT_MASK);
519                 iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT);
520                 printk(PFX "IRQ: RX Hash Hit\n");
521
522         }
523         if (status & IRQ_RX_FRAME) {
524                 reg = ioread32(ctl + AGNX_INT_MASK);
525                 reg &= ~IRQ_RX_FRAME;
526                 iowrite32(reg, ctl + AGNX_INT_MASK);
527                 iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
528                 printk(PFX "IRQ: RX Frame\n");
529                 rx_frame_cnt++;
530         }
531         if (status & IRQ_ERR_INT) {
532                 iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
533 /*              agnx_hw_reset(priv); */
534                 printk(PFX "IRQ: Error Interrupt\n");
535         }
536         if (status & IRQ_TX_QUE_FULL)
537                 printk(PFX "IRQ: TX Workqueue Full\n");
538         if (status & IRQ_BANDMAN_ERR)
539                 printk(PFX "IRQ: Bandwidth Management Error\n");
540         if (status & IRQ_TX_DISABLE)
541                 printk(PFX "IRQ: TX Disable\n");
542         if (status & IRQ_RX_IVASESKEY)
543                 printk(PFX "IRQ: RX Invalid Session Key\n");
544         if (status & IRQ_REP_THHIT)
545                 printk(PFX "IRQ: Replay Threshold Hit\n");
546         if (status & IRQ_TIMER1)
547                 printk(PFX "IRQ: Timer1\n");
548         if (status & IRQ_TIMER_CNT)
549                 printk(PFX "IRQ: Timer Count\n");
550         if (status & IRQ_PHY_FASTINT)
551                 printk(PFX "IRQ: Phy Fast Interrupt\n");
552         if (status & IRQ_PHY_SLOWINT)
553                 printk(PFX "IRQ: Phy Slow Interrupt\n");
554         if (status & IRQ_OTHER)
555                 printk(PFX "IRQ: 0x80000000\n");
556 } /* handle_other_irq */
557
558
559 static inline void route_flag_set(struct agnx_hdr *txhdr)
560 {
561 /*      u32 reg = 0; */
562
563         /* FIXME */
564 /*      reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
565 /*      txhdr->reg5 = cpu_to_be32(reg); */
566         txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
567 /*      txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
568 /*      txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
569 }
570
571 /* Return 0 if no match */
572 static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num)
573 {
574         unsigned int power_level;
575
576         switch (rate) {
577         case 10:
578         case 20:
579         case 55:
580         case 60:
581         case 90:
582         case 120:
583                 power_level = 22;
584                 break;
585
586         case 180:
587                 power_level = 19;
588                 break;
589
590         case 240:
591                 power_level = 18;
592                 break;
593
594         case 360:
595                 power_level = 16;
596                 break;
597
598         case 480:
599                 power_level = 15;
600                 break;
601
602         case 540:
603                 power_level = 14;
604                 break;
605         default:
606                 agnx_bug("Error rate setting\n");
607         }
608
609         if (power_level && (antennas_num == 2))
610                 power_level -= 3;
611
612         return power_level;
613 }
614
615 static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info)
616 {
617         struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data;
618         size_t len;
619         u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr);
620         u32 reg;
621
622         memset(txhdr, 0, sizeof(*txhdr));
623
624 /*      reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
625         reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
626         reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
627         txhdr->reg4 = cpu_to_be32(reg);
628
629         /* Set the Hardware Sequence Number to 1? */
630         reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
631 /*      reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
632         reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
633         txhdr->reg1 = cpu_to_be32(reg);
634         /* Set the agnx_hdr's MAC header */
635         memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
636
637         reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
638 /*      reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
639         reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
640 /*      reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
641         reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
642         reg |= agnx_set_bits(TM, TM_SHIFT, 0);
643         txhdr->reg0 = cpu_to_be32(reg);
644
645         /* Set the long and short retry limits */
646         txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
647         txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
648
649         /* FIXME */
650         len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
651         if (fc & IEEE80211_FCTL_PROTECTED)
652                 len += 8;
653         len = 2398;
654         reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len);
655         len = tx_info->skb->len - sizeof(*txhdr);
656         reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len);
657         txhdr->reg3 = cpu_to_be32(reg);
658
659         route_flag_set(txhdr);
660 } /* fill_hdr */
661
662 static void txm_power_set(struct agnx_priv *priv,
663                           struct ieee80211_tx_info *txi)
664 {
665         struct agnx_sta_power power;
666         u32 reg;
667
668         /* FIXME */
669         if (txi->control.rates[0].idx < 0) {
670                 /* For B mode Short Preamble */
671                 reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
672 /*              control->tx_rate = -control->tx_rate; */
673         } else
674                 reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
675 /*              reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
676         reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
677         reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
678 /*      reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
679         reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
680         /* if rate < 11M set it to 0 */
681         reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
682 /*      reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
683 /*      reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
684
685         power.reg = reg;
686 /*      power.reg = cpu_to_le32(reg); */
687
688 /*      set_sta_power(priv, &power, LOCAL_STAID); */
689         set_sta_power(priv, &power, BSSID_STAID);
690 }
691
692 static inline int tx_packet_check(struct sk_buff *skb)
693 {
694         unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb);
695         if (skb->len > 2048) {
696                 printk(KERN_ERR PFX "length is %d\n", skb->len);
697                 agnx_bug("Too long TX skb");
698                 return -1;
699         }
700         /* FIXME */
701         if (skb->len == ieee_len) {
702                 printk(PFX "A strange TX packet\n");
703                 return -1;
704                 /* tx_faile_irqsafe(); */
705         }
706         return 0;
707 }
708
709 static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
710                      struct agnx_ring *ring)
711 {
712         struct agnx_desc *hdr_desc, *frag_desc;
713         struct agnx_info *hdr_info, *frag_info;
714         struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
715         unsigned long flags;
716         unsigned int i;
717
718         spin_lock_irqsave(&priv->lock, flags);
719
720         /* The RX interrupt need be Disable until this TX packet
721            is handled in the next tx interrupt */
722         disable_rx_interrupt(priv);
723
724         i = ring->idx;
725         ring->idx += 2;
726 /*      if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) */
727 /*              ieee80211_stop_queue(priv->hw, 0); */
728
729         /* Set agnx header's info and desc */
730         i %= ring->size;
731         hdr_desc = ring->desc + i;
732         hdr_info = ring->info + i;
733         hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb);
734         memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len);
735
736         /* Add the agnx header to the front of the SKB */
737         skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len);
738
739         hdr_info->txi = txi;
740         hdr_info->dma_len = sizeof(struct agnx_hdr);
741         hdr_info->skb = skb;
742         hdr_info->type = HEADER;
743         fill_agnx_hdr(priv, hdr_info);
744         hdr_info->mapping = pci_map_single(priv->pdev, skb->data,
745                                            hdr_info->dma_len, PCI_DMA_TODEVICE);
746         do {
747                 u32 frag = 0;
748                 frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1);
749                 frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0);
750                 frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
751                 frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1);
752                 frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1);
753                 hdr_desc->frag = cpu_to_be32(frag);
754         } while (0);
755         hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping);
756
757
758         /* Set Frag's info and desc */
759         i = (i + 1) % ring->size;
760         frag_desc = ring->desc + i;
761         frag_info = ring->info + i;
762         memcpy(frag_info, hdr_info, sizeof(struct agnx_info));
763         frag_info->type = PACKET;
764         frag_info->dma_len = skb->len - hdr_info->dma_len;
765         frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len,
766                                             frag_info->dma_len, PCI_DMA_TODEVICE);
767         do {
768                 u32 frag = 0;
769                 frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0);
770                 frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1);
771                 frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
772                 frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len);
773                 frag_desc->frag = cpu_to_be32(frag);
774         } while (0);
775         frag_desc->dma_addr = cpu_to_be32(frag_info->mapping);
776
777         txm_power_set(priv, txi);
778
779 /*      do { */
780 /*              int j; */
781 /*              size_t len; */
782 /*              len = skb->len - hdr_info->dma_len + hdr_info->hdr_len;  */
783 /*              if (len == 614) { */
784 /*                      agnx_print_desc(hdr_desc); */
785 /*                      agnx_print_desc(frag_desc); */
786 /*                      agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
787 /*                      agnx_print_sta_power(priv, LOCAL_STAID); */
788 /*                      agnx_print_sta(priv, LOCAL_STAID); */
789 /*                      for (j = 0; j < 8; j++) */
790 /*                              agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
791 /*                      agnx_print_sta_power(priv, BSSID_STAID); */
792 /*                      agnx_print_sta(priv, BSSID_STAID); */
793 /*                      for (j = 0; j < 8; j++) */
794 /*                              agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
795 /*                      } */
796 /*      } while (0); */
797
798         spin_unlock_irqrestore(&priv->lock, flags);
799
800         /* FIXME ugly code */
801         /* Trigger TXM */
802         do {
803                 u32 reg;
804                 reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
805                 reg |= 0x8;
806                 iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
807         } while (0);
808
809         /* Trigger TXD */
810         do {
811                 u32 reg;
812                 reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
813                 reg |= 0x8;
814                 iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
815         } while (0);
816
817         return 0;
818 }
819
820 int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
821 {
822         u16 fctl;
823
824         if (tx_packet_check(skb))
825                 return 0;
826
827 /*      print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
828 /*                           skb->data, skb->len); */
829
830         fctl = le16_to_cpu(*((__le16 *)skb->data));
831
832         if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
833                 return __agnx_tx(priv, skb, &priv->txd);
834         else
835                 return __agnx_tx(priv, skb, &priv->txm);
836 }