Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

b43: N-PHY: implement radio 2056 init steps

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Rafał Miłecki and committed by
John W. Linville
ea7ee14b e41596a1

+111 -2
+31 -2
drivers/net/wireless/b43/phy_n.c
··· 401 401 b43_radio_init2055_post(dev); 402 402 } 403 403 404 + static void b43_radio_init2056_pre(struct b43_wldev *dev) 405 + { 406 + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, 407 + ~B43_NPHY_RFCTL_CMD_CHIP0PU); 408 + /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */ 409 + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, 410 + B43_NPHY_RFCTL_CMD_OEPORFORCE); 411 + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, 412 + ~B43_NPHY_RFCTL_CMD_OEPORFORCE); 413 + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, 414 + B43_NPHY_RFCTL_CMD_CHIP0PU); 415 + } 416 + 417 + static void b43_radio_init2056_post(struct b43_wldev *dev) 418 + { 419 + b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB); 420 + b43_radio_set(dev, B2056_SYN_COM_PU, 0x2); 421 + b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2); 422 + msleep(1); 423 + b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2); 424 + b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC); 425 + b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1); 426 + /* 427 + if (nphy->init_por) 428 + Call Radio 2056 Recalibrate 429 + */ 430 + } 431 + 404 432 /* 405 433 * Initialize a Broadcom 2056 N-radio 406 434 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init 407 435 */ 408 436 static void b43_radio_init2056(struct b43_wldev *dev) 409 437 { 410 - /* TODO */ 438 + b43_radio_init2056_pre(dev); 439 + b2056_upload_inittabs(dev, 0, 0); 440 + b43_radio_init2056_post(dev); 411 441 } 412 - 413 442 414 443 /* 415 444 * Upload the N-PHY tables.
+77
drivers/net/wireless/b43/radio_2056.c
··· 24 24 #include "radio_2056.h" 25 25 #include "phy_common.h" 26 26 27 + struct b2056_inittab_entry { 28 + /* Value to write if we use the 5GHz band. */ 29 + u16 ghz5; 30 + /* Value to write if we use the 2.4GHz band. */ 31 + u16 ghz2; 32 + /* Flags */ 33 + u8 flags; 34 + }; 35 + #define B2056_INITTAB_ENTRY_OK 0x01 36 + #define B2056_INITTAB_UPLOAD 0x02 37 + #define UPLOAD .flags = B2056_INITTAB_ENTRY_OK | B2056_INITTAB_UPLOAD 38 + #define NOUPLOAD .flags = B2056_INITTAB_ENTRY_OK 39 + 40 + struct b2056_inittabs_pts { 41 + const struct b2056_inittab_entry *syn; 42 + unsigned int syn_length; 43 + const struct b2056_inittab_entry *tx; 44 + unsigned int tx_length; 45 + const struct b2056_inittab_entry *rx; 46 + unsigned int rx_length; 47 + }; 48 + 49 + #define INITTABSPTS(prefix) \ 50 + .syn = prefix##_syn, \ 51 + .syn_length = ARRAY_SIZE(prefix##_syn), \ 52 + .tx = prefix##_tx, \ 53 + .tx_length = ARRAY_SIZE(prefix##_tx), \ 54 + .rx = prefix##_rx, \ 55 + .rx_length = ARRAY_SIZE(prefix##_rx) 56 + 57 + struct b2056_inittabs_pts b2056_inittabs[] = { 58 + }; 59 + 27 60 #define RADIOREGS3(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ 28 61 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ 29 62 r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, \ ··· 6077 6044 PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424), 6078 6045 }, 6079 6046 }; 6047 + 6048 + static void b2056_upload_inittab(struct b43_wldev *dev, bool ghz5, 6049 + bool ignore_uploadflag, u16 routing, 6050 + const struct b2056_inittab_entry *e, 6051 + unsigned int length) 6052 + { 6053 + unsigned int i; 6054 + u16 value; 6055 + 6056 + for (i = 0; i < length; i++, e++) { 6057 + if (!(e->flags & B2056_INITTAB_ENTRY_OK)) 6058 + continue; 6059 + if ((e->flags & B2056_INITTAB_UPLOAD) || ignore_uploadflag) { 6060 + if (ghz5) 6061 + value = e->ghz5; 6062 + else 6063 + value = e->ghz2; 6064 + b43_radio_write(dev, routing | i, value); 6065 + } 6066 + } 6067 + } 6068 + 6069 + void b2056_upload_inittabs(struct b43_wldev *dev, 6070 + bool ghz5, bool ignore_uploadflag) 6071 + { 6072 + struct b2056_inittabs_pts *pts; 6073 + 6074 + if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) { 6075 + B43_WARN_ON(1); 6076 + return; 6077 + } 6078 + pts = &b2056_inittabs[dev->phy.rev]; 6079 + 6080 + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, 6081 + B2056_SYN, pts->syn, pts->syn_length); 6082 + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, 6083 + B2056_TX0, pts->tx, pts->tx_length); 6084 + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, 6085 + B2056_TX1, pts->tx, pts->tx_length); 6086 + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, 6087 + B2056_RX0, pts->rx, pts->rx_length); 6088 + b2056_upload_inittab(dev, ghz5, ignore_uploadflag, 6089 + B2056_RX1, pts->rx, pts->rx_length); 6090 + } 6080 6091 6081 6092 /* TODO: add support for rev4+ devices by searching in rev4+ tables */ 6082 6093 const struct b43_nphy_channeltab_entry_rev3 *
+3
drivers/net/wireless/b43/radio_2056.h
··· 1114 1114 struct b43_phy_n_sfo_cfg phy_regs; 1115 1115 }; 1116 1116 1117 + void b2056_upload_inittabs(struct b43_wldev *dev, 1118 + bool ghz5, bool ignore_uploadflag); 1119 + 1117 1120 #endif /* B43_RADIO_2056_H_ */